From 671368f0a5ab6c5132fe89f7ee36ff626a49ce10 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sat, 2 Mar 2019 15:23:37 +0800 Subject: [PATCH 01/66] Create zengdiqing1994.md --- .../968-BinaryTreeCameras/zengdiqing1994.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 leetcode/968-BinaryTreeCameras/zengdiqing1994.md diff --git a/leetcode/968-BinaryTreeCameras/zengdiqing1994.md b/leetcode/968-BinaryTreeCameras/zengdiqing1994.md new file mode 100644 index 0000000..1a4e5c3 --- /dev/null +++ b/leetcode/968-BinaryTreeCameras/zengdiqing1994.md @@ -0,0 +1,55 @@ +**968. Binary Tree Cameras** + +[Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/) + +**思路:** + +最小点覆盖和最大独立集都比较简单,只有2个状态,分别是标记和不标记 + +对于最小支配集,每个子树3个状态: + +状态0:根被标记,整个子树都被覆盖的最小标记数目 + +状态1:根未被标记,整个子树被覆盖,且至少有一个子节点被标记 + +状态2:根未被标记,整个子树被覆盖,且没有子节点被标记 + +每个状态如何递归: + +1.状态0:每个子树的3个状态的最小值之和+1: + +dp[root][0] = min(dp[root.left])+min(dp[root.right])+1 + +2.状态1:【如果根没有孩子,dp[root][1]为INF】根未被标记时子树不可以是状态3。所以是前两个状态取最小值之和。但是如果每个子节点的最小值都是状态1,那么就 +和根是状态1的假设矛盾了。所以要挑一个节点取状态0,这必然会使结果增加,那么选增加得最少的那个,即dp[u][0]-dp[u][1]最小的那个指定为状态0。 + +不可能是状态3是因为如果根没有标记,儿子没有标记,根还被覆盖了,可能是根的父亲标记了,但是如果孙子也没有标记,那么儿子就不可能被标记,矛盾。 + +2.状态2:此时子树只可能是状态1。 + +dp[root][2] = dp[root.left][1]+dp[root.right][1] + +最后取根节点的状态1和状态0里最小的那个 + +```py +class Solution: + def minCameraCover(self, root: TreeNode) -> int: + INF = 0x7fffffff + def solve(root): + if root.left and root.right: + left = solve(root.left) #左右子树递归 + right = solve(root.right) + return min(left)+min(right)+1, min(left[0]+min(right[:-1]), min(left[:-1])+right[0]),left[1]+right[1] + res = None + if root.left: #求解满足状态0,1的情况 + res = solve(root.left) + elif root.right: + res = solve(root.right) + if res!=None: + return min(res)+1, res[0], res[1] + return 1, INF, 0 + return min(solve(root)[:-1]) +``` +时间复杂度是O(nlogn) + +[参考](https://blog.csdn.net/lemonmillie/article/details/87825550) From b7cf2499f7d41f699f3b9ee469f25d7d02b1de8e Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 3 Mar 2019 21:32:12 +0800 Subject: [PATCH 02/66] update new question --- README.md | 32 +++++++++++++++++++++++ leetcode/664-StrangePrinter/official.md | 3 +++ leetcode/956-TallestBillboard/official.md | 3 +++ 3 files changed, 38 insertions(+) create mode 100644 leetcode/664-StrangePrinter/official.md create mode 100644 leetcode/956-TallestBillboard/official.md diff --git a/README.md b/README.md index 65262ef..a4dddb0 100644 --- a/README.md +++ b/README.md @@ -2056,3 +2056,35 @@ 难度:困难 --- + +2019年03月29日 + +[956. 最高的广告牌](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) + +英文官方题解: + +[https://leetcode.com/problems/tallest-billboard/solution/](https://leetcode.com/problems/tallest-billboard/solution/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月30日 + +[664. 奇怪的打印机](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) + +英文官方题解: + +[https://leetcode.com/problems/strange-printer/solution/](https://leetcode.com/problems/strange-printer/solution/) + +知识点:动态规划 + +难度:困难 + +--- diff --git a/leetcode/664-StrangePrinter/official.md b/leetcode/664-StrangePrinter/official.md new file mode 100644 index 0000000..bb8c3dc --- /dev/null +++ b/leetcode/664-StrangePrinter/official.md @@ -0,0 +1,3 @@ +**664. 奇怪的打印机** +--- +[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) diff --git a/leetcode/956-TallestBillboard/official.md b/leetcode/956-TallestBillboard/official.md new file mode 100644 index 0000000..d012226 --- /dev/null +++ b/leetcode/956-TallestBillboard/official.md @@ -0,0 +1,3 @@ +**956. 最高的广告牌** +--- +[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) From 272803b99e9387f0dc44d7b1068cda4c892a95a6 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sun, 3 Mar 2019 22:35:54 +0800 Subject: [PATCH 03/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 leetcode/354-RussianDollEnvelopes/zengdiqing1994.md diff --git a/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md b/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md new file mode 100644 index 0000000..948d467 --- /dev/null +++ b/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md @@ -0,0 +1,62 @@ +354. 俄罗斯套娃信封问题 + +[354. 俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) + +思路1: + +这道题和[最长上升子序列](https://blog.csdn.net/u010712012/article/details/86532426)很像,只不过从一维变成了二维,DP解法实际上是一种暴力解法, +首先要给所有的信封按从小到大排序,首先根据宽度从小到大排,如果宽度相同,那么高度小的在前面,然后开始遍历,对于每一个信封,我们都遍历其前面所有的信封, +如果当前信封的长和宽都比前面那个信封的大,那么我们更新DP数组,通过dp[i] = max(dp[i],dp[j]+1)。然后我们每遍历完一个信封,都更新一下结果。 + + + +```py +class Solution: + def maxEnvelopes(self, envelopes: List[List[int]]) -> int: + if not envelopes: + return 0 + nums = sorted(envelopes,key = lambda x:x) #先排好序 + dp = [1]*len(nums) #状态初始化一个dp,也就是最长子序列的长度 + for i in range(1,len(nums)): #i从第二个子列表到最后一个列表 + for j in range(i-1,-1,-1): #j从第倒数第二个列表到第一个字列表遍历 + if nums[i][0]>nums[j][0] and nums[i][1]>nums[j][1]: #比较 + dp[i] = max(dp[i],dp[j]+1) #更新dp + return max(dp) #返回 +``` + +但是上面的时间复杂度是O(n^2),lc提交超时。。。 + +于是就有了思路2: + +可以用二分查找来优化速度,首先要做的还是给信封排序,但是这次排序和上面有些不同,信封的宽度还是从小到大排,但是宽度相等时,我们让高度大的在前面。现在的问题 +就简化成了找高度数字中的最长上升子序列 + +``` +from functools import cmp_to_key + +def maxEnvelopes(envelopes) -> int: + if not envelopes: + return 0 + nums = sorted(envelopes,key=cmp_to_key(lambda x, y: x[0] - y[0] if x[0] != y[0] else y[1] - x[1])) + size = len(nums) + dp = [] + for x in range(size): + low, high = 0, len(dp) - 1 + while low <= high: + mid = (low + high) // 2 + if dp[mid][1] < nums[x][1]: + low = mid + 1 + else: + high = mid - 1 + if low < len(dp): + dp[low] = nums[x] + else: + dp.append(nums[x]) + return len(dp) +def main(): + + envelopes = [[5,4],[6,4],[6,7],[2,3]] + print(maxEnvelopes(envelopes)) +main() +``` +时间复杂度O(nlogn) From 75041ca4c5f0b94d337a81be142ce59bece7a6bf Mon Sep 17 00:00:00 2001 From: passself <910943466@qq.com> Date: Sat, 9 Mar 2019 09:48:13 +0800 Subject: [PATCH 04/66] add answers for leetcode 174 and 920 --- leetcode/174-DungeonGame/official.md | 4 - leetcode/174-DungeonGame/passself.md | 81 +++++++++++++++++++ .../920-NumberOfMusicPlaylists/official.md | 3 - .../920-NumberOfMusicPlaylists/passself.md | 48 +++++++++++ 4 files changed, 129 insertions(+), 7 deletions(-) delete mode 100644 leetcode/174-DungeonGame/official.md create mode 100644 leetcode/174-DungeonGame/passself.md delete mode 100644 leetcode/920-NumberOfMusicPlaylists/official.md create mode 100644 leetcode/920-NumberOfMusicPlaylists/passself.md diff --git a/leetcode/174-DungeonGame/official.md b/leetcode/174-DungeonGame/official.md deleted file mode 100644 index 194b4a0..0000000 --- a/leetcode/174-DungeonGame/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**174. 地下城游戏** ---- - -[https://leetcode-cn.com/problems/dungeon-game/](https://leetcode-cn.com/problems/dungeon-game/) diff --git a/leetcode/174-DungeonGame/passself.md b/leetcode/174-DungeonGame/passself.md new file mode 100644 index 0000000..e369d4c --- /dev/null +++ b/leetcode/174-DungeonGame/passself.md @@ -0,0 +1,81 @@ +#174. 地下城游戏 + +Leetcode 地址 [https://leetcode-cn.com/problems/dungeon-game/](https://leetcode-cn.com/problems/dungeon-game/) + +**题目分析** + +基本一看就是动态规划的题目, 有几个前提条件一定得注意。 + +* 1.骑士的初始健康点数为一个正整数。 +* 2.如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。即无论骑士到达哪个位置健康值必须大于等于1 + +**思路:** + +* 思路一 正向递推从左上角(0,0)到(row-1,row-1),这样效率一般会比反递推效率低很多 +* 思路二 到达最后一个房间的时候健康值至少剩下1,因此可以设置最后的状态为初始状态,由后向前依次决定在每一个位置至少需要多少健康值,这样一个位置的状态是由其下面一个和和右边一个的较小状态决定 .因此一个基本的状态方程是: + +``` +int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); +int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); +dp[i][j] = Math.min(right, down); +``` +还有一个条件就是在每个房间里面的健康值都大于等于1 ```dp[i][j] = max(dp[i][j], 1)``` + +**具体代码** + +``` +public int calculateMinimumHP(int[][] dungeon) { + if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) return 0; + int m = dungeon.length; + int n = dungeon[0].length; + int[][] dp = new int[m][n]; + for (int i = m - 1; i >= 0; i--) { + for (int j = n - 1; j >= 0; j--) { + if(i==m-1 && j==n-1) {//考虑边界 + dp[i][j]=Math.max(1 - dungeon[i][j], 1); + }else if(i==m-1) { + dp[i][j]=Math.max(dp[i][j + 1] - dungeon[i][j], 1); + }else if(j==n-1) { + dp[i][j]=Math.max(dp[i + 1][j] - dungeon[i][j], 1); + }else{ + int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); + int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); + dp[i][j] = Math.min(right, down); + } + } + } + return dp[0][0]; +} +``` + +**时间复杂度** O(M*N) + +**空间复杂度** O(M*N) + +leetcode 代码提交后发现击败了26%的commit + +**第二种解法** + +用一位数组来记录数据,空间复杂度变为o(n),执行效率和速度大幅提升 + +**具体代码** + +``` +public int calculateMinimumHP(int[][] dungeon) { + int m = dungeon.length, n = dungeon[0].length; + int[] dp = new int[n + 1]; + dp[n] = 1; + for (int i = m - 1; i >= 0; i--) { + for (int j = n - 1; j >= 0; j--) { + int health = 0; + if (i == m - 1) health = dp[j + 1] - dungeon[i][j]; + else if (j == n - 1) health = dp[j] - dungeon[i][j]; + else health = Math.min(dp[j + 1], dp[j]) - dungeon[i][j]; + dp[j] = health <= 0 ? 1 : health; + } + } + return dp[0]; +} +``` + + diff --git a/leetcode/920-NumberOfMusicPlaylists/official.md b/leetcode/920-NumberOfMusicPlaylists/official.md deleted file mode 100644 index 0afaa26..0000000 --- a/leetcode/920-NumberOfMusicPlaylists/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**920. Number of Music Playlists** ---- -[https://leetcode-cn.com/problems/number-of-music-playlists/](https://leetcode-cn.com/problems/number-of-music-playlists/) diff --git a/leetcode/920-NumberOfMusicPlaylists/passself.md b/leetcode/920-NumberOfMusicPlaylists/passself.md new file mode 100644 index 0000000..d016bdc --- /dev/null +++ b/leetcode/920-NumberOfMusicPlaylists/passself.md @@ -0,0 +1,48 @@ +#920. 播放列表的数量 + +Leetcode 地址 [https://leetcode-cn.com/problems/number-of-music-playlists/](https://leetcode-cn.com/problems/number-of-music-playlists/) + +**题目分析** + +你的音乐播放器里有 N 首不同的歌,在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复)。请你为她按如下规则创建一个播放列表,dp的方式[参考](https://blog.csdn.net/qq_17550379/article/details/82992083)。 + +**思路:** + +可以暴力枚举所有集合,然后对这些集合中相同元素的位置比较,如果 K){ + dp[i][j] = (dp[i][j] + (dp[i-1][j] * (j-K))%mod)%mod; + } + } + } + return (int)dp[L][N]; + } +} +``` +**时间复杂度** O(L*N) + +**空间复杂度** O(L*N) + + From 78a3325f94b19037a5200bd937509ac7a3b5b12f Mon Sep 17 00:00:00 2001 From: bigablecat Date: Mon, 11 Mar 2019 17:16:04 +0800 Subject: [PATCH 05/66] update new questions --- README.md | 32 +++++++++++++++++++ .../032-LongestValidParentheses/official.md | 3 ++ .../official.md | 3 ++ 3 files changed, 38 insertions(+) create mode 100644 leetcode/032-LongestValidParentheses/official.md create mode 100644 leetcode/943-FindTheShortestSuperstring/official.md diff --git a/README.md b/README.md index a4dddb0..e33c005 100644 --- a/README.md +++ b/README.md @@ -2088,3 +2088,35 @@ 难度:困难 --- + +2019年04月01日 + +[943. 最短超级串](https://github.com/hollischuang/algorithm/tree/master/leetcode/943-FindTheShortestSuperstring) + +[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) + +英文官方题解: + +[https://leetcode.com/articles/find-the-shortest-superstring/](https://leetcode.com/articles/find-the-shortest-superstring/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年04月02日 + +[32. 最长有效括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/032-LongestValidParentheses) + +[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) + +英文官方题解: + +[https://leetcode.com/articles/longest-valid-parentheses/](https://leetcode.com/articles/longest-valid-parentheses/) + +知识点:动态规划 + +难度:困难 + +--- diff --git a/leetcode/032-LongestValidParentheses/official.md b/leetcode/032-LongestValidParentheses/official.md new file mode 100644 index 0000000..181dca1 --- /dev/null +++ b/leetcode/032-LongestValidParentheses/official.md @@ -0,0 +1,3 @@ +**32. 最长有效括号** +--- +[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) diff --git a/leetcode/943-FindTheShortestSuperstring/official.md b/leetcode/943-FindTheShortestSuperstring/official.md new file mode 100644 index 0000000..e5de8c9 --- /dev/null +++ b/leetcode/943-FindTheShortestSuperstring/official.md @@ -0,0 +1,3 @@ +**943. 最短超级串** +--- +[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) From efd47f58e393b3a03b2090469c0bdefdb3817a04 Mon Sep 17 00:00:00 2001 From: maoyanting Date: Sat, 16 Mar 2019 18:08:23 +0800 Subject: [PATCH 06/66] first commit --- leetcode/875-Koko Eating Bananas/sandao.md | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 leetcode/875-Koko Eating Bananas/sandao.md diff --git a/leetcode/875-Koko Eating Bananas/sandao.md b/leetcode/875-Koko Eating Bananas/sandao.md new file mode 100644 index 0000000..b24609d --- /dev/null +++ b/leetcode/875-Koko Eating Bananas/sandao.md @@ -0,0 +1,45 @@ +## **875. Koko吃香蕉** + +https://leetcode.com/problems/koko-eating-bananas/ + +解决方案 +**思路** + +假设piles为[A,B,C,D....],最终求出来的值为K,我们可以得出下列公式: +$$ +Math.ceil({A \over K})+Math.ceil({B \over K})+Math.ceil({C \over K})+...<=H +$$ +可以简略为 +$$ +{A \over K}+{B \over K}+{C \over K}+...<=H +$$ +此时我们能大致得出K=(A+B+C+……)/H + +此时的出来的K应该是小于我们的最终值的,递增套入公式,求出消耗时间小于H的K的最大值 + +```java +public static int minEatingSpeed(int[] piles, int H) { + //step1:求出相近值 + double sum = 0; + for (int i: piles){ + sum += (double)i/H; + } + int k = (int)sum; + //step2:从相似值开始往上找,套入公式 + for (;;k++){ + int h = 0; + for (int i: piles){ + double s = Math.ceil((double)i/k); + h += s; + } + //求出了当前情况下需要消耗的时间h,这个时间必须小于规定的H + if (h <= H ){ + return k; + } + } + } +``` + +**参考资料** + +无 \ No newline at end of file From 413124df649d03c31f9315cb8b6b4ec47ce4f324 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 17 Mar 2019 21:45:41 +0800 Subject: [PATCH 07/66] update --- leetcode/070-ClimbingStairs/official.md | 1 - leetcode/075-SortColors/bigablecat.md | 67 +++++++++ leetcode/075-SortColors/official.md | 3 + leetcode/142-linkedListCycleII/bigablecat.md | 70 --------- leetcode/142-linkedListCycleII/official.md | 3 + leetcode/167-TwoSumII/bigablecat.md | 75 +++++++++ leetcode/167-TwoSumII/official.md | 4 + leetcode/191-NumberOf1Bits/bigablecat.md | 4 +- .../bigablecat.md | 142 ++++++++++++++++++ .../sandao.md | 0 10 files changed, 296 insertions(+), 73 deletions(-) create mode 100644 leetcode/075-SortColors/bigablecat.md create mode 100644 leetcode/075-SortColors/official.md create mode 100644 leetcode/142-linkedListCycleII/official.md create mode 100644 leetcode/167-TwoSumII/bigablecat.md create mode 100644 leetcode/167-TwoSumII/official.md create mode 100644 leetcode/215-KthLargestElementInAnArray/bigablecat.md rename leetcode/{875-Koko Eating Bananas => 875-KokoEatingBananas}/sandao.md (100%) diff --git a/leetcode/070-ClimbingStairs/official.md b/leetcode/070-ClimbingStairs/official.md index db86b03..1d51693 100644 --- a/leetcode/070-ClimbingStairs/official.md +++ b/leetcode/070-ClimbingStairs/official.md @@ -1,4 +1,3 @@ **70. 爬楼梯** --- - [https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) diff --git a/leetcode/075-SortColors/bigablecat.md b/leetcode/075-SortColors/bigablecat.md new file mode 100644 index 0000000..1daac68 --- /dev/null +++ b/leetcode/075-SortColors/bigablecat.md @@ -0,0 +1,67 @@ +**75. 颜色分类** +--- +[https://leetcode-cn.com/problems/sort-colors/](https://leetcode-cn.com/problems/sort-colors/) + +* 网友高票答案: + +```java + + /** + * https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution + * 网友高票答案 + * + * @param A + */ + public void sortColors(int A[]) { + // 定义整数second代表数字2蓝色,zero代表数字0红色 + // 本方法的思路是将数字2蓝色后移到数组的右侧 + // 数字0红色前移到数组左侧 + // 剩余数字1白色在移动过程中也聚集到了中间 + // second初始值为n-1,即数组A下标的上限 + // zero初始值为0,即数组A下标的下限 + int second = A.length - 1, zero = 0; + //从左向右遍历数组A + for (int i = 0; i <= second; i++) { + //如果当前元素A[i]为2蓝色,且下标i比second小 + //交换当前元素A[i]和A[second]在数组A中的位置 + //second--作为参数传入swap方法,递减是在swap方法结束之后才进行的 + //所以swap方法中操作的是A[second] + while (A[i] == 2 && i < second) swap(A, i, second--); + //如果当前元素A[i]为0白色,且下标i比zero大 + //交换当前元素A[i]和A[zero]在数组A中的位置 + //zero++作为参数传入swap方法,递增是在swap方法结束之后才进行的 + //所以swap方法中操作的是A[zero] + while (A[i] == 0 && i > zero) swap(A, i, zero++); + } + } + + /** + * swap方法,交换数组中两个元素的位置 + * + * @param nums 数组 + * @param i 左侧元素的下标 + * @param j 右侧元素的下标 + * @return + */ + public int[] swap(int[] nums, int i, int j) { + //定义一个临时变量存放右侧元素 + int temp = nums[j]; + //将左侧元素赋值给右侧元素 + nums[j] = nums[i]; + //将临时变量存储的原右侧元素赋值给左侧元素 + nums[i] = temp; + //返回交换后的数组 + return nums; + } + +``` + +**复杂度分析** + +空间复杂度:O(1), +只定义了3个整型变量,没有使用更多额外空间,空间复杂读是O(1) + +**参考资料** + +* 网友高票答案: +[https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution](https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution) diff --git a/leetcode/075-SortColors/official.md b/leetcode/075-SortColors/official.md new file mode 100644 index 0000000..d7e50c9 --- /dev/null +++ b/leetcode/075-SortColors/official.md @@ -0,0 +1,3 @@ +**75. 颜色分类** +--- +[https://leetcode-cn.com/problems/sort-colors/](https://leetcode-cn.com/problems/sort-colors/) diff --git a/leetcode/142-linkedListCycleII/bigablecat.md b/leetcode/142-linkedListCycleII/bigablecat.md index 3698b0d..439a91c 100644 --- a/leetcode/142-linkedListCycleII/bigablecat.md +++ b/leetcode/142-linkedListCycleII/bigablecat.md @@ -1,73 +1,3 @@ **142. 环形链表 II** --- [https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) - -* 网友高票Java解法,双指针法 - -```java - - public ListNode detectCycle(ListNode head) { - //快慢指针都从头结点出发 - ListNode slow = head; - ListNode fast = head; - boolean hasCycle = false; //判断是否有环的标识 - while (fast != null && fast.next != null) { - slow = slow.next;//慢指针每次走一步 - fast = fast.next.next;//快指针每次走两步 - - if (slow == fast) { //如果快指针等于慢指针,说明有环 - hasCycle = true; - break; //跳出循环 - } - } - //如果有环,第二次循环找出环的入口 - if (hasCycle) { - //设从头结点到环入口的长度为len - //从环入口到快慢指针相遇点的距离为h - //环的长度为r - //fast和slow走过的相同路段为len+h - //fast比slow多走的路段为m(m≥1且m是整数)个r,即m*r - //设slow走过的路程为s,s=len+h - //设fast走过的路程为f,f=(len+h)+m*r - //又知道fast走过的路程是slow的两倍,即f=2s - //2(len+h) = (len+h) + m*r - // len+h = m*r - // len = m*r - h - // 将公式右边变化以后更好理解 - // len = m*r - h = (m-1)*r + (r-h) - // 让两个指针分别从头结点和相遇点出发,以相同的速度前进 - // 一个指针走完len距离时,到达环形入口 - // 另一个指针围着环绕了(m-1)圈,并且从h位置出发,走了(r-h)步 - // 第二个指针最后到达的位置为 h+(r-h) = r 正好回到环形起点,即环形的入口 - // 最终两个指针会在环形入口处相遇 - slow = head; //让慢指针从头结点重新出发 - while (slow != fast) { //当两个结点未相遇时循环继续 - //慢指针和快指针各走一步 - slow = slow.next; - fast = fast.next; - } - return slow;//循环结束后返回的结点就是环形入口 - } - return null; - } - - -``` - -**复杂度分析** - -时间复杂度:O(n), -判断是否有环时,循环了n+k次,k是快指针比慢指针多跑的长度 -查找环的入口时循环了s次,s是从头结点到环入口的距离 - -空间复杂度:O(1),只使用了两个临时变量,空间复杂度为常数O(1) - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-OƑ)-space-solution-with-detailed-explanation.) - -* 《数据结构面试 之 单链表是否有环及环入口点 附有最详细明了的图解》: -[https://www.jianshu.com/p/ef71e04241e4](https://www.jianshu.com/p/ef71e04241e4) \ No newline at end of file diff --git a/leetcode/142-linkedListCycleII/official.md b/leetcode/142-linkedListCycleII/official.md new file mode 100644 index 0000000..439a91c --- /dev/null +++ b/leetcode/142-linkedListCycleII/official.md @@ -0,0 +1,3 @@ +**142. 环形链表 II** +--- +[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/leetcode/167-TwoSumII/bigablecat.md b/leetcode/167-TwoSumII/bigablecat.md new file mode 100644 index 0000000..8565565 --- /dev/null +++ b/leetcode/167-TwoSumII/bigablecat.md @@ -0,0 +1,75 @@ +**167. 两数之和 II - 输入有序数组** +--- + +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) + + +* 双指针法 + +```java + + /** + * https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution. + * 双指针法 + * + * 时间复杂度:O(N), + * 遍历数组1次 + * + * 空间复杂度:O(1), + * 只定义了一个长度为2的整型数组变量, + * 空间复杂度为O(1) + * + * @param numbers + * @param target + * @return + */ + public static int[] twoSum(int[] numbers, int target) { + //定义一个长度为2的整数数组,用于存储返回的index1和index2 + int[] indexArr = new int[2]; + //如果输入的数组numbers为空或者长度小于2,直接返回空数组indexArr + if (numbers == null || numbers.length < 2) return indexArr; + //定义整型变量index1,从numbers初始下标0开始 + int index1 = 0; + //定义整数index2,从numbers最后一个下标numbers.length - 1开始 + int index2 = numbers.length - 1; + //从下标0开始遍历数组 + for (int index = 0; index < numbers.length; index++) { + //求得下标index1和下标index2对应元素的和sum + int sum = numbers[index1] + numbers[index2]; + //查看sum是否等于目标值target + if (sum == target) { + //符合条件则跳出for循环 + break; + } + // 如果sum不等于目标值,分别对index1和index2进行增减操作 + if (sum > target) { // 当两数相加大于目标值 + //将index2递减,右移获取更小的值 + index2--; + } else if (sum < target) { // 当两数相加小于目标值 + // 将index1递增,左移获取更大的值 + index1++; + } + } + //返回的下标从1开始计数,所以index1和index2分别加1 + indexArr[0] = index1 + 1; + indexArr[1] = index2 + 1; + return indexArr; + } + +``` + +**复杂度分析** + +时间复杂度:O(N), +遍历数组1次 + +空间复杂度:O(1), +只定义了一个长度为2的整型数组变量, +空间复杂度为O(1) + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.) \ No newline at end of file diff --git a/leetcode/167-TwoSumII/official.md b/leetcode/167-TwoSumII/official.md new file mode 100644 index 0000000..0f7315a --- /dev/null +++ b/leetcode/167-TwoSumII/official.md @@ -0,0 +1,4 @@ +**167. 两数之和 II - 输入有序数组** +--- + +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) diff --git a/leetcode/191-NumberOf1Bits/bigablecat.md b/leetcode/191-NumberOf1Bits/bigablecat.md index 73a3aba..6fe8774 100644 --- a/leetcode/191-NumberOf1Bits/bigablecat.md +++ b/leetcode/191-NumberOf1Bits/bigablecat.md @@ -90,9 +90,9 @@ 最差情况时间复杂度是32, 最终时间复杂度是O(1) -空间复杂度:O(n), +空间复杂度:O(1), 没有使用额外的空间, -空间复杂度是O(n) +空间复杂度是O(1) --- diff --git a/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/leetcode/215-KthLargestElementInAnArray/bigablecat.md new file mode 100644 index 0000000..c95274f --- /dev/null +++ b/leetcode/215-KthLargestElementInAnArray/bigablecat.md @@ -0,0 +1,142 @@ +**找数组中第K大的数** +--- +[https://leetcode.com/problems/kth-largest-element-in-an-array/](https://leetcode.com/problems/kth-largest-element-in-an-array/) + +* 《程序员面试金典(第5版)》第8章:排序与查找,结合leetCode上网友高效解法: + +```java + + /** + * @param nums + * @param k + * @return + */ + public int findKthLargest(int[] nums, int k) { + //调用递归方法找到第k个最大值 + // 第k个最大元素在数组nums从右向左数的第k个位置 + // 即从左往右数第(nums.length - k + 1)个位置 + // 数组下标从0计数,第k个最大元素的下标为 (nums.length - k + 1) - 1 = nums.length - k + return quickSelect(nums, 0, nums.length - 1, nums.length - k); + } + + /** + * 《程序员面试金典(第5版)》第8章:排序与查找 + * https://leetcode-cn.com/submissions/api/detail/215/java/3/ + *

+ * 快速选择算法 + * + * @param nums 数组 + * @param left 最左侧元素下标 + * @param right 最右侧元素下标 + * @param K 目标位置 + * @return 第k个最大值 + */ + public int quickSelect(int[] nums, int left, int right, int K) { + //如果起始下标left和结尾下标right重合,即left和right所在位置即基准值 + if (left == right) { + //返回下标start在数组中对应的值nums[start] + return nums[right]; + } + // 调用分割方法partition,返回结果index是当前排序之后基准值pivot的下标 + // pivot左侧元素小于pivot,pivot右侧元素大于pivot + int index = partition(nums, left, right); + // 本方法内的大写字母K代表数组nums中第k大的值,距离当前左边界left有多远 + // (index - left)得到本轮求得的基准值坐标index距离当前左边界left有多远 + // K与(index - left)比较大小,判断K在基准值坐标index的左侧还是右侧 + if (K >= (index - left)) { + // K >= (index - left)表示nums中第k大的值在基准值右侧 + // 取值范围nums[index]到nums[right] + // K值是到左边界left的距离 + // 左边界更新为index时,当前K值减去index到左边界left的距离得到新的K值 + return quickSelect(nums, index, right, K - (index - left)); + } else { + //第k大的值比当前基准值小,在基准值左侧,取值范围nums[left]到nums[index-1]之间 + //因为左边界left没有改变,所以仍然使用当前K值 + return quickSelect(nums, left, index - 1, K); + } + } + + /** + * 使用QuickSelection快速选择算法,分割数组 + * + * @param nums 数组 + * @param left 数组最左侧元素的下标 + * @param right 数组最右侧元素的下标 + * @return + */ + public int partition(int[] nums, int left, int right) { + // 先定义一个基准值pivot + // 本方法中选用数组最左侧和最右侧下标的平均数 + // 取得一个位于数组中间位置的元素作为基准值 + int pivot = nums[(left + right) / 2]; + //在循环体中,left递增,right递减,两个下标不断靠近 + //当left和right交叉(left>right)时,当前一轮完成了排序,循环结束 + while (left <= right) { + // while循环自左向右不断检索数组nums + // 在到达或越过pivot之前,所有nums[left]都在pivot左侧 + // 当不满足条件nums[left] < pivot时 + // 得到了一个应该被放到pivot右侧的元素,它的下标为left + while (nums[left] < pivot) { + // left不断递增 + // 即指针不断向数组右侧移动 + // 直至到达或越过基准值pivot + left++; + } + // while循环自右向左不断检索数组nums + // 在到达或越过pivot之前,所有nums[right]都在pivot右侧 + // 当不满足条件nums[right] > pivot时 + // 得到了一个应该被放到pivot左侧的元素,它的下标为right + while (nums[right] > pivot) { + // right不断递增 + // 即指针不断向数组左侧移动 + // 直至到达或越过基准值pivot + right--; + } + //经过上两轮while循环,此时nums[left]>=pivot>=nums[right] + //可以推出nums[left]>=nums[right] + //如果此时left<=right,需要交换两个元素的值,保证数组按照从小到大的次序排列 + if (left <= right) { + // 调用swap方法 + // 交换数组nums中,下标left和right对应的两个元素 + swap(nums, left, right); + //交换后下标left继续递增1次,right继续递减1次 + left++; + right--; + } + } + //返回更新后的left值 + return left; + } + + /** + * swap方法,交换数组中两个元素的位置 + * + * @param nums 数组 + * @param left 左侧元素的下标 + * @param right 右侧元素的下标 + * @return + */ + public int[] swap(int[] nums, int left, int right) { + //定义一个临时变量存放右侧元素 + int temp = nums[right]; + //将左侧元素赋值给右侧元素 + nums[right] = nums[left]; + //将临时变量存储的原右侧元素赋值给左侧元素 + nums[left] = temp; + //返回交换后的数组 + return nums; + } + +``` + +**复杂度分析** + +空间复杂度:O(1), +没有使用额外空间,空间复杂读是O(1) + +**参考资料** + +* 《程序员面试金典(第5版)》第8章:排序与查找 + +* 网友高效答案: +[https://leetcode-cn.com/submissions/api/detail/215/java/3/](https://leetcode-cn.com/submissions/api/detail/215/java/3/) diff --git a/leetcode/875-Koko Eating Bananas/sandao.md b/leetcode/875-KokoEatingBananas/sandao.md similarity index 100% rename from leetcode/875-Koko Eating Bananas/sandao.md rename to leetcode/875-KokoEatingBananas/sandao.md From 80a39dbccab05bbebecc61bf9dec1f6389f760ea Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 17 Mar 2019 23:22:37 +0800 Subject: [PATCH 08/66] update new questions --- README.md | 2 +- contribute.md | 8 +--- leetcode/321-CreateMaximumNumber/official.md | 48 ++++++++++++++++++++ leetcode/403-FrogJump/official.md | 47 +++++++++++++++++++ 4 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 leetcode/321-CreateMaximumNumber/official.md create mode 100644 leetcode/403-FrogJump/official.md diff --git a/README.md b/README.md index e33c005..2c0542b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### 算法每日一练 -* 这个专栏是Hollis知识星球的朋友们练习算法的地方 +* 这个专栏是Hollis知识星球的朋友们练习算法的地方,同时也欢迎广大网友参与 * 所有题目来源是[leetCode](https://leetcode-cn.com/problemset/all/)官方公开题库 ### 初学者友好的算法题目解答 diff --git a/contribute.md b/contribute.md index 1af35a4..ed55f6f 100644 --- a/contribute.md +++ b/contribute.md @@ -1,7 +1,7 @@ 提交答案步骤 --- ->各位Hollis的朋友们,在向本项目提交您的答案详解时,请阅读以下内容 +>各位网友好,在向本项目提交您的答案详解时,请阅读以下内容
@@ -103,9 +103,3 @@ 4) 在git上提交你的文件,管理员审核通过后大家就能看到你的答案并和你讨论了 --- - -**参考资料** - -1) [leetCode中文题库](https://leetcode-cn.com/problemset/all/) - -2) [覃超《算法面试通关40讲》课件](https://github.com/geektime-geekbang/algorithm-1) diff --git a/leetcode/321-CreateMaximumNumber/official.md b/leetcode/321-CreateMaximumNumber/official.md new file mode 100644 index 0000000..e379863 --- /dev/null +++ b/leetcode/321-CreateMaximumNumber/official.md @@ -0,0 +1,48 @@ +**321. 拼接最大数** +--- +[https://leetcode-cn.com/problems/create-maximum-number/](https://leetcode-cn.com/problems/create-maximum-number/) + +**难度** +困难 + +**题目描述** + +给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。 + +求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。 + +说明: 请尽可能地优化你算法的时间和空间复杂度。 + +**示例 1:** +``` +输入: +nums1 = [3, 4, 6, 5] +nums2 = [9, 1, 2, 5, 8, 3] +k = 5 +输出: +[9, 8, 6, 5, 3] +``` + +**示例 2:** +``` +输入: +nums1 = [6, 7] +nums2 = [6, 0, 4] +k = 5 +输出: +[6, 7, 6, 0, 4] +``` + +**示例 3:** +``` +输入: +nums1 = [3, 9] +nums2 = [8, 9] +k = 3 +输出: +[9, 8, 9] +``` + + +**相关话题** +贪心算法,动态规划 \ No newline at end of file diff --git a/leetcode/403-FrogJump/official.md b/leetcode/403-FrogJump/official.md new file mode 100644 index 0000000..bfb5af2 --- /dev/null +++ b/leetcode/403-FrogJump/official.md @@ -0,0 +1,47 @@ +**403. 青蛙过河** +--- +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +**难度** +困难 + +**题目描述** + +一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 + +给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 + +如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 + +**请注意:** + +* 石子的数量 ≥ 2 且 < 1100; +* 每一个石子的位置序号都是一个非负整数,且其 < 231; +* 第一个石子的位置永远是0。 + +**示例 1:** +```shell +[0,1,3,5,6,8,12,17] + +总共有8个石子。 +第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, +第三个石子在序号为3的单元格的位置, 以此定义整个数组... +最后一个石子处于序号为17的单元格的位置。 + +返回 true。即青蛙可以成功过河,按照如下方案跳跃: +跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 +跳2个单位到第4块石子, 然后跳3个单位到第6块石子, +跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 +``` + +**示例 2:** +```shell + +[0,1,2,3,4,8,9,11] + +返回 false。青蛙没有办法过河。 +这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 +``` + +**相关话题** +贪心算法,动态规划 \ No newline at end of file From f53245a01f03c821f62a33f59c63b805631098c5 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 17 Mar 2019 23:32:39 +0800 Subject: [PATCH 09/66] update --- README.md | 34 ++++++++++++++++++++++++ leetcode/403-FrogJump/README.md | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 leetcode/403-FrogJump/README.md diff --git a/README.md b/README.md index 2c0542b..c47855b 100644 --- a/README.md +++ b/README.md @@ -2120,3 +2120,37 @@ 难度:困难 --- + + +2019年04月03日 + +[403. 青蛙过河](https://github.com/hollischuang/algorithm/tree/master/leetcode/403-FrogJump) + +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- + + +2019年04月04日 + +[321. 拼接最大数](https://github.com/hollischuang/algorithm/tree/master/leetcode/321-CreateMaximumNumber) + +[https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- diff --git a/leetcode/403-FrogJump/README.md b/leetcode/403-FrogJump/README.md new file mode 100644 index 0000000..bfb5af2 --- /dev/null +++ b/leetcode/403-FrogJump/README.md @@ -0,0 +1,47 @@ +**403. 青蛙过河** +--- +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +**难度** +困难 + +**题目描述** + +一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 + +给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 + +如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 + +**请注意:** + +* 石子的数量 ≥ 2 且 < 1100; +* 每一个石子的位置序号都是一个非负整数,且其 < 231; +* 第一个石子的位置永远是0。 + +**示例 1:** +```shell +[0,1,3,5,6,8,12,17] + +总共有8个石子。 +第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, +第三个石子在序号为3的单元格的位置, 以此定义整个数组... +最后一个石子处于序号为17的单元格的位置。 + +返回 true。即青蛙可以成功过河,按照如下方案跳跃: +跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 +跳2个单位到第4块石子, 然后跳3个单位到第6块石子, +跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 +``` + +**示例 2:** +```shell + +[0,1,2,3,4,8,9,11] + +返回 false。青蛙没有办法过河。 +这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 +``` + +**相关话题** +贪心算法,动态规划 \ No newline at end of file From 42f180844ea745be7c2cfc7b76f02f367d90a056 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 17 Mar 2019 23:33:36 +0800 Subject: [PATCH 10/66] update --- leetcode/321-CreateMaximumNumber/{official.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename leetcode/321-CreateMaximumNumber/{official.md => README.md} (100%) diff --git a/leetcode/321-CreateMaximumNumber/official.md b/leetcode/321-CreateMaximumNumber/README.md similarity index 100% rename from leetcode/321-CreateMaximumNumber/official.md rename to leetcode/321-CreateMaximumNumber/README.md From f97f66302b013906313755257c707f063c973107 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 20 Mar 2019 23:32:53 +0800 Subject: [PATCH 11/66] update --- leetcode/169-majorityElement/README.md | 153 ++++++++++++++++++ leetcode/169-majorityElement/bigablecat.md | 152 ++--------------- leetcode/260-SingleNumberIII/README.md | 17 ++ .../README.md | 22 +++ leetcode/409-LongestPalindrome/README.md | 23 +++ .../README.md | 20 +++ leetcode/504-Base7/README.md | 20 +++ 7 files changed, 265 insertions(+), 142 deletions(-) create mode 100644 leetcode/169-majorityElement/README.md create mode 100644 leetcode/260-SingleNumberIII/README.md create mode 100644 leetcode/378-KthSmallestElementInASortedMatrix/README.md create mode 100644 leetcode/409-LongestPalindrome/README.md create mode 100644 leetcode/462-MinimumMovesToEqualArrayElementsII/README.md create mode 100644 leetcode/504-Base7/README.md diff --git a/leetcode/169-majorityElement/README.md b/leetcode/169-majorityElement/README.md new file mode 100644 index 0000000..bd70016 --- /dev/null +++ b/leetcode/169-majorityElement/README.md @@ -0,0 +1,153 @@ +**169. 求众数** +--- +[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) + +* 官方题解2,hashMap + +```java + + public int majorityElement(int[] nums) { + //获取通过hashMap方法得到的数组中所有元素的计数 + Map counts = countNums(nums); + //临时变量用于存储hashMap中取出的众数 + Map.Entry majorityEntry = null; + //遍历hashMap中的每一个元素 + for (Map.Entry entry : counts.entrySet()) { + //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 + if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { + //让众数临时变量等于当前元素 + majorityEntry = entry; + } + } + //经过循环,得到计数最大的值,即所求的众数 + //majorityEntry是hashMap的元素,getKey()获得众数的数字 + return majorityEntry.getKey(); + } + + private Map countNums(int[] nums) { + //创建一个HashMap对象counts用于存储已经出现过的数字 + Map counts = new HashMap(); + //遍历int数组 + for (int num : nums) { + //查看hashMap中是否已经存在当前数字 + if (!counts.containsKey(num)) { + //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 + counts.put(num, 1); + } else { + //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 + counts.put(num, counts.get(num) + 1); + } + } + //返回hashMap + return counts; + } + + +``` + +**复杂度分析** + +时间复杂度:O(n),遍历数组时间复杂度O(n), +遍历HashMap对象的所有元素时间复杂度也是O(n), +最终时间复杂度为n+n,所以是O(n) + +空间复杂度:O(n), +众数在n个元素中最少出现的次数为 2/n+1, +那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, +众数本身也是一个元素,与其他非众数元素不同, +所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 +HashMap保存这些不同的元素需要占用n/2的空间, +所以空间复杂度是O(n/2) + +--- + +* 官方题解5,递归和分治 + +```java + + public int majorityElement(int[] nums) { + return majorityElementRec(nums, 0, nums.length - 1); + } + + /** + * 递归方法 + * + * @param nums + * @param lo + * @param hi + * @return + */ + private int majorityElementRec(int[] nums, int lo, int hi) { + //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 + if (lo == hi) { + return nums[lo]; + } + + //获取数组的中位数元素下标 + // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 + // (hi - lo) / 2 + lo得到数组中间元素的下标 + int mid = (hi - lo) / 2 + lo; + //数组的左半部分从首个元素下标lo到中间元素下标mid + int left = majorityElementRec(nums, lo, mid); + //数组的右半部分从中间元素下标mid到最后一个元素下标hi + int right = majorityElementRec(nums, mid + 1, hi); + + // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 + if (left == right) { + return left; + } + + //统计左半边众数出现的总次数 + int leftCount = countInRange(nums, left, lo, hi); + //统计右半边众数出现的总次数 + int rightCount = countInRange(nums, right, lo, hi); + + //返回较大的候选众数 + return leftCount > rightCount ? left : right; + } + + + /** + * 计算候选众数在某个数组片段中出现的总次数 + * + * @param nums + * @param num + * @param lo + * @param hi + * @return + */ + private int countInRange(int[] nums, int num, int lo, int hi) { + //定义一个计时器count + int count = 0; + //遍历从下标lo到下标hi的元素 + for (int i = lo; i <= hi; i++) { + //如果获得的元素与当前传入的候选众数num相等,计数器加1 + if (nums[i] == num) { + count++; + } + } + //返回候选众数在当前数组片段中出现的总次数 + return count; + } + +``` + +**复杂度分析** + +时间复杂度 : O(nlogn), +每次递归,n就被2分一次,n/2/2... +所以总共调用递归方法的次数是logn次, +递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), +所以总的时间复杂度是n*logn + +空间复杂度:O(logn), +因为进行了logn次的递归调用, +每次递归都占用O(1)的空间复杂度, +所以最终空间复杂度为O(logn) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) diff --git a/leetcode/169-majorityElement/bigablecat.md b/leetcode/169-majorityElement/bigablecat.md index bd70016..a61b7df 100644 --- a/leetcode/169-majorityElement/bigablecat.md +++ b/leetcode/169-majorityElement/bigablecat.md @@ -2,152 +2,20 @@ --- [https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) -* 官方题解2,hashMap +给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 -```java - - public int majorityElement(int[] nums) { - //获取通过hashMap方法得到的数组中所有元素的计数 - Map counts = countNums(nums); - //临时变量用于存储hashMap中取出的众数 - Map.Entry majorityEntry = null; - //遍历hashMap中的每一个元素 - for (Map.Entry entry : counts.entrySet()) { - //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 - if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { - //让众数临时变量等于当前元素 - majorityEntry = entry; - } - } - //经过循环,得到计数最大的值,即所求的众数 - //majorityEntry是hashMap的元素,getKey()获得众数的数字 - return majorityEntry.getKey(); - } - - private Map countNums(int[] nums) { - //创建一个HashMap对象counts用于存储已经出现过的数字 - Map counts = new HashMap(); - //遍历int数组 - for (int num : nums) { - //查看hashMap中是否已经存在当前数字 - if (!counts.containsKey(num)) { - //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 - counts.put(num, 1); - } else { - //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 - counts.put(num, counts.get(num) + 1); - } - } - //返回hashMap - return counts; - } +你可以假设数组是非空的,并且给定的数组总是存在众数。 +示例 1: ``` - -**复杂度分析** - -时间复杂度:O(n),遍历数组时间复杂度O(n), -遍历HashMap对象的所有元素时间复杂度也是O(n), -最终时间复杂度为n+n,所以是O(n) - -空间复杂度:O(n), -众数在n个元素中最少出现的次数为 2/n+1, -那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, -众数本身也是一个元素,与其他非众数元素不同, -所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 -HashMap保存这些不同的元素需要占用n/2的空间, -所以空间复杂度是O(n/2) - ---- - -* 官方题解5,递归和分治 - -```java - - public int majorityElement(int[] nums) { - return majorityElementRec(nums, 0, nums.length - 1); - } - - /** - * 递归方法 - * - * @param nums - * @param lo - * @param hi - * @return - */ - private int majorityElementRec(int[] nums, int lo, int hi) { - //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 - if (lo == hi) { - return nums[lo]; - } - - //获取数组的中位数元素下标 - // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 - // (hi - lo) / 2 + lo得到数组中间元素的下标 - int mid = (hi - lo) / 2 + lo; - //数组的左半部分从首个元素下标lo到中间元素下标mid - int left = majorityElementRec(nums, lo, mid); - //数组的右半部分从中间元素下标mid到最后一个元素下标hi - int right = majorityElementRec(nums, mid + 1, hi); - - // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 - if (left == right) { - return left; - } - - //统计左半边众数出现的总次数 - int leftCount = countInRange(nums, left, lo, hi); - //统计右半边众数出现的总次数 - int rightCount = countInRange(nums, right, lo, hi); - - //返回较大的候选众数 - return leftCount > rightCount ? left : right; - } - - - /** - * 计算候选众数在某个数组片段中出现的总次数 - * - * @param nums - * @param num - * @param lo - * @param hi - * @return - */ - private int countInRange(int[] nums, int num, int lo, int hi) { - //定义一个计时器count - int count = 0; - //遍历从下标lo到下标hi的元素 - for (int i = lo; i <= hi; i++) { - //如果获得的元素与当前传入的候选众数num相等,计数器加1 - if (nums[i] == num) { - count++; - } - } - //返回候选众数在当前数组片段中出现的总次数 - return count; - } - +输入: [3,2,3] +输出: 3 ``` -**复杂度分析** +示例 2: -时间复杂度 : O(nlogn), -每次递归,n就被2分一次,n/2/2... -所以总共调用递归方法的次数是logn次, -递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), -所以总的时间复杂度是n*logn - -空间复杂度:O(logn), -因为进行了logn次的递归调用, -每次递归都占用O(1)的空间复杂度, -所以最终空间复杂度为O(logn) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) +``` +输入: [2,2,1,1,1,2,2] +输出: 2 +``` \ No newline at end of file diff --git a/leetcode/260-SingleNumberIII/README.md b/leetcode/260-SingleNumberIII/README.md new file mode 100644 index 0000000..6797db8 --- /dev/null +++ b/leetcode/260-SingleNumberIII/README.md @@ -0,0 +1,17 @@ +**260. 只出现一次的数字 III** +--- +[https://leetcode-cn.com/problems/single-number-iii/](https://leetcode-cn.com/problems/single-number-iii/) + +给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 + +示例 : + +``` +输入: [1,2,1,3,2,5] +输出: [3,5] +``` + +注意: + +1. 结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。 +2. 你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现? diff --git a/leetcode/378-KthSmallestElementInASortedMatrix/README.md b/leetcode/378-KthSmallestElementInASortedMatrix/README.md new file mode 100644 index 0000000..6ed3e49 --- /dev/null +++ b/leetcode/378-KthSmallestElementInASortedMatrix/README.md @@ -0,0 +1,22 @@ +**378. 有序矩阵中第K小的元素** +--- +[https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/](https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/) + +给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 +请注意,它是排序后的第k小元素,而不是第k个元素。 + +示例: + +``` +matrix = [ + [ 1, 5, 9], + [10, 11, 13], + [12, 13, 15] +], +k = 8, + +返回 13。 +``` + +**说明:** +你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。 diff --git a/leetcode/409-LongestPalindrome/README.md b/leetcode/409-LongestPalindrome/README.md new file mode 100644 index 0000000..88bd80e --- /dev/null +++ b/leetcode/409-LongestPalindrome/README.md @@ -0,0 +1,23 @@ +**409. 最长回文串** +--- +[https://leetcode-cn.com/problems/longest-palindrome/](https://leetcode-cn.com/problems/longest-palindrome/) + +给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 + +在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。 + +注意: +假设字符串的长度不会超过 1010。 + +示例 1: + +``` +输入: +"abccccdd" + +输出: +7 + +解释: +我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。 +``` diff --git a/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md b/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md new file mode 100644 index 0000000..e172f8f --- /dev/null +++ b/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md @@ -0,0 +1,20 @@ +**462. 最少移动次数使数组元素相等 II** +--- +[https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/](https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/) + +给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。 + +``` +例如: + +输入: +[1,2,3] + +输出: +2 + +说明: +只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1): + +[1,2,3] => [2,2,3] => [2,2,2] +``` diff --git a/leetcode/504-Base7/README.md b/leetcode/504-Base7/README.md new file mode 100644 index 0000000..1a2d90a --- /dev/null +++ b/leetcode/504-Base7/README.md @@ -0,0 +1,20 @@ +**504. 七进制数** +--- +[https://leetcode-cn.com/problems/base-7/](https://leetcode-cn.com/problems/base-7/) + +给定一个整数,将其转化为7进制,并以字符串形式输出。 + +示例 1: + +``` +输入: 100 +输出: "202" +``` + +示例 2: + +``` +输入: -7 +输出: "-10" +注意: 输入范围是 [-1e7, 1e7] 。 +``` From 2c5391ea78aa6f1310ce2f49cbaeca070ee01815 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 20 Mar 2019 23:36:23 +0800 Subject: [PATCH 12/66] update --- leetcode/169-majorityElement/README.md | 152 ++------------------- leetcode/169-majorityElement/bigablecat.md | 152 +++++++++++++++++++-- 2 files changed, 152 insertions(+), 152 deletions(-) diff --git a/leetcode/169-majorityElement/README.md b/leetcode/169-majorityElement/README.md index bd70016..e268062 100644 --- a/leetcode/169-majorityElement/README.md +++ b/leetcode/169-majorityElement/README.md @@ -2,152 +2,20 @@ --- [https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) -* 官方题解2,hashMap +给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 -```java - - public int majorityElement(int[] nums) { - //获取通过hashMap方法得到的数组中所有元素的计数 - Map counts = countNums(nums); - //临时变量用于存储hashMap中取出的众数 - Map.Entry majorityEntry = null; - //遍历hashMap中的每一个元素 - for (Map.Entry entry : counts.entrySet()) { - //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 - if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { - //让众数临时变量等于当前元素 - majorityEntry = entry; - } - } - //经过循环,得到计数最大的值,即所求的众数 - //majorityEntry是hashMap的元素,getKey()获得众数的数字 - return majorityEntry.getKey(); - } - - private Map countNums(int[] nums) { - //创建一个HashMap对象counts用于存储已经出现过的数字 - Map counts = new HashMap(); - //遍历int数组 - for (int num : nums) { - //查看hashMap中是否已经存在当前数字 - if (!counts.containsKey(num)) { - //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 - counts.put(num, 1); - } else { - //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 - counts.put(num, counts.get(num) + 1); - } - } - //返回hashMap - return counts; - } +你可以假设数组是非空的,并且给定的数组总是存在众数。 +示例 1: ``` - -**复杂度分析** - -时间复杂度:O(n),遍历数组时间复杂度O(n), -遍历HashMap对象的所有元素时间复杂度也是O(n), -最终时间复杂度为n+n,所以是O(n) - -空间复杂度:O(n), -众数在n个元素中最少出现的次数为 2/n+1, -那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, -众数本身也是一个元素,与其他非众数元素不同, -所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 -HashMap保存这些不同的元素需要占用n/2的空间, -所以空间复杂度是O(n/2) - ---- - -* 官方题解5,递归和分治 - -```java - - public int majorityElement(int[] nums) { - return majorityElementRec(nums, 0, nums.length - 1); - } - - /** - * 递归方法 - * - * @param nums - * @param lo - * @param hi - * @return - */ - private int majorityElementRec(int[] nums, int lo, int hi) { - //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 - if (lo == hi) { - return nums[lo]; - } - - //获取数组的中位数元素下标 - // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 - // (hi - lo) / 2 + lo得到数组中间元素的下标 - int mid = (hi - lo) / 2 + lo; - //数组的左半部分从首个元素下标lo到中间元素下标mid - int left = majorityElementRec(nums, lo, mid); - //数组的右半部分从中间元素下标mid到最后一个元素下标hi - int right = majorityElementRec(nums, mid + 1, hi); - - // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 - if (left == right) { - return left; - } - - //统计左半边众数出现的总次数 - int leftCount = countInRange(nums, left, lo, hi); - //统计右半边众数出现的总次数 - int rightCount = countInRange(nums, right, lo, hi); - - //返回较大的候选众数 - return leftCount > rightCount ? left : right; - } - - - /** - * 计算候选众数在某个数组片段中出现的总次数 - * - * @param nums - * @param num - * @param lo - * @param hi - * @return - */ - private int countInRange(int[] nums, int num, int lo, int hi) { - //定义一个计时器count - int count = 0; - //遍历从下标lo到下标hi的元素 - for (int i = lo; i <= hi; i++) { - //如果获得的元素与当前传入的候选众数num相等,计数器加1 - if (nums[i] == num) { - count++; - } - } - //返回候选众数在当前数组片段中出现的总次数 - return count; - } - +输入: [3,2,3] +输出: 3 ``` -**复杂度分析** - -时间复杂度 : O(nlogn), -每次递归,n就被2分一次,n/2/2... -所以总共调用递归方法的次数是logn次, -递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), -所以总的时间复杂度是n*logn +示例 2: -空间复杂度:O(logn), -因为进行了logn次的递归调用, -每次递归都占用O(1)的空间复杂度, -所以最终空间复杂度为O(logn) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) +``` +输入: [2,2,1,1,1,2,2] +输出: 2 +``` diff --git a/leetcode/169-majorityElement/bigablecat.md b/leetcode/169-majorityElement/bigablecat.md index a61b7df..bd70016 100644 --- a/leetcode/169-majorityElement/bigablecat.md +++ b/leetcode/169-majorityElement/bigablecat.md @@ -2,20 +2,152 @@ --- [https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) -给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 +* 官方题解2,hashMap -你可以假设数组是非空的,并且给定的数组总是存在众数。 +```java + + public int majorityElement(int[] nums) { + //获取通过hashMap方法得到的数组中所有元素的计数 + Map counts = countNums(nums); + //临时变量用于存储hashMap中取出的众数 + Map.Entry majorityEntry = null; + //遍历hashMap中的每一个元素 + for (Map.Entry entry : counts.entrySet()) { + //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 + if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { + //让众数临时变量等于当前元素 + majorityEntry = entry; + } + } + //经过循环,得到计数最大的值,即所求的众数 + //majorityEntry是hashMap的元素,getKey()获得众数的数字 + return majorityEntry.getKey(); + } + + private Map countNums(int[] nums) { + //创建一个HashMap对象counts用于存储已经出现过的数字 + Map counts = new HashMap(); + //遍历int数组 + for (int num : nums) { + //查看hashMap中是否已经存在当前数字 + if (!counts.containsKey(num)) { + //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 + counts.put(num, 1); + } else { + //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 + counts.put(num, counts.get(num) + 1); + } + } + //返回hashMap + return counts; + } -示例 1: ``` -输入: [3,2,3] -输出: 3 -``` -示例 2: +**复杂度分析** + +时间复杂度:O(n),遍历数组时间复杂度O(n), +遍历HashMap对象的所有元素时间复杂度也是O(n), +最终时间复杂度为n+n,所以是O(n) + +空间复杂度:O(n), +众数在n个元素中最少出现的次数为 2/n+1, +那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, +众数本身也是一个元素,与其他非众数元素不同, +所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 +HashMap保存这些不同的元素需要占用n/2的空间, +所以空间复杂度是O(n/2) + +--- + +* 官方题解5,递归和分治 + +```java + + public int majorityElement(int[] nums) { + return majorityElementRec(nums, 0, nums.length - 1); + } + + /** + * 递归方法 + * + * @param nums + * @param lo + * @param hi + * @return + */ + private int majorityElementRec(int[] nums, int lo, int hi) { + //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 + if (lo == hi) { + return nums[lo]; + } + + //获取数组的中位数元素下标 + // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 + // (hi - lo) / 2 + lo得到数组中间元素的下标 + int mid = (hi - lo) / 2 + lo; + //数组的左半部分从首个元素下标lo到中间元素下标mid + int left = majorityElementRec(nums, lo, mid); + //数组的右半部分从中间元素下标mid到最后一个元素下标hi + int right = majorityElementRec(nums, mid + 1, hi); + + // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 + if (left == right) { + return left; + } + + //统计左半边众数出现的总次数 + int leftCount = countInRange(nums, left, lo, hi); + //统计右半边众数出现的总次数 + int rightCount = countInRange(nums, right, lo, hi); + + //返回较大的候选众数 + return leftCount > rightCount ? left : right; + } + + + /** + * 计算候选众数在某个数组片段中出现的总次数 + * + * @param nums + * @param num + * @param lo + * @param hi + * @return + */ + private int countInRange(int[] nums, int num, int lo, int hi) { + //定义一个计时器count + int count = 0; + //遍历从下标lo到下标hi的元素 + for (int i = lo; i <= hi; i++) { + //如果获得的元素与当前传入的候选众数num相等,计数器加1 + if (nums[i] == num) { + count++; + } + } + //返回候选众数在当前数组片段中出现的总次数 + return count; + } ``` -输入: [2,2,1,1,1,2,2] -输出: 2 -``` \ No newline at end of file + +**复杂度分析** + +时间复杂度 : O(nlogn), +每次递归,n就被2分一次,n/2/2... +所以总共调用递归方法的次数是logn次, +递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), +所以总的时间复杂度是n*logn + +空间复杂度:O(logn), +因为进行了logn次的递归调用, +每次递归都占用O(1)的空间复杂度, +所以最终空间复杂度为O(logn) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) From 8b3069ef1fe558ab589efdf909765a5224ab3280 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 20 Mar 2019 23:40:32 +0800 Subject: [PATCH 13/66] update --- leetcode/504-Base7/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/leetcode/504-Base7/README.md b/leetcode/504-Base7/README.md index 1a2d90a..2fd8e8e 100644 --- a/leetcode/504-Base7/README.md +++ b/leetcode/504-Base7/README.md @@ -18,3 +18,5 @@ 输出: "-10" 注意: 输入范围是 [-1e7, 1e7] 。 ``` + +注意: 输入范围是 [-1e7, 1e7] 。 From 671545264bd314ae0c3ea01ddf28aeb86893c62a Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 20 Mar 2019 23:41:46 +0800 Subject: [PATCH 14/66] update --- leetcode/504-Base7/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/leetcode/504-Base7/README.md b/leetcode/504-Base7/README.md index 2fd8e8e..9f127ba 100644 --- a/leetcode/504-Base7/README.md +++ b/leetcode/504-Base7/README.md @@ -16,7 +16,6 @@ ``` 输入: -7 输出: "-10" -注意: 输入范围是 [-1e7, 1e7] 。 ``` 注意: 输入范围是 [-1e7, 1e7] 。 From 6bac5020aaacaeb925b2747b190171e3a5210c83 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Thu, 21 Mar 2019 10:48:06 +0800 Subject: [PATCH 15/66] Create zengdiqing1994.md --- .../409-LongestPalindrome/zengdiqing1994.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 leetcode/409-LongestPalindrome/zengdiqing1994.md diff --git a/leetcode/409-LongestPalindrome/zengdiqing1994.md b/leetcode/409-LongestPalindrome/zengdiqing1994.md new file mode 100644 index 0000000..02aac58 --- /dev/null +++ b/leetcode/409-LongestPalindrome/zengdiqing1994.md @@ -0,0 +1,52 @@ +**409. 最长回文串** +--- +[https://leetcode-cn.com/problems/longest-palindrome/](https://leetcode-cn.com/problems/longest-palindrome/) + +给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 + +在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。 + +注意: +假设字符串的长度不会超过 1010。 + +示例 1: + +``` +输入: +"abccccdd" + +输出: +7 + +解释: +我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。 +``` + +思路:这道回文字符串包括以前的回文字符串的题目都比较重要,由于这里的字符串可以打乱,所以问题就转化成了求偶数个字符的个数,我们了解的回文字符串都知道, +回文串主要有两种形式,一个是左右完全对称的,比如noon,还有一种是以中心字符为中心,左右对称,比如bob,那么统计出来所有偶数个字符的出现总和,然后如果有 +奇数个字符的化,我们取出其最大偶数,然后最后结果加上1就可以啦。 + +```py +class Solution: + def longestPalindrome(self, s: str) -> int: + dict1 = {} #用来存储出现过的字符和出现的次数 + j = 0 #存储回文长度 + z = 0 #统计单数次字符的个数 + for i in range(len(s)): + if s[i] in dict1: + dict1[s[i]] += 1 #出现的字符作为键,次数作为value值 + else: + dict1[s[i]] = 1 + for v in dict1: #对构建好的字典进行遍历 + if (dict1[v] + 1) % 2==0: #出现单数次字符次数减一 + j+=(dict1[v]-1) + z+=1 + if dict1[v] % 2 == 0: #出现偶数次字符,一定可以构造 + j+=dict1[v] + if z > 0: + return j+1 + else: + return j +``` +这个时间复杂度较高:O(n^2) +空间复杂度O(n) From f859e541220f343309959a3c9573246d0dd6a9c0 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Fri, 22 Mar 2019 10:23:52 +0800 Subject: [PATCH 16/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md diff --git a/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md b/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md new file mode 100644 index 0000000..eb43905 --- /dev/null +++ b/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md @@ -0,0 +1,53 @@ +给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 +请注意,它是排序后的第k小元素,而不是第k个元素。 + +示例: + +matrix = [ + [ 1, 5, 9], + [10, 11, 13], + [12, 13, 15] +], +k = 8, + +返回 13。 + +思路: + +二分查找及其优化,由于是有序矩阵,那么左上角的数字一定是最小的,右下角的数字一定是最大的,所以这是我们搜索的范围,算出中间数字mid,由于矩阵中不同行之间的 +元素不是严格有序的,但是每一列是有序的,可以利用这个性质,从数组的左下角开始查找,如果比目标值小,我们就向右移动一位,而且我们知道当列的当前位置的上面 +的所有数字都小于目标值,那么cnt+=1,反之则向上移一位,这样能算出cnt值,然后和target数字比较,进行二分查找。left和right最终会相等。 + + +```py +class Solution(object): + def kthSmallest(self, matrix, k): + """ + :type matrix: List[List[int]] + :type k: int + :rtype: int + """ + left,right = matrix[0][0],matrix[-1][-1] + while left < right: + mid = left + (right - left)/2 #进行二分 + cnt = self.search_less_equal(matrix,mid) + if cnt < k: #进行比较 + left = mid+1 + else: + right = mid + return left + + def search_less_equal(self,matrix,target): + n = len(matrix) + i,j,res = n-1,0,0 + while i >= 0 and j < n: + if matrix[i][j] <= target: + res += i+1 #如果左下角的数比target小,那么就向右移 + j += 1 + else: #反之向上移动 + i -= 1 + + return res +``` + +时间复杂度O(nlgX),X为最大值和最小值的差值 From 0be6f3eea0ea2ba843f504a855ca52669f92d19e Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 24 Mar 2019 21:47:48 +0800 Subject: [PATCH 17/66] update new questions --- _site/README.md | 2156 +++++++++++++++++ _site/contribute.md | 105 + _site/leetcode/001-twoSum/hatrick.md | 39 + _site/leetcode/001-twoSum/official.md | 4 + _site/leetcode/001-twoSum/woody.md | 53 + _site/leetcode/002-addTwoNumber/monkey.md | 47 + .../monkey.md | 43 + .../hatrick.md | 60 + .../official.md | 3 + _site/leetcode/015-threeSum/hatrick.md | 52 + _site/leetcode/015-threeSum/official.md | 4 + .../leetcode/020-validParentheses/official.md | 4 + .../leetcode/024-swapNodesInPairs/official.md | 4 + .../025-reverseNodesInKGroup/bigablecat.md | 75 + .../025-reverseNodesInKGroup/official.md | 4 + .../032-LongestValidParentheses/official.md | 3 + _site/leetcode/036-ValidSudoku/SpecialYang.md | 113 + _site/leetcode/036-ValidSudoku/official.md | 4 + .../leetcode/037-SudokuSolver/SpecialYang.md | 97 + _site/leetcode/037-SudokuSolver/official.md | 4 + _site/leetcode/050-powxN/bigablecat.md | 57 + _site/leetcode/051-NQueens/melody-l.md | 94 + _site/leetcode/051-NQueens/official.md | 4 + _site/leetcode/052-N-QueensII/hatrick.md | 61 + _site/leetcode/052-N-QueensII/official.md | 4 + .../leetcode/053-maximumSubarray/BambooYH.md | 59 + .../leetcode/053-maximumSubarray/official.md | 3 + _site/leetcode/062-UniquePaths/BambooYH.md | 64 + _site/leetcode/062-UniquePaths/official.md | 3 + .../leetcode/063-UniquePathsII/SpecialYang.md | 115 + _site/leetcode/063-UniquePathsII/official.md | 3 + _site/leetcode/064-minimumPathSum/melody-l.md | 54 + _site/leetcode/064-minimumPathSum/official.md | 3 + _site/leetcode/069-SqrtX/official.md | 4 + _site/leetcode/070-ClimbingStairs/melody-l.md | 113 + _site/leetcode/070-ClimbingStairs/official.md | 3 + _site/leetcode/072-EditDistance/official.md | 3 + _site/leetcode/075-SortColors/bigablecat.md | 67 + .../leetcode}/075-SortColors/official.md | 0 .../leetcode/085-MaximalRectangle/passself.md | 189 ++ _site/leetcode/087-ScrambleString/official.md | 3 + _site/leetcode/091-DecodeWays/melody-l.md | 73 + _site/leetcode/091-DecodeWays/official.md | 3 + .../095-UniqueBinarySearchTreesII/melody-l.md | 82 + .../095-UniqueBinarySearchTreesII/official.md | 3 + .../096-uniqueBinarySearchTrees/official.md | 3 + .../097-InterleavingString/official.md | 3 + .../098-validateBinarySearchTree/BambooYH.md | 47 + .../SpecialYang.md | 121 + .../hatrick.md | 42 + .../official.md | 4 + .../zengdiqing1994.md | 42 + .../104-MaximumDepthOfBinaryTree/melody-l.md | 100 + .../104-MaximumDepthOfBinaryTree/official.md | 4 + .../115-DistinctSubsequences/official.md | 4 + _site/leetcode/120-Triangle/melody-l.md | 59 + _site/leetcode/120-Triangle/official.md | 4 + .../bigablecat.md | 101 + .../121-bestTimeToBuyAndSellStock/official.md | 4 + .../SpecialYang.md | 52 + .../bigablecat.md | 141 ++ .../SpecialYang.md | 106 + .../official.md | 4 + .../131-PalindromePartitioning/official.md | 3 + .../132-PalindromePartitioningII/official.md | 3 + _site/leetcode/139-WordBreak/official.md | 3 + _site/leetcode/140-WordBreakII/official.md | 3 + .../leetcode/141-linkedListCycle/official.md | 62 + .../142-linkedListCycleII/bigablecat.md | 3 + .../142-linkedListCycleII/official.md | 3 + _site/leetcode/146-lruCache/hatrick.md | 98 + _site/leetcode/146-lruCache/official.md | 3 + .../152-MaximumProductSubarray/SpecialYang.md | 43 + .../152-MaximumProductSubarray/official.md | 4 + _site/leetcode/167-TwoSumII/bigablecat.md | 75 + .../leetcode}/167-TwoSumII/official.md | 0 _site/leetcode/169-majorityElement/README.md | 21 + .../169-majorityElement/SpecialYang.md | 109 + .../169-majorityElement/bigablecat.md | 153 ++ _site/leetcode/174-DungeonGame/passself.md | 81 + .../BambooYH.md | 44 + .../official.md | 4 + .../leetcode/191-NumberOf1Bits/bigablecat.md | 102 + _site/leetcode/198-houseRobber/hatrick.md | 49 + _site/leetcode/198-houseRobber/official.md | 3 + .../leetcode/200-numberOfIslands/BambooYH.md | 105 + .../leetcode/200-numberOfIslands/official.md | 3 + .../206-reverseLinkedList/official.md | 4 + .../208-implementTriePrefixTree/official.md | 4 + _site/leetcode/212-wordSearchII/official.md | 4 + .../leetcode/213-HouseRobberII/SpecialYang.md | 59 + _site/leetcode/213-HouseRobberII/official.md | 3 + .../BambooYH.md | 147 ++ .../bigablecat.md | 142 ++ _site/leetcode/221-MaximalSquare/official.md | 3 + .../225-implementStackUsingQueues/hatrick.md | 66 + .../225-implementStackUsingQueues/official.md | 4 + _site/leetcode/231-PowerOfTwo/hatrick.md | 44 + _site/leetcode/231-PowerOfTwo/official.md | 4 + .../232-implementQueueUsingStacks/hatrick.md | 80 + .../232-implementQueueUsingStacks/official.md | 4 + .../BambooYH.md | 91 + .../239-slidingWindowMaximum/official.md | 4 + _site/leetcode/242-ValidAnagram/bigablecat.md | 92 + _site/leetcode/260-SingleNumberIII/README.md | 17 + _site/leetcode/264-UglyNumberII/bigablecat.md | 86 + _site/leetcode/264-UglyNumberII/official.md | 3 + _site/leetcode/279-PerfectSquares/official.md | 3 + .../279-PerfectSquares/zengdiqing1994.md | 59 + .../295-FindMedianFromDataStream/BambooYH.md | 71 + .../melody-l.md | 87 + .../official.md | 3 + .../303-rangeSumQueryImmutable/BambooYH.md | 35 + .../303-rangeSumQueryImmutable/official.md | 3 + .../304-RangeSumQuery2DImmutable/official.md | 3 + .../304-RangeSumQuery2DImmutable/woody.md | 92 + .../bigablecat.md | 85 + _site/leetcode/312-BurstBalloons/melody-l.md | 57 + _site/leetcode/312-BurstBalloons/official.md | 3 + .../321-CreateMaximumNumber/README.md | 48 + _site/leetcode/322-CoinChange/official.md | 3 + _site/leetcode/338-CountingBits/bigablecat.md | 104 + _site/leetcode/343-IntegerBreak/hatrick.md | 38 + _site/leetcode/343-IntegerBreak/official.md | 3 + .../354-RussianDollEnvelopes/official.md | 3 + .../official.md | 3 + .../official.md | 4 + .../367-ValidPerfectSquare/official.md | 4 + .../368-LargestDivisibleSubset/passself.md | 99 + .../374-GuessNumberHigherOrLower/official.md | 3 + .../official.md | 3 + .../376-WiggleSubsequence/melody-l.md | 61 + .../376-WiggleSubsequence/official.md | 3 + .../leetcode/377-CombinationSumIV/official.md | 3 + .../README.md | 22 + _site/leetcode/392-IsSubsequence/official.md | 3 + .../392-IsSubsequence/zengdiqing1994.md | 90 + _site/leetcode/403-FrogJump/README.md | 47 + _site/leetcode/403-FrogJump/official.md | 47 + .../leetcode/409-LongestPalindrome/README.md | 23 + .../410-SplitArrayLargestSum/hatrick.md | 55 + .../410-SplitArrayLargestSum/official.md | 3 + .../leetcode/413-arithmeticSlices/official.md | 3 + .../416-PartitionEqualSubsetSum/bigablecat.md | 104 + .../416-PartitionEqualSubsetSum/official.md | 3 + .../official.md | 3 + .../leetcode/455-AssignCookies/SpecialYang.md | 34 + .../leetcode/455-AssignCookies/bigablecat.md | 56 + .../README.md | 20 + _site/leetcode/464-CanIWin/official.md | 3 + .../passself.md | 85 + .../472-ConcatenatedWords/official.md | 3 + _site/leetcode/474-OnesAndZeroes/hatrick.md | 47 + _site/leetcode/474-OnesAndZeroes/official.md | 3 + .../leetcode/486-PredictTheWinner/official.md | 3 + _site/leetcode/494-TargetSum/official.md | 3 + _site/leetcode/504-Base7/README.md | 21 + _site/leetcode/514-FreedomTrail/hatrick.md | 49 + _site/leetcode/514-FreedomTrail/official.md | 3 + .../passself.md | 42 + .../517-SuperWashingMachines/official.md | 3 + .../523-ContinuousSubarraySum/hatrick.md | 90 + .../523-ContinuousSubarraySum/official.md | 3 + _site/leetcode/546-RemoveBoxes/passself.md | 120 + .../leetcode/547-friendCircles/bigablecat.md | 126 + .../551-StudentAttendanceRecordI/official.md | 3 + .../552-StudentAttendanceRecordII/official.md | 3 + .../576-OutOfBoundaryPaths/official.md | 3 + .../576-OutOfBoundaryPaths/zengdiqing1994.md | 66 + .../629-KInversePairsArray/official.md | 3 + .../629-KInversePairsArray/zengdiqing1994.md | 117 + .../leetcode/638-ShoppingOffers/bigablecat.md | 134 + .../SpecialYang.md | 75 + .../646-MaximumLengthOfPairChain/official.md | 3 + .../647-PalindromicSubstrings/bigablecat.md | 198 ++ .../647-PalindromicSubstrings/official.md | 3 + _site/leetcode/650-2KeysKeyboard/mahone.md | 34 + _site/leetcode/650-2KeysKeyboard/official.md | 3 + _site/leetcode/664-StrangePrinter/official.md | 3 + .../bigablecat.md | 95 + .../official.md | 3 + .../passself.md | 70 + .../bigablecat.md | 130 + .../official.md | 3 + .../691-StickersToSpellWord/official.md | 3 + .../692-TopKFrequentWords/bigablecat.md | 66 + .../hatrick.md | 54 + .../official.md | 3 + .../BambooYH.md | 47 + .../BambooYH.md | 43 + .../official.md | 3 + .../hatrick.md | 57 + .../official.md | 3 + .../mahone.md | 35 + .../official.md | 3 + .../official.md | 3 + _site/leetcode/740-DeleteAndEarn/melody-l.md | 68 + _site/leetcode/740-DeleteAndEarn/official.md | 3 + .../746-minCostClimbingStairs/bigablecat.md | 61 + .../746-minCostClimbingStairs/official.md | 3 + .../764-LargestPlusSign/SpecialYang.md | 145 ++ .../leetcode/764-LargestPlusSign/official.md | 3 + .../official.md | 3 + .../zengdiqing1994.md | 84 + .../790-DominoAndTrominoTiling/mahone.md | 44 + .../790-DominoAndTrominoTiling/official.md | 3 + .../official.md | 3 + _site/leetcode/808-SoupServings/official.md | 3 + .../813-LargestSumOfAverages/melody-l.md | 59 + .../813-LargestSumOfAverages/official.md | 3 + _site/leetcode/837-New21Game/official.md | 3 + _site/leetcode/838-PushDominoes/official.md | 3 + .../844-BackspaceStringCompare/BambooYH.md | 89 + .../844-BackspaceStringCompare/bigablecat.md | 64 + .../bigablecat.md | 88 + .../official.md | 3 + _site/leetcode/860-lemonadeChange/BambooYH.md | 46 + .../860-lemonadeChange/SpecialYang.md | 79 + _site/leetcode/860-lemonadeChange/official.md | 4 + .../official.md | 3 + .../874-walkingRobotSimulation/SpecialYang.md | 111 + .../874-walkingRobotSimulation/hatrick.md | 57 + .../874-walkingRobotSimulation/official.md | 4 + .../leetcode/875-KokoEatingBananas/sandao.md | 45 + _site/leetcode/877-stoneGame/melody-l.md | 72 + _site/leetcode/877-stoneGame/official.md | 3 + .../898-BitwiseORsOfSubarrays/official.md | 3 + .../official.md | 3 + .../zengdiqing1994.md | 57 + .../920-NumberOfMusicPlaylists/passself.md | 48 + .../931-MinimumFallingPathSum/hatrick.md | 53 + .../931-MinimumFallingPathSum/official.md | 3 + _site/leetcode/935-KnightDialer/official.md | 3 + .../940-DistinctSubsequencesII/official.md | 4 + .../official.md | 3 + .../954-ArrayOfDoubledPairs/bigablecat.md | 258 ++ .../leetcode/956-TallestBillboard/official.md | 3 + .../official.md | 3 + .../bigablecat.md | 89 + .../official.md | 3 + .../968-BinaryTreeCameras/official.md | 3 + .../968-BinaryTreeCameras/zengdiqing1994.md | 55 + _site/leetcode/975-OddEvenJump/official.md | 3 + .../official.md | 3 + _site/leetcode/sample/concise.md | 40 + _site/leetcode/sample/concise.png | Bin 0 -> 85605 bytes _site/leetcode/sample/full.md | 72 + _site/leetcode/sample/full.png | Bin 0 -> 166160 bytes .../\345\211\221\346\214\207Offer/README.md" | 8 + leetcode/075-SortColors/README.md | 24 + leetcode/167-TwoSumII/README.md | 21 + .../215-KthLargestElementInAnArray/README.md | 19 + .../bigablecat.md | 2 +- leetcode/347-TopKFrequentElements/README.md | 77 + .../347-TopKFrequentElements/bigablecat.md | 19 + leetcode/455-AssignCookies/README.md | 36 + 256 files changed, 11962 insertions(+), 1 deletion(-) create mode 100644 _site/README.md create mode 100644 _site/contribute.md create mode 100644 _site/leetcode/001-twoSum/hatrick.md create mode 100644 _site/leetcode/001-twoSum/official.md create mode 100644 _site/leetcode/001-twoSum/woody.md create mode 100644 _site/leetcode/002-addTwoNumber/monkey.md create mode 100644 _site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md create mode 100644 _site/leetcode/005-LongestPalindromicSubstring/hatrick.md create mode 100644 _site/leetcode/005-LongestPalindromicSubstring/official.md create mode 100644 _site/leetcode/015-threeSum/hatrick.md create mode 100644 _site/leetcode/015-threeSum/official.md create mode 100644 _site/leetcode/020-validParentheses/official.md create mode 100644 _site/leetcode/024-swapNodesInPairs/official.md create mode 100644 _site/leetcode/025-reverseNodesInKGroup/bigablecat.md create mode 100644 _site/leetcode/025-reverseNodesInKGroup/official.md create mode 100644 _site/leetcode/032-LongestValidParentheses/official.md create mode 100644 _site/leetcode/036-ValidSudoku/SpecialYang.md create mode 100644 _site/leetcode/036-ValidSudoku/official.md create mode 100644 _site/leetcode/037-SudokuSolver/SpecialYang.md create mode 100644 _site/leetcode/037-SudokuSolver/official.md create mode 100644 _site/leetcode/050-powxN/bigablecat.md create mode 100644 _site/leetcode/051-NQueens/melody-l.md create mode 100644 _site/leetcode/051-NQueens/official.md create mode 100644 _site/leetcode/052-N-QueensII/hatrick.md create mode 100644 _site/leetcode/052-N-QueensII/official.md create mode 100644 _site/leetcode/053-maximumSubarray/BambooYH.md create mode 100644 _site/leetcode/053-maximumSubarray/official.md create mode 100644 _site/leetcode/062-UniquePaths/BambooYH.md create mode 100644 _site/leetcode/062-UniquePaths/official.md create mode 100644 _site/leetcode/063-UniquePathsII/SpecialYang.md create mode 100644 _site/leetcode/063-UniquePathsII/official.md create mode 100644 _site/leetcode/064-minimumPathSum/melody-l.md create mode 100644 _site/leetcode/064-minimumPathSum/official.md create mode 100644 _site/leetcode/069-SqrtX/official.md create mode 100644 _site/leetcode/070-ClimbingStairs/melody-l.md create mode 100644 _site/leetcode/070-ClimbingStairs/official.md create mode 100644 _site/leetcode/072-EditDistance/official.md create mode 100644 _site/leetcode/075-SortColors/bigablecat.md rename {leetcode => _site/leetcode}/075-SortColors/official.md (100%) create mode 100644 _site/leetcode/085-MaximalRectangle/passself.md create mode 100644 _site/leetcode/087-ScrambleString/official.md create mode 100644 _site/leetcode/091-DecodeWays/melody-l.md create mode 100644 _site/leetcode/091-DecodeWays/official.md create mode 100644 _site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md create mode 100644 _site/leetcode/095-UniqueBinarySearchTreesII/official.md create mode 100644 _site/leetcode/096-uniqueBinarySearchTrees/official.md create mode 100644 _site/leetcode/097-InterleavingString/official.md create mode 100644 _site/leetcode/098-validateBinarySearchTree/BambooYH.md create mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md create mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md create mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md create mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md create mode 100644 _site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md create mode 100644 _site/leetcode/104-MaximumDepthOfBinaryTree/official.md create mode 100644 _site/leetcode/115-DistinctSubsequences/official.md create mode 100644 _site/leetcode/120-Triangle/melody-l.md create mode 100644 _site/leetcode/120-Triangle/official.md create mode 100644 _site/leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md create mode 100644 _site/leetcode/121-bestTimeToBuyAndSellStock/official.md create mode 100644 _site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md create mode 100644 _site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md create mode 100644 _site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md create mode 100644 _site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md create mode 100644 _site/leetcode/131-PalindromePartitioning/official.md create mode 100644 _site/leetcode/132-PalindromePartitioningII/official.md create mode 100644 _site/leetcode/139-WordBreak/official.md create mode 100644 _site/leetcode/140-WordBreakII/official.md create mode 100644 _site/leetcode/141-linkedListCycle/official.md create mode 100644 _site/leetcode/142-linkedListCycleII/bigablecat.md create mode 100644 _site/leetcode/142-linkedListCycleII/official.md create mode 100644 _site/leetcode/146-lruCache/hatrick.md create mode 100644 _site/leetcode/146-lruCache/official.md create mode 100644 _site/leetcode/152-MaximumProductSubarray/SpecialYang.md create mode 100644 _site/leetcode/152-MaximumProductSubarray/official.md create mode 100644 _site/leetcode/167-TwoSumII/bigablecat.md rename {leetcode => _site/leetcode}/167-TwoSumII/official.md (100%) create mode 100644 _site/leetcode/169-majorityElement/README.md create mode 100644 _site/leetcode/169-majorityElement/SpecialYang.md create mode 100644 _site/leetcode/169-majorityElement/bigablecat.md create mode 100644 _site/leetcode/174-DungeonGame/passself.md create mode 100644 _site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md create mode 100644 _site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md create mode 100644 _site/leetcode/191-NumberOf1Bits/bigablecat.md create mode 100644 _site/leetcode/198-houseRobber/hatrick.md create mode 100644 _site/leetcode/198-houseRobber/official.md create mode 100644 _site/leetcode/200-numberOfIslands/BambooYH.md create mode 100644 _site/leetcode/200-numberOfIslands/official.md create mode 100644 _site/leetcode/206-reverseLinkedList/official.md create mode 100644 _site/leetcode/208-implementTriePrefixTree/official.md create mode 100644 _site/leetcode/212-wordSearchII/official.md create mode 100644 _site/leetcode/213-HouseRobberII/SpecialYang.md create mode 100644 _site/leetcode/213-HouseRobberII/official.md create mode 100644 _site/leetcode/215-KthLargestElementInAnArray/BambooYH.md create mode 100644 _site/leetcode/215-KthLargestElementInAnArray/bigablecat.md create mode 100644 _site/leetcode/221-MaximalSquare/official.md create mode 100644 _site/leetcode/225-implementStackUsingQueues/hatrick.md create mode 100644 _site/leetcode/225-implementStackUsingQueues/official.md create mode 100644 _site/leetcode/231-PowerOfTwo/hatrick.md create mode 100644 _site/leetcode/231-PowerOfTwo/official.md create mode 100644 _site/leetcode/232-implementQueueUsingStacks/hatrick.md create mode 100644 _site/leetcode/232-implementQueueUsingStacks/official.md create mode 100644 _site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md create mode 100644 _site/leetcode/239-slidingWindowMaximum/official.md create mode 100644 _site/leetcode/242-ValidAnagram/bigablecat.md create mode 100644 _site/leetcode/260-SingleNumberIII/README.md create mode 100644 _site/leetcode/264-UglyNumberII/bigablecat.md create mode 100644 _site/leetcode/264-UglyNumberII/official.md create mode 100644 _site/leetcode/279-PerfectSquares/official.md create mode 100644 _site/leetcode/279-PerfectSquares/zengdiqing1994.md create mode 100644 _site/leetcode/295-FindMedianFromDataStream/BambooYH.md create mode 100644 _site/leetcode/300-LongestIncreasingSubsequence/melody-l.md create mode 100644 _site/leetcode/300-LongestIncreasingSubsequence/official.md create mode 100644 _site/leetcode/303-rangeSumQueryImmutable/BambooYH.md create mode 100644 _site/leetcode/303-rangeSumQueryImmutable/official.md create mode 100644 _site/leetcode/304-RangeSumQuery2DImmutable/official.md create mode 100644 _site/leetcode/304-RangeSumQuery2DImmutable/woody.md create mode 100644 _site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md create mode 100644 _site/leetcode/312-BurstBalloons/melody-l.md create mode 100644 _site/leetcode/312-BurstBalloons/official.md create mode 100644 _site/leetcode/321-CreateMaximumNumber/README.md create mode 100644 _site/leetcode/322-CoinChange/official.md create mode 100644 _site/leetcode/338-CountingBits/bigablecat.md create mode 100644 _site/leetcode/343-IntegerBreak/hatrick.md create mode 100644 _site/leetcode/343-IntegerBreak/official.md create mode 100644 _site/leetcode/354-RussianDollEnvelopes/official.md create mode 100644 _site/leetcode/357-CountNumbersWithUniqueDigits/official.md create mode 100644 _site/leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md create mode 100644 _site/leetcode/367-ValidPerfectSquare/official.md create mode 100644 _site/leetcode/368-LargestDivisibleSubset/passself.md create mode 100644 _site/leetcode/374-GuessNumberHigherOrLower/official.md create mode 100644 _site/leetcode/375-GuessNumberHigherOrLowerII/official.md create mode 100644 _site/leetcode/376-WiggleSubsequence/melody-l.md create mode 100644 _site/leetcode/376-WiggleSubsequence/official.md create mode 100644 _site/leetcode/377-CombinationSumIV/official.md create mode 100644 _site/leetcode/378-KthSmallestElementInASortedMatrix/README.md create mode 100644 _site/leetcode/392-IsSubsequence/official.md create mode 100644 _site/leetcode/392-IsSubsequence/zengdiqing1994.md create mode 100644 _site/leetcode/403-FrogJump/README.md create mode 100644 _site/leetcode/403-FrogJump/official.md create mode 100644 _site/leetcode/409-LongestPalindrome/README.md create mode 100644 _site/leetcode/410-SplitArrayLargestSum/hatrick.md create mode 100644 _site/leetcode/410-SplitArrayLargestSum/official.md create mode 100644 _site/leetcode/413-arithmeticSlices/official.md create mode 100644 _site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md create mode 100644 _site/leetcode/416-PartitionEqualSubsetSum/official.md create mode 100644 _site/leetcode/446-ArithmeticSlicesIISubsequence/official.md create mode 100644 _site/leetcode/455-AssignCookies/SpecialYang.md create mode 100644 _site/leetcode/455-AssignCookies/bigablecat.md create mode 100644 _site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md create mode 100644 _site/leetcode/464-CanIWin/official.md create mode 100644 _site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md create mode 100644 _site/leetcode/472-ConcatenatedWords/official.md create mode 100644 _site/leetcode/474-OnesAndZeroes/hatrick.md create mode 100644 _site/leetcode/474-OnesAndZeroes/official.md create mode 100644 _site/leetcode/486-PredictTheWinner/official.md create mode 100644 _site/leetcode/494-TargetSum/official.md create mode 100644 _site/leetcode/504-Base7/README.md create mode 100644 _site/leetcode/514-FreedomTrail/hatrick.md create mode 100644 _site/leetcode/514-FreedomTrail/official.md create mode 100644 _site/leetcode/516-LongestPalindromicSubsequence/passself.md create mode 100644 _site/leetcode/517-SuperWashingMachines/official.md create mode 100644 _site/leetcode/523-ContinuousSubarraySum/hatrick.md create mode 100644 _site/leetcode/523-ContinuousSubarraySum/official.md create mode 100644 _site/leetcode/546-RemoveBoxes/passself.md create mode 100644 _site/leetcode/547-friendCircles/bigablecat.md create mode 100644 _site/leetcode/551-StudentAttendanceRecordI/official.md create mode 100644 _site/leetcode/552-StudentAttendanceRecordII/official.md create mode 100644 _site/leetcode/576-OutOfBoundaryPaths/official.md create mode 100644 _site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md create mode 100644 _site/leetcode/629-KInversePairsArray/official.md create mode 100644 _site/leetcode/629-KInversePairsArray/zengdiqing1994.md create mode 100644 _site/leetcode/638-ShoppingOffers/bigablecat.md create mode 100644 _site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md create mode 100644 _site/leetcode/646-MaximumLengthOfPairChain/official.md create mode 100644 _site/leetcode/647-PalindromicSubstrings/bigablecat.md create mode 100644 _site/leetcode/647-PalindromicSubstrings/official.md create mode 100644 _site/leetcode/650-2KeysKeyboard/mahone.md create mode 100644 _site/leetcode/650-2KeysKeyboard/official.md create mode 100644 _site/leetcode/664-StrangePrinter/official.md create mode 100644 _site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md create mode 100644 _site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md create mode 100644 _site/leetcode/688-KnightProbabilityInChessboard/passself.md create mode 100644 _site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md create mode 100644 _site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md create mode 100644 _site/leetcode/691-StickersToSpellWord/official.md create mode 100644 _site/leetcode/692-TopKFrequentWords/bigablecat.md create mode 100644 _site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md create mode 100644 _site/leetcode/698-PartitionToKEqualSumSubsets/official.md create mode 100644 _site/leetcode/703-KthLargestElementInAStream/BambooYH.md create mode 100644 _site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md create mode 100644 _site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md create mode 100644 _site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md create mode 100644 _site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md create mode 100644 _site/leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md create mode 100644 _site/leetcode/718-MaximumLengthOfRepeatedSubarray/official.md create mode 100644 _site/leetcode/730-CountDifferentPalindromicSubsequences/official.md create mode 100644 _site/leetcode/740-DeleteAndEarn/melody-l.md create mode 100644 _site/leetcode/740-DeleteAndEarn/official.md create mode 100644 _site/leetcode/746-minCostClimbingStairs/bigablecat.md create mode 100644 _site/leetcode/746-minCostClimbingStairs/official.md create mode 100644 _site/leetcode/764-LargestPlusSign/SpecialYang.md create mode 100644 _site/leetcode/764-LargestPlusSign/official.md create mode 100644 _site/leetcode/787-CheapestFlightsWithinKStops/official.md create mode 100644 _site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md create mode 100644 _site/leetcode/790-DominoAndTrominoTiling/mahone.md create mode 100644 _site/leetcode/790-DominoAndTrominoTiling/official.md create mode 100644 _site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md create mode 100644 _site/leetcode/808-SoupServings/official.md create mode 100644 _site/leetcode/813-LargestSumOfAverages/melody-l.md create mode 100644 _site/leetcode/813-LargestSumOfAverages/official.md create mode 100644 _site/leetcode/837-New21Game/official.md create mode 100644 _site/leetcode/838-PushDominoes/official.md create mode 100644 _site/leetcode/844-BackspaceStringCompare/BambooYH.md create mode 100644 _site/leetcode/844-BackspaceStringCompare/bigablecat.md create mode 100644 _site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md create mode 100644 _site/leetcode/847-ShortestPathVisitingAllNodes/official.md create mode 100644 _site/leetcode/860-lemonadeChange/BambooYH.md create mode 100644 _site/leetcode/860-lemonadeChange/SpecialYang.md create mode 100644 _site/leetcode/860-lemonadeChange/official.md create mode 100644 _site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md create mode 100644 _site/leetcode/874-walkingRobotSimulation/SpecialYang.md create mode 100644 _site/leetcode/874-walkingRobotSimulation/hatrick.md create mode 100644 _site/leetcode/874-walkingRobotSimulation/official.md create mode 100644 _site/leetcode/875-KokoEatingBananas/sandao.md create mode 100644 _site/leetcode/877-stoneGame/melody-l.md create mode 100644 _site/leetcode/877-stoneGame/official.md create mode 100644 _site/leetcode/898-BitwiseORsOfSubarrays/official.md create mode 100644 _site/leetcode/903-ValidPermutationsForDISequence/official.md create mode 100644 _site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md create mode 100644 _site/leetcode/920-NumberOfMusicPlaylists/passself.md create mode 100644 _site/leetcode/931-MinimumFallingPathSum/hatrick.md create mode 100644 _site/leetcode/931-MinimumFallingPathSum/official.md create mode 100644 _site/leetcode/935-KnightDialer/official.md create mode 100644 _site/leetcode/940-DistinctSubsequencesII/official.md create mode 100644 _site/leetcode/943-FindTheShortestSuperstring/official.md create mode 100644 _site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md create mode 100644 _site/leetcode/956-TallestBillboard/official.md create mode 100644 _site/leetcode/964-LeastOperatorsToExpressNumber/official.md create mode 100644 _site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md create mode 100644 _site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md create mode 100644 _site/leetcode/968-BinaryTreeCameras/official.md create mode 100644 _site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md create mode 100644 _site/leetcode/975-OddEvenJump/official.md create mode 100644 _site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md create mode 100644 _site/leetcode/sample/concise.md create mode 100644 _site/leetcode/sample/concise.png create mode 100644 _site/leetcode/sample/full.md create mode 100644 _site/leetcode/sample/full.png create mode 100644 "_site/\345\211\221\346\214\207Offer/README.md" create mode 100644 leetcode/075-SortColors/README.md create mode 100644 leetcode/167-TwoSumII/README.md create mode 100644 leetcode/215-KthLargestElementInAnArray/README.md create mode 100644 leetcode/347-TopKFrequentElements/README.md create mode 100644 leetcode/347-TopKFrequentElements/bigablecat.md create mode 100644 leetcode/455-AssignCookies/README.md diff --git a/_site/README.md b/_site/README.md new file mode 100644 index 0000000..c47855b --- /dev/null +++ b/_site/README.md @@ -0,0 +1,2156 @@ + +### 算法每日一练 + +* 这个专栏是Hollis知识星球的朋友们练习算法的地方,同时也欢迎广大网友参与 +* 所有题目来源是[leetCode](https://leetcode-cn.com/problemset/all/)官方公开题库 + +### 初学者友好的算法题目解答 + +* 算法解答部分的代码注释细致到每一行 +* 希望能为初学者提供最大的便利去理解每道题目和解法 +* 欢迎网友为本项目做贡献,提交你的解题方法和详细解释 + +--- + +### 专题列表 +* 2018年11月27日~2019年01月16日 +>[《算法面试通关40讲》专题](https://time.geekbang.org/course/intro/130) +>[《算法面试通关40讲》官方课件](https://github.com/geektime-geekbang/algorithm-1) + +* 2018年11月16日 +>LeetCode动态规划专题 + +--- + +专题(Begin):《算法面试40讲》 +--- + +2018年11月27日 + +[206. 反转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/206-reverseLinkedList) + +[https://leetcode-cn.com/problems/reverse-linked-list/](https://leetcode-cn.com/problems/reverse-linked-list/) + +英文官方题解: + +[https://leetcode.com/articles/reverse-linked-list/](https://leetcode.com/articles/reverse-linked-list/) + +知识点:数组、链表 + +难度:简单 + +--- + +2018年11月28日 + +[24. 两两交换链表中的节点](https://github.com/hollischuang/algorithm/tree/master/leetcode/024-swapNodesInPairs) + +[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) + +无官方题解,网友最高票Java答案: + +[https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.](https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.) + +知识点:数组、链表 + +难度:中等 + +--- + +2018年11月29日 + +[141. 环形链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/141-linkedListCycle) + +[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) + +官方题解: + +[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) + +知识点:数组、链表 + +难度:简单 + +--- + +2018年11月30日 + +[142. 环形链表 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/142-linkedListCycleII) + +[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) + +知识点:数组、链表 + +难度:中等 + +--- + +2018年12月01日 + +[25. k个一组翻转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/025-reverseNodesInKGroup) + +[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments](https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments) + +知识点:数组、链表 + +难度:困难 + +--- + +2018年12月02日 + +[20. 有效的括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/020-validParentheses) + +[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) + +官方题解: + +[https://leetcode-cn.com/articles/valid-parentheses/](https://leetcode-cn.com/articles/valid-parentheses/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月03日 + +[232. 用栈实现队列](https://github.com/hollischuang/algorithm/tree/master/leetcode/232-implementQueueUsingStacks) + +[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) + +英文官方题解: + +[https://leetcode.com/articles/implement-queue-using-stacks/](https://leetcode.com/articles/implement-queue-using-stacks/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月04日 + +[225. 用队列实现栈](https://github.com/hollischuang/algorithm/tree/master/leetcode/225-implementStackUsingQueues) + +[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) + +英文官方题解: + +[https://leetcode.com/articles/implement-stack-using-queues/](https://leetcode.com/articles/implement-stack-using-queues/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月05日 + +[844. 比较含退格的字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/844-BackspaceStringCompare) + +[https://leetcode-cn.com/problems/backspace-string-compare/](https://leetcode-cn.com/problems/backspace-string-compare/) + +英文官方题解: + +[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月06日 + +[703. 数据流中的第K大元素](https://github.com/hollischuang/algorithm/tree/master/leetcode/703-KthLargestElementInAStream) + +[https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) + +知识点:优先队列 + +难度:简单 + +--- + +2018年12月07日 + +[692. 前K个高频单词](https://github.com/hollischuang/algorithm/tree/master/leetcode/692-TopKFrequentWords) + +[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) + +英文官方题解: + +[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) + +知识点:优先队列 + +难度:中等 + +--- + +2018年12月08日 + +[239. 滑动窗口最大值](https://github.com/hollischuang/algorithm/tree/master/leetcode/239-slidingWindowMaximum) + +[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/sliding-window-maximum/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation](https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation) + +知识点:优先队列 + +难度:困难 + +--- + +2018年12月09日 + +[242. 有效的字母异位词](https://github.com/hollischuang/algorithm/tree/master/leetcode/242-ValidAnagram) + +[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) + +英文官方题解: + +[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) + +知识点:哈希表和集合 + +难度:简单 + +--- + +2018年12月10日 + +[1. 两数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/001-twoSum) + +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +官方题解: + +[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) + +知识点:哈希表和集合 + +难度:简单 + +--- + +2018年12月11日 + +[15. 三数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/015-threeSum) + +[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution](https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution) + +知识点:哈希表和集合 + +难度:中等 + +--- + +2018年12月12日 + +[98. 验证二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/098-validateBinarySearchTree) + +[https://leetcode-cn.com/problems/validate-binary-search-tree/](https://leetcode-cn.com/problems/validate-binary-search-tree/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)](https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines](https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines) + +知识点:树、二叉树、二叉搜索树 + +难度:中等 + +--- + +2018年12月13日 + +[236. 二叉树的最近公共祖先](https://github.com/hollischuang/algorithm/tree/master/leetcode/236-lowestCommonAncestorOfABinaryTree) + +[https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) + +英文官方题解: + +[https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/) + +知识点:树、二叉树、二叉搜索树 + +难度:中等 + +--- + +2018年12月14日 + +[50. Pow(x, n)](https://github.com/hollischuang/algorithm/tree/master/leetcode/050-powxN) + +[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers](https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers) + +知识点:递归、分治 + +难度:中等 + +--- + +2018年12月15日 + +[169. 求众数](https://github.com/hollischuang/algorithm/tree/master/leetcode/169-majorityElement) + +[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) + +英文官方题解: + +[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) + +知识点:递归、分治 + +难度:简单 + +--- + +2018年12月16日 + +[53. 最大子序和](https://github.com/hollischuang/algorithm/tree/master/leetcode/053-maximumSubarray) + +[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts](https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java](https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java) + +知识点:递归、分治、动态规划 + +难度:简单 + +--- + +2018年12月17日 + +[860. 柠檬水找零](https://github.com/hollischuang/algorithm/tree/master/leetcode/860-lemonadeChange) + +[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) + +官方题解: + +[https://leetcode-cn.com/articles/lemonade-change/](https://leetcode-cn.com/articles/lemonade-change/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月18日 + +[122. 买卖股票的最佳时机 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/122-bestTimeToBuyAndSellStockII) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) + +官方题解: + +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月19日 + +[455. 分发饼干](https://github.com/hollischuang/algorithm/tree/master/leetcode/455-AssignCookies) + +[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)](https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月20日 + +[874. 模拟行走机器人](https://github.com/hollischuang/algorithm/tree/master/leetcode/874-walkingRobotSimulation) + +[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) + +英文官方题解: + +[https://leetcode.com/problems/walking-robot-simulation/solution/](https://leetcode.com/problems/walking-robot-simulation/solution/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月21日 + +[102. 二叉树的层次遍历](https://github.com/hollischuang/algorithm/tree/master/leetcode/102-BinaryTreeLevelOrderTraversal) + +[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS) + +知识点:广度优先搜索 + +难度:中等 + +--- + +2018年12月22日 + +[104. 二叉树的最大深度](https://github.com/hollischuang/algorithm/tree/master/leetcode/104-MaximumDepthOfBinaryTree) + +[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) + +官方题解: + +[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) + +知识点:深度优先搜索 + +难度:简单 + +--- + +2018年12月23日 + +[51. N-皇后](https://github.com/hollischuang/algorithm/tree/master/leetcode/051-NQueens) + +[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.](https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.) + +知识点:剪枝 + +难度:困难 + +--- + +2018年12月24日 + +[36. 有效的数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/036-ValidSudoku) + +[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings](https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code](https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code) + +知识点:剪枝 + +难度:中等 + +--- + +2018年12月25日 + +[37. 解数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/037-SudokuSolver) + +[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking](https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking) + +知识点:剪枝 + +难度:困难 + +--- + +2018年12月26日 + +[69. x 的平方根](https://github.com/hollischuang/algorithm/tree/master/leetcode/069-SqrtX) + +[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) + +知识点:二分查找 + +难度:简单 + +--- + +2018年12月27日 + +[367. 有效的完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) + +[https://leetcode-cn.com/problems/valid-perfect-square/](https://leetcode-cn.com/problems/valid-perfect-square/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code](https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code) + +知识点:二分查找 + +难度:简单 + +--- + +2018年12月28日 + +[208. 实现 Trie (前缀树)](https://github.com/hollischuang/algorithm/tree/master/leetcode/208-implementTriePrefixTree) + +[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) + +英文官方题解: + +[https://leetcode.com/articles/implement-trie-prefix-tree/](https://leetcode.com/articles/implement-trie-prefix-tree/) + +知识点:字典树 + +难度:中等 + +--- + +2018年12月29日 + +[212. 单词搜索 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/212-wordSearchII) + +[https://leetcode-cn.com/problems/word-search-ii/](https://leetcode-cn.com/problems/word-search-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)](https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)) + +知识点:字典树 + +难度:困难 + +--- + +2018年12月30日 + +[191. 位1的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/191-NumberOf1Bits) + +[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) + +英文官方题解: + +[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) + +知识点:位运算 + +难度:简单 + +--- + +2018年12月31日 + +[338. 比特位计数](https://github.com/hollischuang/algorithm/tree/master/leetcode/338-CountingBits) + +[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) + +知识点:位运算 + +难度:中等 + +--- + +2019年01月01日 + +[231. 2的幂](https://github.com/hollischuang/algorithm/tree/master/leetcode/231-PowerOfTwo) + +[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount](https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount) + +知识点:位运算 + +难度:简单 + +--- + +2019年01月02日 + +[52. N皇后 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/052-N-QueensII) + +[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution](https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)) + +知识点:位运算 + +难度:困难 + +--- + +2019年01月03日 + +[70. 爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/070-ClimbingStairs) + +[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) + +英文官方题解: + +[https://leetcode.com/articles/climbing-stairs/](https://leetcode.com/articles/climbing-stairs/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月04日 + +[120. 三角形最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/120-Triangle) + +[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle](https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution](https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月05日 + +[152. 乘积最大子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/152-MaximumProductSubarray) + +[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity](https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time](https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月06日 + +[123. 买卖股票的最佳时机 III](https://github.com/hollischuang/algorithm/tree/master/leetcode/123-BestTimeToBuyAndSellStockIII) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月07日 + +[121. 买卖股票的最佳时机](https://github.com/hollischuang/algorithm/tree/master/leetcode/121-bestTimeToBuyAndSellStock) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) + +官方题解: + +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月08日 + +[188. 买卖股票的最佳时机 IV](https://github.com/hollischuang/algorithm/tree/master/leetcode/188-bestTimeToBuyAndSellStockIV) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月09日 + +[309. 最佳买卖股票时机含冷冻期](https://github.com/hollischuang/algorithm/tree/master/leetcode/309-BestTimeToBuyAndSellStockWithCooldown) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月10日 + +[714. 买卖股票的最佳时机含手续费](https://github.com/hollischuang/algorithm/tree/master/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +英文官方题解: + +[https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月11日 + +[300. 最长上升子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/300-LongestIncreasingSubsequence) + +[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/longest-increasing-subsequence/](https://leetcode.com/articles/longest-increasing-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月12日 + +[322. 零钱兑换](https://github.com/hollischuang/algorithm/tree/master/leetcode/322-CoinChange) + +[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) + +英文官方题解: + +[https://leetcode.com/articles/coin-change/](https://leetcode.com/articles/coin-change/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月13日 + +[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) + +[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) + +英文官方题解: + +[https://leetcode.com/articles/edit-distance/](https://leetcode.com/articles/edit-distance/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月14日 + +[200. 岛屿的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/200-numberOfIslands) + +[https://leetcode-cn.com/problems/number-of-islands/](https://leetcode-cn.com/problems/number-of-islands/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution](https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution) + +知识点:并查集 + +难度:中等 + +--- + +2019年01月15日 + +[547. 朋友圈](https://github.com/hollischuang/algorithm/tree/master/leetcode/547-friendCircles) + +[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) + +无官方题解,网友高票Java答案1(DFS): + +[https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution](https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution) + +无官方题解,网友高票Java答案2(Union Find): + +[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) + +知识点:并查集 + +难度:中等 + +--- + +2019年01月16日 + +[146. LRU缓存机制](https://github.com/hollischuang/algorithm/tree/master/leetcode/146-lruCache) + +[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)](https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)) + +知识点:LRU + +难度:困难 + +--- + +专题(End):《算法面试40讲》 +--- + +
+ +专题(Begin):动态规划 +--- + +2019年01月17日 + +[303. 区域和检索 - 数组不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/303-rangeSumQueryImmutable) + +[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) + +英文官方题解: + +[https://leetcode.com/articles/range-sum-query-immutable/](https://leetcode.com/articles/range-sum-query-immutable/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月18日 + +[746. 使用最小花费爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/746-minCostClimbingStairs) + +[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) + +英文官方题解: + +[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月19日 + +[198. 打家劫舍](https://github.com/hollischuang/algorithm/tree/master/leetcode/198-houseRobber) + +[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月20日 + +[877. 石子游戏](https://github.com/hollischuang/algorithm/tree/master/leetcode/877-stoneGame) + +[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) + +官方题解: + +[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月21日 + +[64. 最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/064-minimumPathSum) + +[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月22日 + +[96. 不同的二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/096-uniqueBinarySearchTrees) + +[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) + +英文官方题解: + +[https://leetcode.com/articles/unique-binary-search-trees/](https://leetcode.com/articles/unique-binary-search-trees/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月23日 + +[413. 等差数列划分](https://github.com/hollischuang/algorithm/tree/master/leetcode/413-arithmeticSlices) + +[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) + +英文官方题解: + +[https://leetcode.com/articles/arithmetic-slices/](https://leetcode.com/articles/arithmetic-slices/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月24日 + +[712. 两个字符串的最小ASCII删除和](https://github.com/hollischuang/algorithm/tree/master/leetcode/712-MinimumASCIIDeleteSumforTwoStrings) + +[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月25日 + +[62. 不同路径](https://github.com/hollischuang/algorithm/tree/master/leetcode/062-UniquePaths) + +[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space](https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)](https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月26日 + +[638. 大礼包](https://github.com/hollischuang/algorithm/tree/master/leetcode/638-ShoppingOffers) + +[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) + +英文官方题解: + +[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月27日 + +[647. 回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/647-PalindromicSubstrings) + +[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) + +英文官方题解: + +[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月28日 + +[931. 下降路径最小和](https://github.com/hollischuang/algorithm/tree/master/leetcode/931-MinimumFallingPathSum) + +[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-path-falling-sum/](https://leetcode.com/articles/minimum-path-falling-sum/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月29日 + +[343. 整数拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/343-IntegerBreak) + +[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution](https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月30日 + +[95. 不同的二叉搜索树 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/095-UniqueBinarySearchTreesII) + +[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) + +英文官方题解: + +[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月31日 + +[740. 删除与获得点数](https://github.com/hollischuang/algorithm/tree/master/leetcode/740-DeleteAndEarn) + +[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) + +英文官方题解: + +[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月01日 + +[646. 最长数对链](https://github.com/hollischuang/algorithm/tree/master/leetcode/646-MaximumLengthOfPairChain) + +[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) + +英文官方题解: + +[https://leetcode.com/articles/maximum-length-of-pair-chain/](https://leetcode.com/articles/maximum-length-of-pair-chain/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月02日 + +[764. 最大加号标志](https://github.com/hollischuang/algorithm/tree/master/leetcode/764-LargestPlusSign) + +[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) + +英文官方题解: + +[https://leetcode.com/articles/largest-plus-sign/](https://leetcode.com/articles/largest-plus-sign/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月03日 + +[279. 完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/279-PerfectSquares) + +[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月04日 + +[392. 判断子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/392-IsSubsequence) + +[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments](https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月05日 + +[377. 组合总和 Ⅳ](https://github.com/hollischuang/algorithm/tree/master/leetcode/377-CombinationSumIV) + +[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation](https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月06日 + +[486. 预测赢家](https://github.com/hollischuang/algorithm/tree/master/leetcode/486-PredictTheWinner) + +[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) + +英文官方题解: + +[https://leetcode.com/articles/predict-the-winner/](https://leetcode.com/articles/predict-the-winner/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月07日 + +[357. 计算各个位数不同的数字个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/357-CountNumbersWithUniqueDigits) + +[https://leetcode-cn.com/problems/count-numbers-with-unique-digits/](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月08日 + +[494. 目标和](https://github.com/hollischuang/algorithm/tree/master/leetcode/494-TargetSum) + +[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) + +英文官方题解: + +[https://leetcode.com/articles/target-sum/](https://leetcode.com/articles/target-sum/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月09日 + +[516. 最长回文子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/516-LongestPalindromicSubsequence) + +[https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution](https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月10日 + +[688. “马”在棋盘上的概率](https://github.com/hollischuang/algorithm/tree/master/leetcode/688-KnightProbabilityInChessboard) + +[https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) + +英文官方题解: + +[https://leetcode.com/articles/knight-probability-in-chessboard/](https://leetcode.com/articles/knight-probability-in-chessboard/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月11日 + +[718. 最长重复子数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/718-MaximumLengthOfRepeatedSubarray) + +[https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/) + +英文官方题解: + +[https://leetcode.com/articles/maximum-length-of-repeated-subarray/](https://leetcode.com/articles/maximum-length-of-repeated-subarray/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月12日 + +[650. 只有两个键的键盘](https://github.com/hollischuang/algorithm/tree/master/leetcode/650-2KeysKeyboard) + +[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) + +英文官方题解: + +[https://leetcode.com/articles/2-keys-keyboard/](https://leetcode.com/articles/2-keys-keyboard/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月13日 + +[873. 最长的斐波那契子序列的长度](https://github.com/hollischuang/algorithm/tree/master/leetcode/873-LengthOfLongestFibonacciSubsequence) + +[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) + +官方题解: + +[https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月14日 + +[139. 单词拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/139-WordBreak) + +[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways](https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月15日 + +[264. 丑数 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/264-UglyNumberII) + +[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月16日 + +[416. 分割等和子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/416-PartitionEqualSubsetSum) + +[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月17日 + +[304. 二维区域和检索 - 矩阵不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/304-RangeSumQuery2DImmutable) + +[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) + +英文无官方题解: + +[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月18日 + +[221. 最大正方形](https://github.com/hollischuang/algorithm/tree/master/leetcode/221-MaximalSquare) + +[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) + +英文官方题解: + +[https://leetcode.com/articles/maximal-square/](https://leetcode.com/articles/maximal-square/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月19日 + +[698. 划分为k个相等的子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/698-PartitionToKEqualSumSubsets) + +[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) + +英文官方题解: + +[https://leetcode.com/articles/partition-to-k-equal-sum-subsets/](https://leetcode.com/articles/partition-to-k-equal-sum-subsets/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月20日 + +[474. 一和零](https://github.com/hollischuang/algorithm/tree/master/leetcode/474-OnesAndZeroes) + +[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.](https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space](https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月21日 + +[838. 推多米诺](https://github.com/hollischuang/algorithm/tree/master/leetcode/838-PushDominoes) + +[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/articles/push-dominoes/](https://leetcode.com/articles/push-dominoes/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月22日 + +[790. 多米诺和托米诺平铺](https://github.com/hollischuang/algorithm/tree/master/leetcode/790-DominoAndTrominoTiling) + +[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月23日 + +[813. 最大平均值和的分组](https://github.com/hollischuang/algorithm/tree/master/leetcode/813-LargestSumOfAverages) + +[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) + +英文官方题解: + +[https://leetcode.com/articles/largest-sum-of-averages/](https://leetcode.com/articles/largest-sum-of-averages/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月24日 + +[376. 摆动序列变](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) + +[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月25日 + +[801. 使序列递增的最小交换次数](https://github.com/hollischuang/algorithm/tree/master/leetcode/801-MinimumSwapsToMakeSequencesIncreasing) + +[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/](https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月26日 + +[808. 分汤](https://github.com/hollischuang/algorithm/tree/master/leetcode/808-SoupServings) + +[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) + +英文官方题解: + +[https://leetcode.com/articles/soup-servings/](https://leetcode.com/articles/soup-servings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月27日 + +[63. 不同路径 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/063-UniquePathsII) + +[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) + +英文官方题解: + +[https://leetcode.com/articles/unique-paths-ii/](https://leetcode.com/articles/unique-paths-ii/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月28日 + +[213. 打家劫舍 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/213-HouseRobberII) + +[https://leetcode-cn.com/problems/house-robber-ii/](https://leetcode-cn.com/problems/house-robber-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation](https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月01日 + +[368. 最大整除子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/368-LargestDivisibleSubset) + +[https://leetcode-cn.com/problems/largest-divisible-subset/](https://leetcode-cn.com/problems/largest-divisible-subset/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)](https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月02日 + +[467. 环绕字符串中唯一的子字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/467-UniqueSubstringsInWraparoundString) + +[https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月03日 + +[464. 我能赢吗](https://github.com/hollischuang/algorithm/tree/master/leetcode/464-CanIWin) + +[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation](https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation](https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月04日 + +[935. 骑士拨号器](https://github.com/hollischuang/algorithm/tree/master/leetcode/935-KnightDialer) + +[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) + +英文官方题解: + +[https://leetcode.com/articles/knight-dialer/](https://leetcode.com/articles/knight-dialer/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月05日 + +[787. K 站中转内最便宜的航班](https://github.com/hollischuang/algorithm/tree/master/leetcode/787-CheapestFlightsWithinKStops) + +[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月06日 + +[576. 出界的路径数](https://github.com/hollischuang/algorithm/tree/master/leetcode/576-OutOfBoundaryPaths) + +[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) + +英文官方题解: + +[https://leetcode.com/articles/out-of-boundary-paths/](https://leetcode.com/articles/out-of-boundary-paths/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月07日 + +[374. 猜数字大小](https://github.com/hollischuang/algorithm/tree/master/leetcode/374-GuessNumberHigherOrLower) + +[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) + +英文官方题解: + +[https://leetcode.com/articles/guess-number-higher-or-lower/](https://leetcode.com/articles/guess-number-higher-or-lower/) + +知识点:二分查找 + +难度:简单 + +--- + +2019年03月08日 + +[375. 猜数字大小 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/375-GuessNumberHigherOrLowerII) + +[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~](https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月09日 + +[967. 连续差相同的数字](https://github.com/hollischuang/algorithm/tree/master/leetcode/967-NumbersWithSameConsecutiveDifferences) + +[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) + +英文官方题解: + +[https://leetcode.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/numbers-with-same-consecutive-differences/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月10日 + +[673. 最长递增子序列的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/673-NumberOfLongestIncreasingSubsequence) + +[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月11日 + +[131. 分割回文串](https://github.com/hollischuang/algorithm/tree/master/leetcode/131-PalindromePartitioning) + +[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.](https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.) + +知识点:回溯算法 + +难度:中等 + +--- + +2019年03月12日 + +[132. 分割回文串II](https://github.com/hollischuang/algorithm/tree/master/leetcode/132-PalindromePartitioningII) + +[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.](https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月13日 + +[5. 最长回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/005-LongestPalindromicSubstring) + +[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) + +英文官方题解: + +[https://leetcode.com/articles/longest-palindromic-substring/](https://leetcode.com/articles/longest-palindromic-substring/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月14日 + +[523. 连续的子数组和](https://github.com/hollischuang/algorithm/tree/master/leetcode/523-ContinuousSubarraySum) + +[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space](https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月15日 + +[837. 新21点](https://github.com/hollischuang/algorithm/tree/master/leetcode/837-New21Game) + +[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) + +英文官方题解: + +[https://leetcode.com/articles/new-21-game/](https://leetcode.com/articles/new-21-game/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月16日 + +[898. 子数组按位或操作](https://github.com/hollischuang/algorithm/tree/master/leetcode/898-BitwiseORsOfSubarrays) + +[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) + +英文官方题解: + +[https://leetcode.com/articles/bitwise-ors-of-subarrays/](https://leetcode.com/articles/bitwise-ors-of-subarrays/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月17日 + +[91. 解码方法](https://github.com/hollischuang/algorithm/tree/master/leetcode/091-DecodeWays) + +[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) + +无官方题解,网友高票Java答案1: + +[https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference](https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference) + +无官方题解,网友高票Java答案2: + +[https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation](https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月18日 + +[312. 戳气球](https://github.com/hollischuang/algorithm/tree/master/leetcode/312-BurstBalloons) + +[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations](https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月19日 + +[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) + +[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)](https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月20日 + +[975. 奇偶跳](https://github.com/hollischuang/algorithm/tree/master/leetcode/975-OddEvenJump) + +[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) + +官方题解: + +[https://leetcode-cn.com/articles/odd-even-jump/](https://leetcode-cn.com/articles/odd-even-jump/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月21日 + +[115. 不同的子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/115-DistinctSubsequences) + +[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java](https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月22日 + +[940. 不同的子序列 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/940-DistinctSubsequencesII) + +[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) + +英文官方题解: + +[https://leetcode.com/articles/distinct-subsequences-ii/](https://leetcode.com/articles/distinct-subsequences-ii/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月23日 + +[691. 贴纸拼词](https://github.com/hollischuang/algorithm/tree/master/leetcode/691-StickersToSpellWord) + +[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) + +英文官方题解: + +[https://leetcode.com/articles/stickers-to-spell-word/](https://leetcode.com/articles/stickers-to-spell-word/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月24日 + +[982. 按位与为零的三元组](https://github.com/hollischuang/algorithm/tree/master/leetcode/982-TriplesWithBitwiseANDEqualToZero) + +[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月25日 + +[546. 移除盒子](https://github.com/hollischuang/algorithm/tree/master/leetcode/546-RemoveBoxes) + +[https://leetcode-cn.com/problems/remove-boxes/](https://leetcode-cn.com/problems/remove-boxes/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions](https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月26日 + +[85. 最大矩形](https://github.com/hollischuang/algorithm/tree/master/leetcode/085-MaximalRectangle) + +[https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution](https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月27日 + +[903. DI 序列的有效排列](https://github.com/hollischuang/algorithm/tree/master/leetcode/903-ValidPermutationsForDISequence) + +[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) + +英文官方题解: + +[https://leetcode.com/articles/valid-permutations-for-di-sequence/](https://leetcode.com/articles/valid-permutations-for-di-sequence/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月28日 + +[629. K个逆序对数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) + +英文官方题解: + +[https://leetcode.com/articles/k-inverse-pairs-array/](https://leetcode.com/articles/k-inverse-pairs-array/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月29日 + +[956. 最高的广告牌](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) + +英文官方题解: + +[https://leetcode.com/problems/tallest-billboard/solution/](https://leetcode.com/problems/tallest-billboard/solution/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月30日 + +[664. 奇怪的打印机](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) + +英文官方题解: + +[https://leetcode.com/problems/strange-printer/solution/](https://leetcode.com/problems/strange-printer/solution/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年04月01日 + +[943. 最短超级串](https://github.com/hollischuang/algorithm/tree/master/leetcode/943-FindTheShortestSuperstring) + +[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) + +英文官方题解: + +[https://leetcode.com/articles/find-the-shortest-superstring/](https://leetcode.com/articles/find-the-shortest-superstring/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年04月02日 + +[32. 最长有效括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/032-LongestValidParentheses) + +[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) + +英文官方题解: + +[https://leetcode.com/articles/longest-valid-parentheses/](https://leetcode.com/articles/longest-valid-parentheses/) + +知识点:动态规划 + +难度:困难 + +--- + + +2019年04月03日 + +[403. 青蛙过河](https://github.com/hollischuang/algorithm/tree/master/leetcode/403-FrogJump) + +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- + + +2019年04月04日 + +[321. 拼接最大数](https://github.com/hollischuang/algorithm/tree/master/leetcode/321-CreateMaximumNumber) + +[https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) + +无官方题解,网友高票Java答案: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- diff --git a/_site/contribute.md b/_site/contribute.md new file mode 100644 index 0000000..ed55f6f --- /dev/null +++ b/_site/contribute.md @@ -0,0 +1,105 @@ +提交答案步骤 +--- + +>各位网友好,在向本项目提交您的答案详解时,请阅读以下内容 + +
+ +**0. 从题目列表或者leetCode题库选择题目** + +1) 从本项目的题目列表中选择,每日更新,来自leetCode免费公开题库 + +[https://github.com/hollischuang/algorithm/blob/master/daily.md](https://github.com/hollischuang/algorithm/blob/master/daily.md) + +2) 或者直接从leetCode免费题库中自行选择 + +[https://leetcode-cn.com/problemset/all/](https://leetcode-cn.com/problemset/all/) + +
+ +**1. 为运行成功的代码写出详细注释** + +* 可以提交一个精简版的答案,仅包括代码和详细注释 + +``` +精简版答案包括: + +1) 能够在leetCode上成功提交的代码 + +2) 代码详细注释 + +3) 参考或引用的链接 + +``` + +![精简版答案示例](https://raw.githubusercontent.com/hollischuang/Interview/master/algorithm/leetcode/sample/concise.png) + +>*精简版答案示例下载地址:* + +>[https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/concise.md](https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/concise.md) + +
+ +* 或者提交一个详尽版的答案,参照leetCode官方题解样式 + +``` +详尽版答案包括: + +1) 能够在leetCode上成功提交的代码 + +2) 代码详细注释 + +3) 复杂度分析:包括时间复杂度和空间复杂度 + +4) 方法和思路概述 + +5) 参考或引用的链接 + +``` + +![详尽版答案示例](https://raw.githubusercontent.com/hollischuang/Interview/master/algorithm/leetcode/sample/full.png) + +>*详尽版示例下载地址:* + +>[https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/full.md](https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/full.md) + +* 引用和参考: + +``` + +不强制原创,如果提交的答案有借鉴、转载、翻译, + +请务必注明引用出处 +``` + +
+ +**2. 找到题目所在目录,新建md文件并提交,命名规则 "英文或拼音昵称.md"** + +1) 在/Interview/algorithm/leetcode/文件夹下找到题目文件夹,如 + +``` +/Interview/algorithm/leetcode/141-LinkedListCycle + +如果项目里还没有该题的文件夹,请按照驼峰式命名法新建"题号-题目名称.md",题号小于百位数请加0 + +比如题号是24的swap-nodes-in-pairs,命名后如下 + +/Interview/algorithm/leetcode/024-SwapNodesInPairs +``` + +2) 文件名请务必使用英文或拼音: + +``` +比如你的昵称叫offical, 文件就命名为 official.md +``` + +3) 建好后完整路径和名称如下所示: + +``` +/Interview/algorithm/leetcode/141-LinkedListCycle/offical.md +``` + +4) 在git上提交你的文件,管理员审核通过后大家就能看到你的答案并和你讨论了 + +--- diff --git a/_site/leetcode/001-twoSum/hatrick.md b/_site/leetcode/001-twoSum/hatrick.md new file mode 100644 index 0000000..8b955cc --- /dev/null +++ b/_site/leetcode/001-twoSum/hatrick.md @@ -0,0 +1,39 @@ +**1. 两数之和** +--- +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +解决方案 +**思路** +思路1: 根据题意我们其实可以直接使用双重for循环,然后拿到两个值相加就等于目标值的那两个下标返回即可, +只是这样的时间复杂度是O(N^2) +思路2: 我们可以转换思路,先将目标值与我们需要下标对应元素值保存起来,等到下一个我们需要的差值,就会拿到之前key, +既可以得到两个下标 + +``` +private static int[] twoSum(int[] nums, int target) { + //定义容器,存放首个下标,当有其差值出现的时候,便可以等到另一个下标 + Map map = new HashMap<>(); + //用来存储最后返回结果 + int[] result = new int[2]; + for (int i = 0; i < nums.length; i++) { + //判断之前的key是否已经保存到map中,如果已经存在,那么当前的值加上之前的值既为目标值 + if (map.containsKey(target - nums[i])) { + result[0] = map.get(target - nums[i]); + //这个时候i所对应的元素还没有放到map中,但是我们要找的值已经找到返回即可 + result[1] = i; + return result; + } + map.put(nums[i], i); + } + return result; + } + +``` +**复杂度分析** +时间复杂度:O(N) 循环所有数组元素,当然根据目标值,每次查找花费O(1)时间,所以最后复杂度为O(N) +空间复杂度:O(N) 使用map数据结构,存储的元素取决于传入的元素数量 + + +**参考资料** +* 本题leetCode英文官方题解: +[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) diff --git a/_site/leetcode/001-twoSum/official.md b/_site/leetcode/001-twoSum/official.md new file mode 100644 index 0000000..729d988 --- /dev/null +++ b/_site/leetcode/001-twoSum/official.md @@ -0,0 +1,4 @@ +**1. 两数之和** +--- +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + diff --git a/_site/leetcode/001-twoSum/woody.md b/_site/leetcode/001-twoSum/woody.md new file mode 100644 index 0000000..996a728 --- /dev/null +++ b/_site/leetcode/001-twoSum/woody.md @@ -0,0 +1,53 @@ +>答案示例,本人自行编写后参考LeetCode官方题库。 + +**001.两数之和** +--- +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +摘要 + +本文适用于初学者。 + + +```java + +class Solution { + //这道题虽然不难,但在解决的过程中会发现有更优质的方法去解决 + public int[] twoSum(int[] nums, int target) { + //第一眼看到这个题的时候,很像冒泡排除,选择排序 + int i=0; int j=i+1; + //其实这个效率低的方法直接冒泡就可以 + // 确定要循环几次,来走完所有的情况 + for(i=0;i 题目只是单纯的要求两个数相加求和,那我们直接用迭代的方式来控制对应位置上数字两两相加。需要注意的有两点:一是需要考虑两个个位数相加的进位,超过10之后向前进一,这里用一个变量来保存进位。二是因为两个数字的长度不一定一样,长度短的如果位数不够,则用0来补足。 + +- code(scala version) +``` + def addTwoNumbers(l1: ListNode, l2: ListNode): ListNode = { + + var ll1 = l1 + var ll2 = l2 + + //定义指向头结点的变量 + var result: ListNode = new ListNode() + //定义一个dummy指针来指向头节点,这样可以任意的移动刚开始指向头节点的变量而不用担心头结点的丢失 + var dummy: ListNode = result + + //保存两个一位数相加后结果的十位数上的值:结果大于等于10则为1,否则为0 + var carry: Int = 0 + var sum, x, y: Int = 0 + while (ll1 != null || ll2 != null) { + //如果当前链表的当前节点为空,则值为null + if (ll1 != null) x = ll1.x else x = 0 + if (ll2 != null) y = ll2.x else y = 0 + sum = x + y + carry + result.next = new ListNode(sum % 10) + carry = if (sum > 9) 1 else 0 + result = result.next + + //链表当前节点不为空,则向后推移一个节点,若为空,则不变 + if (ll1 != null) ll1 = ll1.next + if (ll2 != null) ll2 = ll2.next + } + //当两个链表中的所以节点都相加完之后,判断最后一个相加的结果是否超过10,超过10的时候需要额外增加一个节点来保存进位的结果 + if (carry == 1) result.next = new ListNode(1) + //返回dummy指针的next,即结果的头指针 + dummy.next + } +``` +- 时间空间复杂度分析 + > 时间复杂度:O(max(m,n)) m,n分别为两个链表的长度,因为需要相应位置相加,所以需要遍历两个链表 + > 空间复杂度:O(max(m,n)) m,n分别为两个链表的长度,最后结果长度一定跟最大的数长度相同或者比其大一位,我们用对应长度的链表保存。 + +- 参考资料 +[official solution: https://leetcode.com/problems/add-two-numbers/solution/](https://leetcode.com/problems/add-two-numbers/solution/) diff --git a/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md b/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md new file mode 100644 index 0000000..2a220b1 --- /dev/null +++ b/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md @@ -0,0 +1,43 @@ +**1. 003-LongestSubstringWithoutRepeatingCharacters** +--- +[https://leetcode.com/problems/longest-substring-without-repeating-characters/](https://leetcode.com/problems/longest-substring-without-repeating-characters/) + +- 解决思路 + > 题目需要求解最长无重复字符的子串长度。首先依次的遍历该字符串,用一个数据结构(set,map等)来保存已经遍历过的字符,当前字符没有出现过,则将其添加到我们定义的数据结构中,当前无重复子串长度加一。如果当前字符出现过,则需要将数据结构中与该字符相同字符之前的字符全部删除,并重新计数新的子串长度。此处需要用一个变量来保存之前无重复子串的最大长度,每次出现重复字符时都要跟之前最大的长度比较判断是否需要更新。 + +- code(scala version) +``` + def lengthOfLongestSubstringWithSet(s: String): Int ={ + //传入的string的长度 + var length = s.length + //用set保存出现过的字符 + var elemSet: Set[Char] = Set() + + var begin, end = 0 + //用来保存当前所计算的最长长度 + var maxLength = 0 + while(begin < length && end < length){ + //如果set中不包含当前字符,则将当前字符添加入set,并向后移动给一个字符 + if(!elemSet.contains(s.charAt(end))){ + elemSet += s.charAt(end) + end = end +1 + //更新maxLength,此处是重点:注意一定要用max函数比较 当前的不重复字符串长度 与 上一次出现重复字符时记录的最长不重复字符串长度 + maxLength = Math.max(maxLength , end - begin) + } else{ + //如果set中包含当前字符,则利用循环将出现重复字符之前的字符全部从set中删除,保证set所留的都是需要重新计算长度的字符 + do { + elemSet -= s.charAt(begin) + begin = begin + 1 + } while(s.charAt(begin-1)!=s.charAt(end)) + } + } + + maxLength + } +``` +- 时间空间复杂度分析 + > 时间复杂度:O(n) n为字符串长度,此处需要遍历两次字符串,所以时间复杂度为O(2n)=O(n) + > 空间复杂度:O(min(m,n)) 因为我们需要O(k)的空间来保存无重复字符的子串。k的最大长度不会超过原始字符串的长度n,也不会超过原始字符串中字符所在的字符表或者字母表集合的大小m。k取m和n的最小值。 + +- 参考资料 +[https://leetcode.com/problems/longest-substring-without-repeating-characters/solution/](https://leetcode.com/problems/longest-substring-without-repeating-characters/solution/) \ No newline at end of file diff --git a/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md b/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md new file mode 100644 index 0000000..7634117 --- /dev/null +++ b/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md @@ -0,0 +1,60 @@ +**5. 最长回文子串** +--- +[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) + +解决方案 +**思路** +从1到字符串长度开始遍历,找每个长度可能存在的字符串。 +注意:每个长度只要找到一个即可,并且注意当前长度存在回文串的条件为上次迭代存在回文串或者上上次. +注意剪枝操作,不然的话有可能会超时 +``` + public static String longestPalindrome(String s) { + //用来记录上次最长的回文串长度 + int max = 1; + //存储当前长度对应的回文串 + Map subStringMap = new HashMap<>(); + subStringMap.put(1, Character.toString(s.charAt(0))); + int len = s.length(); + //当前迭代回文串存在的条件是,要么上次迭代存在回文串,要么上上次存在 + boolean flag = false; + for (int i = 2; i <= len; i++) { + for (int t = 0; t + i <= len; t++) { + if ((i - 1) != max && (i - 2) != max) + break; + if (flag) { + flag = false; + continue; + } + String subString = s.substring(t, t + i); + if (check(subString)) { + //注意,只要当前长度找到一个回文串就可以了,不需要再找了 + max = i; + if (!subStringMap.containsKey(i)) { + subStringMap.put(i, subString); + } else + flag = true; + break; + } + } + } + return subStringMap.get(max); + } + + private static boolean check(String subString) { + int len = subString.length(); + int mid = len / 2; + for (int i = 0; i < mid; i++) { + //从两遍向中间靠拢对比 + if (subString.charAt(i) != subString.charAt(len - 1 - i)) + return false; + } + return true; + } +``` +**复杂度分析** +时间复杂度:O(N*N) +空间复杂度:O(N) 额外用了一个存储结构 + + +**参考资料** +[https://blog.csdn.net/cserwangjun/article/details/80878797](https://blog.csdn.net/cserwangjun/article/details/80878797) diff --git a/_site/leetcode/005-LongestPalindromicSubstring/official.md b/_site/leetcode/005-LongestPalindromicSubstring/official.md new file mode 100644 index 0000000..7bb01c7 --- /dev/null +++ b/_site/leetcode/005-LongestPalindromicSubstring/official.md @@ -0,0 +1,3 @@ +**5. 最长回文子串** +--- +[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git a/_site/leetcode/015-threeSum/hatrick.md b/_site/leetcode/015-threeSum/hatrick.md new file mode 100644 index 0000000..8c48ec4 --- /dev/null +++ b/_site/leetcode/015-threeSum/hatrick.md @@ -0,0 +1,52 @@ +**15. 三数之和** +--- +[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) + + +解决方案 +**思路** +首先考虑数组遍历时去重: +方法一:先将数组排好序,在遍历的时候与上一个进行比较,相同则直接进入下一个 +方法二:用容器Set——简单,但是同样需要排序,增加算法复杂度并且此题三个数操作不方便, +    降低复杂度一般的途径就是利用已有的而未用到的条件将多余的步骤跳过或者删去,由于三个数是具有一个特点的:和为某个定值,这个条件只是用来判断了而并没有使用 +    并且,由上个去重得知,后面使用的数组是已经排序好的。此时仔细想想应该就能想到,从两端使用两个指针相向移动,两端指针所指数之和如果小于目标值,只需要移动左边的指针,否则只需要移动右边的指针!! + 例如[1,1,1,4,5,7,8,8,9]中 定目标值为15,从两边开始,1+9为10,小于15,移动右边指针左移变成1+8只会更少,所以移动左边变成4+9以此类推 + +``` + public static List> threeSum(int[] nums) { + List> result = new ArrayList<>(); + Arrays.sort(nums); + + for (int i = 0; i < nums.length - 2; i++) { + int left = i + 1; + int right = nums.length - 1; + if (i > 0 && nums[i] == nums[i - 1]) + continue; // 去掉重复的起点 + while (left < right) { + int sum = nums[left] + nums[right] + nums[i]; + if (sum == 0) { + result.add(Arrays.asList(nums[i], nums[left], nums[right])); + while (left < right && nums[left] == nums[left + 1]) + left++; // 去掉重复的左点 + while (left < right && nums[right] == nums[right - 1]) + right--; // 去掉重复的右点 + right--; // 进入下一组左右点判断 + left++; + } else if (sum > 0) { + right--; // sum>0 ,说明和过大了,需要变小,所以移动右边指针 + } else { + left++; // 同理,需要变大,移动左指针 + } + } + } + return result; + } + +``` +**复杂度分析** +时间复杂度:O(N2) 使用排序+去重+双指针移动定位 +空间复杂度:O(N) + + +**参考资料** +[https://www.cnblogs.com/Xieyang-blog/p/8242900.html](https://www.cnblogs.com/Xieyang-blog/p/8242900.html) diff --git a/_site/leetcode/015-threeSum/official.md b/_site/leetcode/015-threeSum/official.md new file mode 100644 index 0000000..f849931 --- /dev/null +++ b/_site/leetcode/015-threeSum/official.md @@ -0,0 +1,4 @@ +**15. 三数之和** +--- +[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) + diff --git a/_site/leetcode/020-validParentheses/official.md b/_site/leetcode/020-validParentheses/official.md new file mode 100644 index 0000000..a82a70a --- /dev/null +++ b/_site/leetcode/020-validParentheses/official.md @@ -0,0 +1,4 @@ +**20. 有效的括号** +--- +[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) + diff --git a/_site/leetcode/024-swapNodesInPairs/official.md b/_site/leetcode/024-swapNodesInPairs/official.md new file mode 100644 index 0000000..0004d08 --- /dev/null +++ b/_site/leetcode/024-swapNodesInPairs/official.md @@ -0,0 +1,4 @@ +**24. 两两交换链表中的节点** +--- +[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) + diff --git a/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md b/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md new file mode 100644 index 0000000..5e33667 --- /dev/null +++ b/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md @@ -0,0 +1,75 @@ +25. k个一组翻转链表 +--- + +[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) + +```java + /** + * 递归解法 + *

+ * //定义ListNode如下 + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + * + * @param head + * @param k + * @return + */ + public ListNode reverseKGroup(ListNode head, int k) { + if (head == null || head.next == null) return head; + ListNode prev = null; //定义一个前驱结点prev,初始值为null + ListNode next = head.next; //定义当前结点的后继结点next + ListNode tail = head; //定义尾结点,缓存当前头结点,反转后变成尾结点 + int k0 = k; //定义k0缓存原始k值 + // while循环中的代码每次操作的都是前一个结点的后继结点 + // 当循环至k-1次时,操作的是本组最后一个结点 + // 所以在循环开始前让k=k-1,将循环减少1次,否则会计算下一组的头结点 + k = k - 1; + while (next != null && k > 0) { + head.next = prev; //反转当前结点 + //反转完成后为下一轮循环赋值 + prev = head; //当前结点赋值给前驱结点变量prev + head = next; //后继结点赋值给当前结点变量head + next = head.next; //获得新的后继结点 + k--; + } + //while循环结束后,head是本组结点原顺序的尾结点,翻转后的新头结点 + //对head进行翻转操作,本组结点全部翻转完毕 + head.next = prev; + + //如果k>0说明本组的结点总数少于k + if (k > 0) { + //用原始值k0减去剩余的k,得到本组结点的实际个数 + k = k0 - k; + //重新反转链表 + //因为本组长度小于k,根据题意要保持原有顺序 + //上面的while循环已经做了反转,重新调用reverseKGroup再反转一次回到原有顺序 + head = reverseKGroup(head, k); + } else { + k = k0;//k恢复原始值 + //获取下一组的头结点 + next = reverseKGroup(next, k); + //将本组的尾结点与下一组的头结点连接 + tail.next = next; + } + //每次都返回新的头结点 + return head; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +若链表结点个数为n,k个一组,共n/k组, +方法依次对每组结点进行处理,总共需要(n/k)次, +因为使用了递归调用,所以递归本身的时间复杂度是n/k, +方法中使用了while循环,遍历每组中的k个结点,时间复杂度为k, +最终时间复杂度是(n/k)*k = n + +空间复杂度:O(n),本题中递归的空间复杂度约为n/k,所以空间复杂度是O(n) + +--- diff --git a/_site/leetcode/025-reverseNodesInKGroup/official.md b/_site/leetcode/025-reverseNodesInKGroup/official.md new file mode 100644 index 0000000..392197d --- /dev/null +++ b/_site/leetcode/025-reverseNodesInKGroup/official.md @@ -0,0 +1,4 @@ +**25. k个一组翻转链表** +--- +[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) + diff --git a/_site/leetcode/032-LongestValidParentheses/official.md b/_site/leetcode/032-LongestValidParentheses/official.md new file mode 100644 index 0000000..181dca1 --- /dev/null +++ b/_site/leetcode/032-LongestValidParentheses/official.md @@ -0,0 +1,3 @@ +**32. 最长有效括号** +--- +[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) diff --git a/_site/leetcode/036-ValidSudoku/SpecialYang.md b/_site/leetcode/036-ValidSudoku/SpecialYang.md new file mode 100644 index 0000000..c9382fd --- /dev/null +++ b/_site/leetcode/036-ValidSudoku/SpecialYang.md @@ -0,0 +1,113 @@ +**有效的数独** +--- +https://leetcode.com/problems/valid-sudoku/ + +此题其实很简单,根本无需采用dfs的方式即可解决,平常的循环做法即可。主要解决如下问题: +1. 保证每一行不出现重复的数字 +2. 保证每一列不出现重复的数字 +3. 保证每一个子九宫格不出现重复的数字 + +本题没有要求你解数独,只是单纯的让你判断是否合法,那还不简单,遍历判断呗 + +### 思路一 +循环遍历九宫格,判断每一个已填充数字的单元格是否是合法。 +1. 对于行,我们判断该行中除了当前列以外是否出现了重复数字 +2. 对于列,我们判断该列中除了当前行以外是否出现了重复数字 +3. 对于九宫格,我们判断该九宫格除了当前位置以外是否出现了重复数字 + +```java + /** + * 常规遍历做法 + * @param board + * @return + */ + public boolean isValidSudoku1(char[][] board) { + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + //对每一个不是'.'的格子进行判断 + if (board[i][j] != '.' + && !isValidSudoku(board, i, j)) { + return false; + } + } + } + return true; + } + + /** + * 判断该单元格出现的数字是否是合法的 + * @param board + * @param row + * @param col + * @return + */ + public boolean isValidSudoku(char[][] board, int row, int col) { + char ch = board[row][col]; + //行 + for (int i = 0; i < 9; i++) { + if (i != row && ch == board[i][col]) { + return false; + } + } + //列 + for (int i = 0; i < 9; i++) { + if (i != col && ch == board[row][i]) { + return false; + } + } + //九宫格 + //定位该单元格所处的九宫格的起始行 + int startRow = row / 3 * 3; + //定位该单元格所处的九宫格的起始列 + int startCol = col / 3 * 3; + for (int i = startRow; i < startRow + 3; i++) { + for (int j = startCol; j < startCol + 3; j++) { + if (i != row && j != col && ch == board[i][j]) { + return false; + } + } + } + return true; + } +``` +#### 复杂度 +- 时间复杂度:O(n^2),双重循环嘛。至于判断逻辑则是常量级别 +- 空间复杂度:O(1) + +### 思路二 +思路一其实对于每一个单元格进行判断时的算法常量级别还是有点大的。每次都会从行的开头或者列的开头判断,所以我们可以缓存起来,这样下次判断的时候,即可快速查找是否有响应的值,这时就要用O(1)查询的哈希结构了,**集合**非常适合本情况。 +我们利用3个set,分别代表每行,每列,每个九宫格出现的数字 +1. 数字存到**行集合**的形式为:`rows.add(num + " in row " + i)` +2. 数字存到**列集合**的形式为:`cols.add(num + " in col " + j)` +3. 数字存到**九宫格集合**的形式为:`blocks.add(num + "in block " + i / 3 + "-" + j / 3)` + +```java + /** + * 空间换时间 + * @param board + * @return + */ + public boolean isValidSudoku2(char[][] board) { + Set rows = new HashSet<>(); + Set cols = new HashSet<>(); + Set blocks = new HashSet<>(); + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + char num = board[i][j]; + if (!rows.add(num + " in row " + i) || + !cols.add(num + " in col " + j) || + !blocks.add(num + "in block " + i / 3 + "-" + j / 3)) { + return false; + } + } + } + } + return true; + } +``` +#### 复杂度 +- 时间复杂度:O(n) +- 空间复杂度:O(n) + +参考:https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings diff --git a/_site/leetcode/036-ValidSudoku/official.md b/_site/leetcode/036-ValidSudoku/official.md new file mode 100644 index 0000000..16e3f01 --- /dev/null +++ b/_site/leetcode/036-ValidSudoku/official.md @@ -0,0 +1,4 @@ +**36. 有效的数独** +--- + +[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) diff --git a/_site/leetcode/037-SudokuSolver/SpecialYang.md b/_site/leetcode/037-SudokuSolver/SpecialYang.md new file mode 100644 index 0000000..9a59455 --- /dev/null +++ b/_site/leetcode/037-SudokuSolver/SpecialYang.md @@ -0,0 +1,97 @@ +**解数独** +--- +https://leetcode.com/problems/sudoku-solver/ + +这道题其实是有效数独的延伸,要求你为给定的数独图的中所有空位填入合适的数字,并且满足数独图的要求。 + +难度其实不大,就是普通的dfs问题。分2个步骤: +1. 递过程:对于每一个空的单元格,尝试从1到9,填入单元格中,并检验是否有效。若有效,则向下递,否则换另一个数填入 +2. 归过程:即回溯,当前的单元格恢复为空白 + +我们还是从(0,0)开始,一直探索到不满足条件,然后回溯,再次向下探索,直到(9,0)为止。因为题目保证了必然有解,所以当探索到(9,0)位置时,说明之前填入的数都是合法的。 + +```java + public void solveSudoku(char[][] board) { + dfs(board, 0, 0); + } + + /** + * 递归填充值 + * 每个待填的格子 从1开始到9尝试填充 + * @param board + * @param row + * @param col + * @return + */ + public boolean dfs(char[][] board, int row, int col) { + //递归结束条件 + if (row == 9 && col == 0) { + return true; + } + /* + 首先生成下一个格子的合法位置 + 在这里处理的目的是为了避免后面的循环部分,每次都要求下一个位置 + */ + int newCol = col + 1, newRow = row; + //换行 + if (newCol == 9) { + newCol = 0; + newRow += 1; + } + //如果该单元格不用填充,则直接往前递 + if (board[row][col] != '.') { + return dfs(board, newRow, newCol); + } + //尝试1到9填充 + for (char i = '1'; i <= '9'; i++) { + if (isValid(board, row, col, i)) { + //递 + board[row][col] = i; + //要当前填充有解,直接往上回溯 + if (dfs(board, newRow, newCol)) { + return true; + } + //归 + board[row][col] = '.'; + } + } + return false; + } + + /** + * 判断如果放入该值,是否满足合法 + * @param board + * @param row + * @param col + * @param ch + * @return + */ + public boolean isValid(char[][] board, int row, int col, char ch) { + //满足行要求 + for (int i = 0; i < 9; i++) { + if (i != row && ch == board[i][col]) { + return false; + } + } + //满足列要求 + for (int i = 0; i < 9; i++) { + if (i != col && ch == board[row][i]) { + return false; + } + } + //满足单元格要求 + int startRow = row / 3 * 3; + int startCol = col / 3 * 3; + for (int i = startRow; i < startRow + 3; i++) { + for (int j = startCol; j < startCol + 3; j++) { + if (i != row && j != col && ch == board[i][j]) { + return false; + } + } + } + return true; + } +``` +#### 复杂度 +- 时间复杂度:O(9^k),k为空白的单元格数 +- 空间复杂度:O(1),虽然深度最大为81,但是是固定值,故可认为是常量级别 diff --git a/_site/leetcode/037-SudokuSolver/official.md b/_site/leetcode/037-SudokuSolver/official.md new file mode 100644 index 0000000..3ab44bf --- /dev/null +++ b/_site/leetcode/037-SudokuSolver/official.md @@ -0,0 +1,4 @@ +**37. 解数独** +--- + +[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) diff --git a/_site/leetcode/050-powxN/bigablecat.md b/_site/leetcode/050-powxN/bigablecat.md new file mode 100644 index 0000000..1b1c9ee --- /dev/null +++ b/_site/leetcode/050-powxN/bigablecat.md @@ -0,0 +1,57 @@ +**50. Pow(x, n)** +--- +[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) + + +* 网友高票Java解法,递归分治 + +```java + + public double myPow(double x, int n) { + //如果n==0,返回1,因为x的0次方为1 + if (n == 0) + return 1; + if (n < 0) { + //因为 n = -1*(-n),所以x的n次方等于x的-1次方的-n次方 + //所以n等于负数时进行如下两步操作 + // n = -n让n变为正 + n = -n; + //让x成为x的倒数 + x = 1 / x; + //判断原来的n值是否超出了JavaInteger的下界 + if (-n == Integer.MIN_VALUE) { + //考虑到Java语言中Integer的取值范围在-2147483648到2147483647之间 + //Integer.MIN_VALUE = -2147483648, + //Integer.MAX_VALUE = 2147483647, + //当n的值在取值范围之外,编译无法通过,不予考虑 + //当 n = -2147483648 时,让 n = -n 得到 n = 2147483648 超过了Integer.MAX_VALUE=2147483647 + //为了避免这种情况,在n = -n = 2147483648后 + //让n-1 = 2147483647,同时取出一个x,按照奇数的计算方式返回结果 + return x * myPow(x, (n - 1)); + } + } + //接下来进行分治,将求x的n次方转变为求x平方的(n/2)次方 + //判断n是否为偶数,如果是偶数,只需递归调用myPow,如果是奇数,取出一个x,再与myPow结果相乘 + return (n % 2 == 0) ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } + + +``` + +**复杂度分析** + +时间复杂度:O(logn), +每次递归,n就被2分一次,n/2/2..., +所以总共调用递归方法的次数是logn次, +递归方法中没有循环,只有常数级的操作, +所以总的时间复杂度是O(logn) + +空间复杂度:O(logn), +每次递归都占用O(1)的空间 + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) diff --git a/_site/leetcode/051-NQueens/melody-l.md b/_site/leetcode/051-NQueens/melody-l.md new file mode 100644 index 0000000..b9e7f9f --- /dev/null +++ b/_site/leetcode/051-NQueens/melody-l.md @@ -0,0 +1,94 @@ +**051. NQueens** +--- +[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) + +方法一:回溯法 +```java + +public class Solution { + public List> solveNQueens(int n) { + // 构造棋盘 + char[][] board = new char[n][n]; + // 初始化棋盘所有的棋子 + for(int i = 0; i < n; i++) + for(int j = 0; j < n; j++) + board[i][j] = '.'; + // 初始化结果集 + List> resultList = new ArrayList>(); + // 从第0列开始搜索所有结果,保存到resultList结果集中 + search(board, 0, resultList); + + return resultList; + } + + /** + * 递归获取所有的结果 + * @param board 棋盘 + * @param column 所在列 + * @param resultList 最终结果集 + */ + public void search(char[][] board, int column, List> resultList) { + // 如果最后一列已经遍历完,则将棋盘保存,添加到最终结果集中并返回 + if(column == board.length) { + resultList.add(construct(board)); + return; + } + + // 寻找第column列的哪一行适合放置皇后的位置 + for(int i = 0; i < board.length; i++) { + // 如果在第i行,第column列添加皇后能够满足棋盘的0~column列不冲突 + if(validate(board, i, column)) { + // 第i行,第column列放置一个皇后 + board[i][column] = 'Q'; + // 继续探索第column+1列适合放置皇后的位置 + search(board, column + 1, resultList); + // 重置column列的结果,继续探索其他位置的可能性 + board[i][column] = '.'; + } + } + } + + /** + * 验证将皇后放在第y列,第x行,是否可行 + * 由于棋盘的0~y-1列的皇后位置都是有效的, + * 所以验证方式为:让0~y-1列的皇后与当前的皇后比,若都不存在冲突,则有效 + * 冲突检测,正负对角线(测试斜率是否为正负一),是否同一行(不可能同列) + * @param board 棋盘 + * @param x 所在行 + * @param y 所在列 + * @return 位置是否有效 + */ + public boolean validate(char[][] board, int x, int y) { + // 从第i行开始遍历 + for(int i = 0; i < board.length; i++) { + // 从第j列开始遍历 + for(int j = 0; j < y; j++) { + // 如果此位置为皇后,且满足两点斜率为正负1或者同行,则存在冲突 + if(board[i][j] == 'Q' && (x - i == y - j || x - i == j - y || x == i)) + return false; + } + } + + return true; + } + + // 产生了一个结果集序列 + public List construct(char[][] board) { + List result = new LinkedList(); + for(int i = 0; i < board.length; i++) { + String s = new String(board[i]); + result.add(s); + } + return result; + } +} + +``` + +--- + + +**参考资料** + +* 网友推荐题解: +[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) diff --git a/_site/leetcode/051-NQueens/official.md b/_site/leetcode/051-NQueens/official.md new file mode 100644 index 0000000..b61c943 --- /dev/null +++ b/_site/leetcode/051-NQueens/official.md @@ -0,0 +1,4 @@ +**51. N-皇后** +--- + +[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) diff --git a/_site/leetcode/052-N-QueensII/hatrick.md b/_site/leetcode/052-N-QueensII/hatrick.md new file mode 100644 index 0000000..b4d30b5 --- /dev/null +++ b/_site/leetcode/052-N-QueensII/hatrick.md @@ -0,0 +1,61 @@ +**52. N皇后 II** +--- + +[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) + +```java + +public class NQueenII { + private int count = 0; + + public int totalNQueens(int n) { + int[] x = new int[n]; + queens(x, n, 0); + return count; + } + + private void queens(int[] x, int n, int row) { + for (int i = 0; i < n; i++) { + //判断是否合法 + if (check(x, n, row, i)) { + //将皇后放在第row行,第i列 + x[row] = i; + //如果是最后一行,则输出结果 + if (row == n - 1) { + count++; + //回溯,寻找下一个结果 + x[row] = 0; + return; + } + //寻找下一行 + queens(x, n, row + 1); + //回溯 + x[row] = 0; + } + } + } + + /** + * @param x 数组解 + * @param n 棋盘长宽 + * @param row 当前放置行 + * @param col 当前放置列 + * @return + */ + private boolean check(int[] x, int n, int row, int col) { + for (int i = 0; i < row; i++) { + if (x[i] == col || x[i] + i == col + row || x[i] - i == col - row) { + return false; + } + } + return true; + } +} + +``` +--- + + +**参考资料** + +[https://blog.csdn.net/xygy8860/article/details/46861817](https://blog.csdn.net/xygy8860/article/details/46861817) diff --git a/_site/leetcode/052-N-QueensII/official.md b/_site/leetcode/052-N-QueensII/official.md new file mode 100644 index 0000000..090fa43 --- /dev/null +++ b/_site/leetcode/052-N-QueensII/official.md @@ -0,0 +1,4 @@ +**52. N皇后 II** +--- + +[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) diff --git a/_site/leetcode/053-maximumSubarray/BambooYH.md b/_site/leetcode/053-maximumSubarray/BambooYH.md new file mode 100644 index 0000000..83e556f --- /dev/null +++ b/_site/leetcode/053-maximumSubarray/BambooYH.md @@ -0,0 +1,59 @@ +**最大的子数组和** +--- +[https://leetcode.com/problems/maximum-subarray/](https://leetcode.com/problems/maximum-subarray/) + +解决方案: +方法一:**DP** +**思路** +找一个数组中,连续子数组的最大和。最暴力的解法就是两重循环,从第一个元素开始,遍历后面的元素,依次计算子数组的和。然后在从第二个元素开始遍历。这样的做法显然时间复杂度比较高,是`O(n^2)`.我们可以用动态规划的思想来解决这个问题。假设有`array[0]~array[n-1]`共n个元素,换个角度来看问题,我们也就是求分别以`array[i]`结尾的子数组的最大和。如果我们求以`array[n-1]`结尾的子数组最大和`Sum(n-1)`,我们可以先求`array[n-2]`结尾的子数组最大和`Sum(n-2)`,如果这个`Sum(n-2)>0`,那么说明这段子数组对后面的数组一定有贡献,因为这个数是个正数。n +**算法** +从左向右遍历,依次计算以`array[i]`为结尾的子数组的最大和。在遍历的过程中,用一个变量`max`记录曾经出现过的最大值。遍历完成后返回`max`。 +``` +public class Solution { + public int maxSubArray(int[] A) { + int n = A.length; + //创建一个跟原数组等大小的辅助数组dp,dp[i]表示以A[i]结尾的子数组的最大和 + int[] dp = new int[n]; + //初始化dp[0],因为以A[0]结尾的子数组的最大和就是A[0] + dp[0] = A[0]; + //记录遍历过程中出现过的最大值 + int max = dp[0]; + + for(int i = 1; i < n; i++){ + //如果dp[i-1]>0,那么dp[i] = dp[i-1]+A[i],因为dp[i-1]是个正数,所以对dp[i]有贡献 + dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0); + //记录当前出现的最大值 + max = Math.max(max, dp[i]); + } + + return max; + } +} +``` +复杂度分析: +n表示数组的长度 +空间复杂度:O(1) +时间复杂度:O(n) + +上面定义了一个DP数组是为了方便理解,其实上面的DP数组可以用一个变量`cur`来表示,代码如下: +``` +public class Solution { + public int maxSubArray(int[] A) { + int n = A.length; + int cur = A[0]; + int max = A[0]; + + for(int i = 1; i < n; i++){ + cur = cur > 0 ? A[i]+cur : A[i]; + max = Math.max(max, cur); + } + + return max; + } +} +``` + +复杂度分析: +n表示数组的长度 +空间复杂度:O(1) +时间复杂度:O(n) \ No newline at end of file diff --git a/_site/leetcode/053-maximumSubarray/official.md b/_site/leetcode/053-maximumSubarray/official.md new file mode 100644 index 0000000..e50ab30 --- /dev/null +++ b/_site/leetcode/053-maximumSubarray/official.md @@ -0,0 +1,3 @@ +**53. 最大子序和** +--- +[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/062-UniquePaths/BambooYH.md b/_site/leetcode/062-UniquePaths/BambooYH.md new file mode 100644 index 0000000..c42de98 --- /dev/null +++ b/_site/leetcode/062-UniquePaths/BambooYH.md @@ -0,0 +1,64 @@ +**不同路径** + +[https://leetcode.com/problems/unique-paths/](https://leetcode.com/problems/unique-paths/) + +方法一:**动态规划** +**思路** +这道题是一道特别经典的动态规划题,而且有助于理解动态规划。首先分析题意,这部是最重要的,只有认真分析题意,才可以找出正确的状态转移方程。首先题目要求从左上角,走到右下角。在每次移动的过程中,只有两个方向可以选择,要么往右走,要么往下走。这是非常关键的,也就是说,如果我们走到了`array[i][j]`这个点,那上一步要么在这个点的上边`array[i-1][j]`,要么在这个点的左边`array[i][j-1]`,只有这两种情况。换句话说,如果我们用dp[i][j]表示到array[i][j]这个点的路径数,那么`dp[i][j] = dp[i-1][j] + dp[i][j-1]`,这个肯定是正确的,因为只有上述描述的两种情况。 + +**算法** +我们从上到下,从左到右遍历,然后利用公式`dp[i][j] = dp[i-1][j] + dp[i][j-1]`算出最终结果。 +``` +class Solution { + public int uniquePaths(int m, int n) { + int[][] dp = new int[m][n]; + //初始化,到达dp[0][j]只有1条路径,因为只能往右和下走 + for(int i = 0; i < n; i++) { + dp[0][i] = 1; + } + //初始化,到达dp[i][0]只有一条路径 + for(int i = 0; i < m; i++) { + dp[i][0] = 1; + } + //遍历 + for(int i = 1; i < m; i++) { + for(int j = 1; j < n; j++) { + dp[i][j] = dp[i-1][j] + dp[i][j-1]; + } + } + + return dp[m-1][n-1]; + } +} +``` +复杂度分析: +假设矩阵的行数为M,列数为N +时间复杂度:O(M*N) + +空间复杂度:O(M*N) + +## 优化 +上述代码可以进行空间优化,我们可以看到,dp[i][j]只与两个数值有关,而且这两个数值,一个是它左边的,一个是它右边的,所以我们可以只用一个大小为n的一维数组。具体代码如下 +``` +class Solution { + public int uniquePaths(int m, int n) { + int[] dp = new int[n]; + //初始化 + for(int i = 0; i < n; i++) { + dp[i] = 1; + } + for(int i = 1; i < m; i++) { + for(int j = 1; j < n; j++) { + //右边的dp[j]其实就相当于dp[i-1][j],因为这个值是更新之前的值,dp[j-1]相当于dp[i][j-1]. + dp[j] = dp[j-1] + dp[j]; + } + } + + return dp[n-1]; + } +} +``` +复杂度分析: +假设矩阵的行数为M,列数为N +时间复杂度:O(M*N) +空间复杂度:O(N) \ No newline at end of file diff --git a/_site/leetcode/062-UniquePaths/official.md b/_site/leetcode/062-UniquePaths/official.md new file mode 100644 index 0000000..4cd834b --- /dev/null +++ b/_site/leetcode/062-UniquePaths/official.md @@ -0,0 +1,3 @@ +**62. 不同路径** +--- +[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) diff --git a/_site/leetcode/063-UniquePathsII/SpecialYang.md b/_site/leetcode/063-UniquePathsII/SpecialYang.md new file mode 100644 index 0000000..f182475 --- /dev/null +++ b/_site/leetcode/063-UniquePathsII/SpecialYang.md @@ -0,0 +1,115 @@ +63.不同的路径Ⅱ +--- +https://leetcode.com/problems/unique-paths-ii/ +题目的意思是给定一个网格,机器人从左上角开始走,走到右下角一共有多少种步数,同时网格中可能有障碍物。机器人的方向只能向右和向左两种走法,显然当前位置的可以由它的上和左方向走来,所以这是经典的动态规划问题。 +### 思路一 +因为考虑障碍物,所以状态方程如下: +```math +dp[i][j] = dp[i][j - 1] + dp[i]- 1][j], \; +\;if grid[i][j] == 0 + +dp[i][j] = 0, \;\; if grid[i][j] = 1 +``` +我们这里额外引入空间来存放到第i行,第j列的走法 +``` + /** + * 当前格子只能由它的上面和左边过来 + * 所以状态转移方程为: + * dp[i][j] = dp[i][j - 1] + dp[i - 1][j] + * dp[i][j] = 0, if obstacle + * @param obstacleGrid + * @return + */ + public int uniquePathsWithObstacles1(int[][] obstacleGrid) { + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + //额外空间,用于方便处理边界 + int[][] dp = new int[m + 1][n + 1]; + dp[1][0] = 1; + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (obstacleGrid[i - 1][j - 1] == 0) { + dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; + } + } + } + return dp[m][n]; + } +``` +#### 复杂度 +- 时间复杂度:O(m `$\times$` n) +- 空间复杂度:O(m `$\times$` n) +### 思路二 +对状态方程进行优化,压缩状态 +``` + /** + * dp[i][j]仅依赖它的上方和左边两个状态 + * 所以压缩状态,dp[i - 1]对应dp[i][j - 1], dp[i]对应dp[i - 1][j] + * + * 注意每一行的第0列特殊处理一下 + * @param obstacleGrid + * @return + */ + public int uniquePathsWithObstacles3(int[][] obstacleGrid) { + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + //额外空间,用于方便处理边界 + int[] dp = new int[n + 1]; + dp[0] = 1; + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (obstacleGrid[i - 1][j - 1] == 0) { + dp[j] = (i != 1 && j == 1 ? 0 : dp[j - 1]) + dp[j]; + } else { + //这里要归0,因为会被下一个行作为头部使用 + dp[j] = 0; + } + } + } + return dp[n]; + } +``` +#### 复杂度 +- 时间复杂度:O(m `$\times$` n) +- 空间复杂度:O(n) + +### 思路三 +我们不需要额外的空间,用网格本身来作dp状态。 +- 首先我们对第0行和第0列进行特殊处理,判断每一个位置之前值是否为1(表示路径可达),然后看当前位置是否是障碍物。若不是障碍物,则当前值设置为1,表示可达;否则设置为0,表示不可达。我们可以看到对于为1的障碍物我们都清0,因为此时0代表路径数,其实就是不可达。 +- 对第0列也进行同样的处理 +- 从第1行开始,从每行的第1列开始,遍历判断当前位置的值是不是障碍物,若是,则设置0,表示不贡献路径数,否则为头部和左边的和 + +```java + /** + * 用网格自身作为dp + * @param obstacleGrid + * @return + */ + public int uniquePathsWithObstacles2(int[][] obstacleGrid) { + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + if (obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) { + return 0; + } + obstacleGrid[0][0] = 1; + for (int i = 1; i < n; i++) { + obstacleGrid[0][i] = (obstacleGrid[0][i - 1] == 1 && obstacleGrid[0][i] == 0) ? 1 : 0; + } + for (int i = 1; i < m; i++) { + obstacleGrid[i][0] = (obstacleGrid[i - 1][0] == 1 && obstacleGrid[i][0] == 0) ? 1 : 0; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (obstacleGrid[i][j] == 0) { + obstacleGrid[i][j] = obstacleGrid[i][j - 1] + obstacleGrid[i - 1][j]; + } else { + obstacleGrid[i][j] = 0; + } + } + } + return obstacleGrid[m - 1][n - 1]; + } +``` +#### 复杂度 +- 时间复杂度:O(m `$\times$` n) +- 空间复杂度:O(1) \ No newline at end of file diff --git a/_site/leetcode/063-UniquePathsII/official.md b/_site/leetcode/063-UniquePathsII/official.md new file mode 100644 index 0000000..7c71971 --- /dev/null +++ b/_site/leetcode/063-UniquePathsII/official.md @@ -0,0 +1,3 @@ +**63. 不同路径 II** +--- +[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) diff --git a/_site/leetcode/064-minimumPathSum/melody-l.md b/_site/leetcode/064-minimumPathSum/melody-l.md new file mode 100644 index 0000000..f81c6a3 --- /dev/null +++ b/_site/leetcode/064-minimumPathSum/melody-l.md @@ -0,0 +1,54 @@ +**064. MinimunPathSum** +--- +[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) + +方法一:动态规划 + +由于题目规定,每次只能向下或者向右移动一步。因此,对于(i,j)的最小路径,只能从左边(i, j-1)和上边(i-1, j)中选择最小的路径。所以递推式为: +设(i,j)所在位置的权重为V(i,j),最小路径为A(i,j),则: +* 若i=0 且 j!=0, A(i, j) = A(i-1, j) + V(i, j) +* 若i!=0 且 j=0, A(i, j) = A(i, j-1) + V(i, j) +* 若i!=0 且 j!=0, A(i ,j) = Min{A(i-1, j) , A(i, j-1)} + V(i, j) +* 若i=0 且 j=0, A(i, j) = V(i, j) + +由于A(i, j)是依赖于左上角的,所以从左上角的(0,0)开始向右计算,这样能够保证所有的(i,j)递推式中依赖的值都已经被计算了。 +```java + +public class Solution { + // 复用grid, + // gird中数组的数值经过计算保存由<0,0>到达该点的最小路径和 + public int minPathSum(int[][] grid) { + int row = grid.length;// 行 + int column = grid[0].length; // 列 + // 按照顺序遍历 + for (int i = 0; i < row; i++) { + for (int j = 0; j < column; j++) { + if (i == 0 && j != 0) { // 如果是第一行的 + // 路径只能是从左边出发的 + grid[i][j] = grid[i][j] + grid[i][j - 1]; + } else if (i != 0 && j == 0) { //如果是第一列的 + // 路径只能是从上面出发的 + grid[i][j] = grid[i][j] + grid[i - 1][j]; + } else if (i == 0 && j == 0) { //如果是起点 + grid[i][j] = grid[i][j]; + } else { // 非第一行和第一列的 + // 能到达这个位置, + // 只能由这个位置上面,或者这个位置左边到达了 + // 因此选择上面路径和最小的相加 + grid[i][j] = Math.min(grid[i][j - 1], grid[i - 1][j]) + grid[i][j]; + } + } + } + // 遍历完后,返回最后一个的值 + return grid[row - 1][column - 1]; + } +} + + +``` + +--- + +**参考资料** +* 网友推荐题解: +[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) diff --git a/_site/leetcode/064-minimumPathSum/official.md b/_site/leetcode/064-minimumPathSum/official.md new file mode 100644 index 0000000..ce1339d --- /dev/null +++ b/_site/leetcode/064-minimumPathSum/official.md @@ -0,0 +1,3 @@ +**64. 最小路径和** +--- +[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) diff --git a/_site/leetcode/069-SqrtX/official.md b/_site/leetcode/069-SqrtX/official.md new file mode 100644 index 0000000..b9d2b1f --- /dev/null +++ b/_site/leetcode/069-SqrtX/official.md @@ -0,0 +1,4 @@ +**69. x 的平方根** +--- + +[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) diff --git a/_site/leetcode/070-ClimbingStairs/melody-l.md b/_site/leetcode/070-ClimbingStairs/melody-l.md new file mode 100644 index 0000000..ac89d60 --- /dev/null +++ b/_site/leetcode/070-ClimbingStairs/melody-l.md @@ -0,0 +1,113 @@ +**070. ClimbingStairs** +--- +[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) + +首先判断该问题是否为dp问题。 +对于台阶问题,由于只能走一步或者两步,所以对于N级台阶,很明显得到,第N级台阶的方法数 = 第N-1级台阶方法数 + 第N-2级台阶方法数。即第N级的“最优决策”只与N-1的“最优决策”和N-2的“最优决策”有关,即满足最优子结构和无后效性,而本身问题是有界的,因此该问题为dp问题。 +令F(n)表示n级台阶的方法数,则有: +* F(n) = F(n-1) + F(n-2) (n>=3), +* F(1) = 1 +* F(2) = 2 + +方法一:递推式的递归版本 + +```java + +public class Solution { + /** + * 递推公式,使用递归的实现 + * @param n 问题中的台阶数 + * @return 返回总步数 + */ + public int climbStairs(int n) { + if (n > 2) + return climbStairs(n - 1) + climbStairs(n - 2);// 递推公式递归 + + if (n == 2) + return 2; // 当n=2 + else if (n == 1) + return 1;// 当n=1 + + return 0; + } +} + +``` + +方法二:递推式的递归缓存版 + +递归中存在重复的计算,例如:当n=5时, +* F(5) = F(4)+F(3) +* F(4) = F(3)+F(2) +此时,F(3)重复计算了一次,因此可以在这个地方添加缓存保存中间值。 + +```java + +public class Solution { + /** + * 递推公式,使用递归的实现,添加缓存(又称记忆化搜索)。 + * @param n 问题中的台阶数 + * @return 返回总步数 + */ + public int climbStairs(int n) { + int[] cache = new int[n + 1]; // step从1开始,所以为了方便理解,cache从位置1开始缓存数据 + return doClimbStairs(n, cache); + } + + public int doClimbStairs(int step, int[] cache) { + if (step == 2) + return 2; // 当n=2 + else if (step == 1) + return 1;// 当n=1 + + if (cache[step] > 0) // int[] 初始化默认值为全0,若缓存命中则值大于0 + return cache[step]; // 命中直接返回 + else { + cache[step] = doClimbStairs(step - 1, cache) + doClimbStairs(step - 2, cache);// 未命中,使用递推公式递归 + return cache[step]; //返回结果 + } + } +} + +``` + +方法三:递推式非递归版本 +因为F(n) = F(n-1) + F(n-2) (n>=3)。 +所以,该式子的计算过程是可以用数组表示的,数组的位置为n的值是位置为n-1的值与位置n-2的值之和。 +所以算法思路为:顺序遍历数组,取数组当前位置的前两个位置的值相加赋值给当前位置。 + +```java + +public class Solution { + // 递推公式,非递归版本 + public int climbStairs(int n) { + if (n == 1) + return 1; // 算法思路数组长度至少为2,所以1时直接返回结果 + + // 构造int[] result;存储爬n个台阶的方法数,为了方便对应,所以长度取n+1 + // 如果不希望每一步的结果都被记录,则只需要int result;存储每个阶段的值, + // 循环到n结束的时候将最终结果返回即可 + int[] result = new int[n + 1]; + int start = 1; // 第1个台阶 + int end = 2; // 第2阶台阶 + result[start] = 1; // 第1个台阶方法数为1 + result[end] = 2;// 第2个台阶方法数为2 + + for (int i = 3; i <= n; i++) { + result[i] = result[i - 1] + result[i - 2]; // 第i个台阶数为前两个台阶的方法数之和 + } + + return result[n]; + } +} + +``` + +--- + + +**参考资料** +* 斐波那契数列的数学公式: +[https://blog.csdn.net/beautyofmath/article/details/48184331](https://blog.csdn.net/beautyofmath/article/details/48184331) +* 官方题解: +[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) diff --git a/_site/leetcode/070-ClimbingStairs/official.md b/_site/leetcode/070-ClimbingStairs/official.md new file mode 100644 index 0000000..1d51693 --- /dev/null +++ b/_site/leetcode/070-ClimbingStairs/official.md @@ -0,0 +1,3 @@ +**70. 爬楼梯** +--- +[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) diff --git a/_site/leetcode/072-EditDistance/official.md b/_site/leetcode/072-EditDistance/official.md new file mode 100644 index 0000000..ac7654f --- /dev/null +++ b/_site/leetcode/072-EditDistance/official.md @@ -0,0 +1,3 @@ +**72. 编辑距离** +--- +[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) diff --git a/_site/leetcode/075-SortColors/bigablecat.md b/_site/leetcode/075-SortColors/bigablecat.md new file mode 100644 index 0000000..1daac68 --- /dev/null +++ b/_site/leetcode/075-SortColors/bigablecat.md @@ -0,0 +1,67 @@ +**75. 颜色分类** +--- +[https://leetcode-cn.com/problems/sort-colors/](https://leetcode-cn.com/problems/sort-colors/) + +* 网友高票答案: + +```java + + /** + * https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution + * 网友高票答案 + * + * @param A + */ + public void sortColors(int A[]) { + // 定义整数second代表数字2蓝色,zero代表数字0红色 + // 本方法的思路是将数字2蓝色后移到数组的右侧 + // 数字0红色前移到数组左侧 + // 剩余数字1白色在移动过程中也聚集到了中间 + // second初始值为n-1,即数组A下标的上限 + // zero初始值为0,即数组A下标的下限 + int second = A.length - 1, zero = 0; + //从左向右遍历数组A + for (int i = 0; i <= second; i++) { + //如果当前元素A[i]为2蓝色,且下标i比second小 + //交换当前元素A[i]和A[second]在数组A中的位置 + //second--作为参数传入swap方法,递减是在swap方法结束之后才进行的 + //所以swap方法中操作的是A[second] + while (A[i] == 2 && i < second) swap(A, i, second--); + //如果当前元素A[i]为0白色,且下标i比zero大 + //交换当前元素A[i]和A[zero]在数组A中的位置 + //zero++作为参数传入swap方法,递增是在swap方法结束之后才进行的 + //所以swap方法中操作的是A[zero] + while (A[i] == 0 && i > zero) swap(A, i, zero++); + } + } + + /** + * swap方法,交换数组中两个元素的位置 + * + * @param nums 数组 + * @param i 左侧元素的下标 + * @param j 右侧元素的下标 + * @return + */ + public int[] swap(int[] nums, int i, int j) { + //定义一个临时变量存放右侧元素 + int temp = nums[j]; + //将左侧元素赋值给右侧元素 + nums[j] = nums[i]; + //将临时变量存储的原右侧元素赋值给左侧元素 + nums[i] = temp; + //返回交换后的数组 + return nums; + } + +``` + +**复杂度分析** + +空间复杂度:O(1), +只定义了3个整型变量,没有使用更多额外空间,空间复杂读是O(1) + +**参考资料** + +* 网友高票答案: +[https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution](https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution) diff --git a/leetcode/075-SortColors/official.md b/_site/leetcode/075-SortColors/official.md similarity index 100% rename from leetcode/075-SortColors/official.md rename to _site/leetcode/075-SortColors/official.md diff --git a/_site/leetcode/085-MaximalRectangle/passself.md b/_site/leetcode/085-MaximalRectangle/passself.md new file mode 100644 index 0000000..187fb26 --- /dev/null +++ b/_site/leetcode/085-MaximalRectangle/passself.md @@ -0,0 +1,189 @@ +#85. 最大矩形 + +Leetcode 地址 [https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) + +**题目分析** + +该题目需要有两种结题方式,第一种是利用dp动态规划,第二种是用栈的思路。dp的方式[参考](https://leetcode.com/problems/maximal-rectangle/discuss/29054/share-my-dp-solution)。 + +**思路:** + +已知二维二进制矩阵 + +``` +["1","0","1","0","0"], +["1","0","1","1","1"], +["1","1","1","1","1"], +["1","0","0","1","0"] +``` + +1.定义三个数组 + +**left[]:** 从左到右,连续出现"1"的string 的第一个坐标 + +**right[]:** 从右到左, 连续出现"1"的最后一个坐标 + +**height[]:** 从上到下的高度 + +**result:** (right[i] - left[i]) * heights[i] 其实就是计算面积 (right[i] - left[i])就是宽度 + +height 过程: + +``` +1 0 1 0 0 +2 0 2 1 1 +3 1 3 2 2 +4 0 0 3 0 +``` + +left : + +``` +0 0 2 0 0 +0 0 2 2 2 +0 0 2 2 2 +0 0 0 3 0 +``` +right: + +``` +1 5 3 5 5 +1 5 3 5 5 +1 5 3 5 5 +1 5 5 4 5 +``` +3. + +**具体代码** + +``` +class Solution { + public int maximalRectangle(char[][] matrix) { + if (matrix == null || matrix.length == 0) return 0; + int m = matrix.length; + int n = matrix[0].length; + int result = 0; + int height[] = new int[n]; + int left[] = new int[n]; + int right[] = new int[n]; + Arrays.fill(right,n); + + for (int i = 0; i < m; i++) { + //curLeft 每一行的下标 类似index + int curLeft = 0,curRight = n; + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1') height[j] ++; + else height[j] = 0; + } + + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1'){ + left[j] = Math.max(curLeft,left[j]); + }else { + left[j] = 0; + curLeft = j + 1; + } + } + + for (int j = n- 1; j >= 0; j--) { + if (matrix[i][j] == '1'){ + right[j] = Math.min(curRight,right[j]); + }else{ + right[j] = n; + curRight = j; + } + } + + for (int j = 0; j< n;j++){ + result = Math.max(result,(right[j] - left[j]) * height[j]); + } + } + + return result; + } +} +``` +**时间复杂度** O(N*N) + +leetcode 代码提交后发现击败了98%的commit + +**第二种解法** + +第二种解法是使用栈。基本思路来源就是84题。我们可以这样想想,从每一行来看。每一行对应的矩阵的高度其实就相当于是当前行的直方图,也就相当于求直方图中最大面积。这样一来就和84解法一样了。 + +思路解析 + +将两行加在一起,例如下面两行 + +``` +1 0 1 0 0 +1 0 1 1 1 +``` +加起来得到 + +``` +2 0 2 1 1 +``` +那么这两行的最大长方形要不就是2,要不就是衡向的三个1,那么如果是三行的结果是怎样的 + +``` +1 0 1 0 0 +1 0 1 1 1 +1 1 1 1 1 +``` +加起来得到 + +``` +3 1 3 2 2 +``` +这个结果可以看出,这里就将上面的矩阵表现成为了一个柱状图,值就是它的高度利用leetcode 84的代码 + +``` +private int largestRectangleArea(int[] heights) { + int max = 0, n = heights.length; + int[] small_left = new int[n]; + int[] small_right = new int[n]; + small_left[0] = -1; + small_right[n-1] = n; + for ( int i = 1; i < n; i++ ) { + int idx = i - 1; + while ( idx >= 0 && heights[idx] >= heights[i] ) + idx = small_left[idx]; + small_left[i] = idx; + } + for ( int i = n - 2; i >= 0; i-- ) { + int idx = i + 1; + while ( idx < n && heights[idx] >= heights[i] ) + idx = small_right[idx]; + small_right[i] = idx; + } + for ( int i = 0; i < n; i++ ) { + int area = (small_right[i] - small_left[i] - 1) * heights[i]; + if ( area > max ) + max = area; + } + return max; +} +``` + +计算leetcode 85的最大长方形结果 + +``` +public int maximalRectangle(char[][] matrix) { + if ( matrix == null || matrix.length == 0 ) return 0; + int m = matrix.length, n = matrix[0].length, max = 0; + int[] row_sum = new int[n]; + for ( int i = 0; i < m; i++ ) { + for ( int j = 0; j < n; j++ ) + // 遇到0重置,1累加 + row_sum[j] = ('0' == matrix[i][j]) ? 0 : row_sum[j] + 1; + int area = largestRectangleArea(row_sum); + if ( area > max ) + max = area; + } + return max; +} + +``` + + diff --git a/_site/leetcode/087-ScrambleString/official.md b/_site/leetcode/087-ScrambleString/official.md new file mode 100644 index 0000000..8b79f8e --- /dev/null +++ b/_site/leetcode/087-ScrambleString/official.md @@ -0,0 +1,3 @@ +**87. 扰乱字符串** +--- +[https://leetcode-cn.com/problems/scramble-string/](https://leetcode-cn.com/problems/scramble-string/) diff --git a/_site/leetcode/091-DecodeWays/melody-l.md b/_site/leetcode/091-DecodeWays/melody-l.md new file mode 100644 index 0000000..08615ca --- /dev/null +++ b/_site/leetcode/091-DecodeWays/melody-l.md @@ -0,0 +1,73 @@ +**091. DecodeWays** + +--- +[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) + +* 该问题细节太多,需要对0参与的情况进行特殊考虑。 +1. 求递推式 +设result[i]表示前i+1项字符能构成的解码个数总数。 +* 若第i-1项与第i项组合,不能够小于26,则result[i]的加入不能够增加解码个数的总数,因为其只能作为单项列出来然后加入到之前的所有组合里面,因此result[i] = result[i-1]; +* 若第i-1项与第i项组合,能够小于等于26,则result[i]的加入能够增加解码个数。增加的解码个数是将i-1与i作为一个整体插入到i-2序列中会产生的解码个数。即result[i] = result[i-1] + result[i-2]; +2. 特殊情况说明 +因为提供的数据中存在有0的情况,这个需要单独拿出来看。题目示例没有给0所对应的例子。此处列举几例:`10解码只有1种,即10`,`100解码只有0种,因为10,0并不能被解码`,`101解码只有1中,因为01不能被当作1来看待`,`301解码只有0种,因为30没有对应的值,01不能被当作1来看待`。 +3. 算法思路 +递推式中的i>=2,所以先确定i=0,i=1的情况。然后顺序遍历数组后面的值,根据递推式相加即可。唯一需要针对有0的进行特殊考虑。 + + +--- + +方法一:动态规划 + +```java + +public class Solution { + public int numDecodings(String s) { + // String转为char数组进行计算 + char[] problem = s.toCharArray(); + // result[i]表示索引为i时, + // 前i+1项char数组所构成的String字符串的解码总数 + int[] result = new int[problem.length]; + + // 如果第一个字母为0,则一定不能解码, + // '01'是不能作为'1'解码的 + if (problem[0] == '0') + return 0; + // 如果第一个字母不为0,长度为1,则解码的方式有1种 + else if (problem.length == 1) + return 1; + + // 下面探讨:长度>=2 且 首字母不为'0'的情况 + // 索引为0的解码总数为1 + result[0] = 1; + // result[1]的值进行分类探讨,此时首字母肯定不为0, + if (problem[1] == '0' && problem[0] >= '3') { + // 类似于'30'开头,解码总数为0 + return 0; + } else if (problem[1] != '0' && problem[1] + problem[0] * 10 <= 554) { + // 类似于'12',解码总数为2 + result[1] = 2; + } else { + // 类似于'34'和'20' + result[1] = 1; + } + + for (int i = 2; i < problem.length; i++) { + if (problem[i] == '0' && (problem[i - 1] >= '3' || problem[i - 1] <= '0')) + // 带0,且与前面的组合不能够小于26,类似于'00'或者'30'这种 + return 0; + else if (problem[i] == '0' && problem[i - 1] < '3') + // 带0,且与前面的组合能够小于26,类似于'20'这种 + result[i] = result[i - 2]; + else if (problem[i - 1] != '0' && problem[i] + problem[i - 1] * 10 <= 554) + // 不带0,且与前面的组合能够小于26 + result[i] = result[i - 1] + result[i - 2]; + else + // 不带0,且与前面的组合不能够小于26 + result[i] = result[i - 1]; + } + + return result[problem.length - 1]; + } +} + +``` diff --git a/_site/leetcode/091-DecodeWays/official.md b/_site/leetcode/091-DecodeWays/official.md new file mode 100644 index 0000000..7e1c57f --- /dev/null +++ b/_site/leetcode/091-DecodeWays/official.md @@ -0,0 +1,3 @@ +**91. 解码方法** +--- +[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) diff --git a/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md b/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md new file mode 100644 index 0000000..5f84f3a --- /dev/null +++ b/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md @@ -0,0 +1,82 @@ +**095.UniqueBinarySearchTreesII** +--- +[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) + +方法一:动态规划+递归 +对于二叉搜索树,其左子树中的所有节点的值都小于根节点,右子树的所有节点的值都大于根节点。因此,该问题可以转为 +* 对于从1到n的序列A={1...n},求以i为根节点的所有二叉搜索树集合(其中,i>=1 且 i<=n)。 + +设以i为根节点的所有二叉树集合为F(i),很显然,F(i)的结果为:`{1...i-1}的可能BTS集合`和`{i+1...n}的可能BTS集合`的`笛卡尔积`。此时,这个问题又回归到了初始问题(求1到n的BTS集合)。这种再次回归到初始问题的就可以采用递归的办法解决。 + +当然,该问题经过不断递归是有解的。因为不断的递归之后,问题域的size是逐渐减小的。当size==1的时候,问题是可解的(此时,集合只有一个节点,所有的BTS组合唯一)。 + +综上,dp思路为: +设`F(start, end)`表示从start到end序列的所有BTS可能性的集合。则 `F(start, end)={ F(start, i-1) × F(i+1, end) | i属于{1, ... ,n} }`,此处`×`表示笛卡尔积。 + +```java +class Solution { + public List generateTrees(int n) { + // 测试用例中存在n=0的情况 + if (n <= 0) + return new ArrayList(); + + return getTrees(1, n); + } + + /** + * 获取从start到end的所有二叉搜索树集合 + * @param start 起始位置 + * @param end 终点位置 + * @return 从start到end之间的所有Tree组合的集合 + */ + private List getTrees(int start, int end) { + + List list = new LinkedList(); + + // 若上层递归root结点该方向无节点,则递归到此处 + if (start > end) { + list.add(null); + return list; + } + + // 若上层递归root结点该方向存在一个结点,则递归到此处 + // 这一步是可以省略的, + // 因为当start==end的时候,后面的循环递归的逻辑与该处逻辑等价 + // 这里提前返回,避免再次进入start>end的递归 + if (start == end) { + list.add(new TreeNode(start)); + return list; + } + + List leftNodeList, rightNodeList; + for (int i = start; i <= end; i++) { + // 获取start到i-1的所有二叉搜索树 + leftNodeList = getTrees(start, i - 1); + // 获取i+1到end的所有二叉搜索树 + rightNodeList = getTrees(i + 1, end); + // 获取到当根节点为i的左二叉搜索树和右二叉搜索树的所有情况 + // 遍历左BST与右BST组合的所有情况, + // 将所有情况都与root结合为一个二叉搜索树 + for (TreeNode leftNode : leftNodeList) { + for (TreeNode rightNode : rightNodeList) { + TreeNode root = new TreeNode(i); + root.left = leftNode; + root.right = rightNode; + list.add(root); + } + } + } + + return list; + } +} + +``` + +--- + + +**参考资料** + +* 官方题解: +[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) diff --git a/_site/leetcode/095-UniqueBinarySearchTreesII/official.md b/_site/leetcode/095-UniqueBinarySearchTreesII/official.md new file mode 100644 index 0000000..ad28ab8 --- /dev/null +++ b/_site/leetcode/095-UniqueBinarySearchTreesII/official.md @@ -0,0 +1,3 @@ +**95. 不同的二叉搜索树 II** +--- +[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) diff --git a/_site/leetcode/096-uniqueBinarySearchTrees/official.md b/_site/leetcode/096-uniqueBinarySearchTrees/official.md new file mode 100644 index 0000000..0c96b15 --- /dev/null +++ b/_site/leetcode/096-uniqueBinarySearchTrees/official.md @@ -0,0 +1,3 @@ +**96. 不同的二叉搜索树** +--- +[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) diff --git a/_site/leetcode/097-InterleavingString/official.md b/_site/leetcode/097-InterleavingString/official.md new file mode 100644 index 0000000..a9c0de4 --- /dev/null +++ b/_site/leetcode/097-InterleavingString/official.md @@ -0,0 +1,3 @@ +**97. 交错字符串** +--- +[https://leetcode-cn.com/problems/interleaving-string/](https://leetcode-cn.com/problems/interleaving-string/) diff --git a/_site/leetcode/098-validateBinarySearchTree/BambooYH.md b/_site/leetcode/098-validateBinarySearchTree/BambooYH.md new file mode 100644 index 0000000..c57425e --- /dev/null +++ b/_site/leetcode/098-validateBinarySearchTree/BambooYH.md @@ -0,0 +1,47 @@ +**98 判断叉查找树是否有效** +--- +[https://leetcode.com/problems/validate-binary-search-tree/](https://leetcode.com/problems/validate-binary-search-tree/) + +解决方案: +方法一:**栈、中序遍历** +**思路** +首先,我们要知道二叉搜索树的特点。 +- 若左子树不为空,则左子树节点值小于根节点的值 +- 若右字树不为空,则右字树节点值大于根节点的值 +- 任意节点的左右字树也为二叉搜索树 +- 没有键值相等的节点 +- [参考wiki](https://zh.wikipedia.org/zh-cn/%E4%BA%8C%E5%85%83%E6%90%9C%E5%B0%8B%E6%A8%B9) + +所以了解了二叉搜索树的特点之后,我们可以知道,中序遍历二叉搜索树,得到的是一个递增的序列。所以此题只需进行中序遍历,判断是否是一个递增序列就可以了。 +**算法** +采用非递归的方式进行中序遍历,在遍历的过程中,判断是否是一个递增的序列,如果不是,则返回false +**代码** +``` +class Solution { + public boolean isValidBST(TreeNode root) { + if(root == null) + return true; + Stack stack = new Stack(); + TreeNode pre = null; + while(root != null || !stack.isEmpty()) { //当左子节点存在的时候,将左子节点加入栈中 + while(root != null) { + stack.push(root); + root = root.left; + } + //弹出栈顶节点 + root = stack.pop(); + //如果当前节点小于等于前一个节点的值,则返回false + if(pre != null && root.val <= pre.val) + return false; + //将pre指向当前节点 + pre = root; + //继续遍历当前节点的右子节点 + root = root.right; + } + return true; + } +} +``` +复杂度分析 +空间复杂度:O(h),h表示当前树的树高,最坏情况下为n,平均为logn +时间复杂度:O(n), 当前树的节点的总数 diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md new file mode 100644 index 0000000..38bbe84 --- /dev/null +++ b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md @@ -0,0 +1,121 @@ +**二叉树的层序遍历** +--- +https://leetcode.com/problems/binary-tree-level-order-traversal/ + +其实二叉树层序遍历本身不难,只需一个队列,不断从根节点插入,然后弹出队列,并把其孩子节点再插入即可。你只要保证了从根->下的顺序,从左—>右的顺序,即就保证了层序。空想很难,不妨自己画个简单的二叉树,演练一遍即可。 +**难点在于如何使得按行打印呢**,也就说打印顺序不变,但是要把属于一行的节点放在一起。 + +### 思路一 +还是借助队列,只不过我们每次弹出时,都会记录下当前队列的长度。为什么这样做呢?因为当前长度正是这一层所有的节点数,然后我们再把其他们的所有的孩子节点加入队列,同样下一次弹出时,记录下队列长度,这时又是当前层的节点数。 + +以上的技巧需要你从根节点开始保证: +1. 根节点入队列 +2. 记录当前队列的长度,为1,当前层为1个节点 +3. 开始加入根节点左右孩子 +4. 记录当前队列的长度,为2,当前层为2个节点 +5. 开始加入他们的左右孩子 +6. 一直到队列为空 + +```java + /** + * 最不费脑的一个方法,推荐 + * @param root + * @return + */ + public List> levelOrder1(TreeNode root) { + List> result = new LinkedList<>(); + Queue queue = new LinkedList<>(); + if (root == null) { + return result; + } + queue.offer(root); + while (!queue.isEmpty()) { + int size = queue.size(); + List level = new LinkedList<>(); + while (size-- > 0) { + TreeNode node = queue.poll(); + level.add(node.val); + if (node.left != null) { + queue.offer(node.left); + } + if (node.right != null) { + queue.offer(node.right); + } + } + result.add(level); + } + return result; + } +``` + +#### 思路二 +双指针法。 +last指向当前层最后一个,nLast指向下一层最后一个。 +当队列弹出的节点等于last时,说明当前层遍历完毕,这时需更新last为nLast的层。 +nLast的更新则只需在添加孩子时,更新它即可,因为这些操作都是设计到下一层。 +```java + /** + * 双指针法 + * @param root + * @return + */ + public List> levelOrder2(TreeNode root) { + List> result = new LinkedList<>(); + Queue queue = new LinkedList<>(); + if (root == null) { + return result; + } + queue.offer(root); + TreeNode last = root, nLast = null; + List level = new LinkedList<>(); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + level.add(node.val); + if (node.left != null) { + queue.offer(node.left); + nLast = node.left; + } + if (node.right != null) { + queue.offer(node.right); + nLast = node.right; + } + if (node == last) { + last = nLast; + result.add(level); + level = new LinkedList<>(); + } + } + return result; + } +``` + +### 思路三 +DFS,我们都知道层次遍历最符合BFS的方式。但就要是搞事情,此解法来自评论区。 +我们DFS时,会带上树高,若存放本层的节点的容器未创建,则创建,否则直接插入。DFS的遍历保证了同一层的左边的节点先于右边的节点。 +所以从根节点到叶子节点的过程中,各个节点是插入到不同层的容器里。 +```java + /** + * DFS 版 + * @param root + * @return + */ + public List> levelOrder3(TreeNode root) { + List> result = new ArrayList>(); + levelHelper(result, root, 0); + return result; + } + + public void levelHelper(List> result, TreeNode node, int height) { + if (node == null) { + return; + } + if (height >= result.size()) { + result.add(new LinkedList<>()); + } + result.get(height).add(node.val); + levelHelper(result, node.left, height + 1); + levelHelper(result, node.right, height + 1); + } +``` + +参考:https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS \ No newline at end of file diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md new file mode 100644 index 0000000..ec6f741 --- /dev/null +++ b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md @@ -0,0 +1,42 @@ +**二叉树的层序遍历** +--- +[https://leetcode.com/problems/binary-tree-level-order-traversal/](https://leetcode.com/problems/binary-tree-level-order-traversal/) + +解决方案 +**思路** + 使用广度优先探索,使用队列。 + 若根节点为空,直接返回; + 否则将根节点入队,然后,判断队列是否为空,若不为空,则将队首节点出队,访问,并判断其左右子节点是否为空,若不为空,则压入队列。 + +``` +class Solution{ + List> res=new ArrayList(); + public List> levelOrder(TreeNode root) { + if(root==null) return res; //边界条件 + Queue q=new LinkedList(); //创建的队列用来存放结点,泛型注意是TreeNode + q.add(root); + while(!q.isEmpty()){ //队列为空说明已经遍历完所有元素,while语句用于循环每一个层次 + int count=q.size(); + List list=new ArrayList(); + while(count>0){ //遍历当前层次的每一个结点,每一层次的Count代表了当前层次的结点数目 + TreeNode temp=q.peek(); + q.poll(); //遍历的每一个结点都需要将其弹出 + list.add(temp.val); + if(temp.left!=null)q.add(temp.left); //迭代操作,向左探索 + if(temp.right!=null)q.add(temp.right); + count--; + } + res.add(list); + } + return res; + + } +} + +``` +**复杂度分析** +时间复杂度:O(NlogN) +空间复杂度:O(N+M) + +**参考资料** + [https://www.cnblogs.com/patatoforsyj/p/9496127.html](https://www.cnblogs.com/patatoforsyj/p/9496127.html) diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md new file mode 100644 index 0000000..570e750 --- /dev/null +++ b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md @@ -0,0 +1,4 @@ +**102. 二叉树的层次遍历** +--- + +[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md new file mode 100644 index 0000000..e47ef89 --- /dev/null +++ b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md @@ -0,0 +1,42 @@ +#### 二叉树的层次遍历 + +https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ + +**思路**: + +层次遍历需要借助队列这样一个辅助的数据结构. + +1.题目给出从左到右访问节点,自然想到的就是BFS,广度优先搜索。每个节点访问且仅访问一次。所以时间复杂度是O(N),根节点先入队列,然后队列不空,取出头元素, +如果左孩子存在就入队列,否则什么都不做,右孩子同理。直到队列为空,则表示树层次遍历结束。 + +2.深度优先搜索DFS,也可以做。但是最好还是BFS + +代码:(BFS) + +``` +class Solution: + def levelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + if not root: + return [] #若根节点为空,则返回空列表 + result = [] #模拟一个队列存储节点 + queue = collections.deque() #双端队列 + queue.append(root) #首先将根节点入队 + + while queue: + level_size = len(queue) #记录同层节点的个数 + current_level = [] #使用列表来存储同层节点 + + for _ in range(level_size): + node = queue.popleft() #将同层节点依次出队 + current_level.append(node.val) + if node.left: queue.append(node.left) #非空左孩子入队 + if node.right: queue.append(node.right) #非空右孩子入队 + result.append(current_level) + return result +``` + +时间复杂度是O(N) diff --git a/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md b/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md new file mode 100644 index 0000000..37730bb --- /dev/null +++ b/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md @@ -0,0 +1,100 @@ +**051. 二叉树的最大深度** +--- +[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) + +方法一:递归 +采用深度优先搜索递归的方式计算最大长度。 + +```java +public class Solution { + public int maxDepth(TreeNode root) { + // 判断当前结点是否为空 + if (root == null) { + // 若为空,则返回长度0 + return 0; + } else { + // 若不为空,则深度优先搜索 + + // 先递归获取左子树的最大长度, + int left_height = maxDepth(root.left); + // 递归获取右子树的最大长度 + int right_height = maxDepth(root.right); + + // 返回当前左右子树中最大的长度+1,加一是为了将自己的长度也算上 + return java.lang.Math.max(left_height, right_height) + 1; + } + } +} + +// 二叉树的定义 +class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } +} + +``` + +**复杂度分析** + +时间复杂度: +O(n)。每个节点只访问一次,所以为O(n)。 + +空间复杂度: +最差的情况,即树的高度即为节点个数,则递归N次,因此是O(n)。最好的情况即完全平衡,树的高度将是log(N),此时空间复杂度为O(log(N))。 + +方法二:迭代 + +依旧是深度优先搜索,使用栈来代替递归。两者区别是,递归计算深度是递归结束回溯阶段通过加一来更新深度;迭代计算深度是每访问到一个节点就更新一次深度。 + +```java + +public class Solution { + public int maxDepth(TreeNode root) { + // 声明栈,栈中存入KV,其中key是节点,value是当前节点的深度 + Queue> stack = new LinkedList<>(); + // 若当前节点不为空则入栈 + if (root != null) { + // 根节点入栈,深度为1 + stack.add(new Pair(root, 1)); + } + + // 需要确定的二叉树的最大深度, + // 通过不断和每个节点的深度比较来确定二叉树的最大深度 + int depth = 0; + while (!stack.isEmpty()) { + // 出栈 + Pair current = stack.poll(); + // 获取出栈的节点 + root = current.getKey(); + // 获取出栈节点的深度 + int currentDepth = current.getValue(); + if (root != null) { + // 比较深度大小,更新二叉树的深度 + depth = Math.max(depth, currentDepth); + // 左子节点入栈 + stack.add(new Pair(root.left, currentDepth + 1)); + // 右子节点入栈 + stack.add(new Pair(root.right, currentDepth + 1)); + } + } + return depth; + } +} + +``` + +--- + + +**参考资料** + +* 官方中文题解: +[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) + +* 官方英文题解: +[https://leetcode.com/articles/maximum-depth-of-binary-tree/](https://leetcode.com/articles/maximum-depth-of-binary-tree/) diff --git a/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md b/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md new file mode 100644 index 0000000..ff5f1f6 --- /dev/null +++ b/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md @@ -0,0 +1,4 @@ +**104. 二叉树的最大深度** +--- + +[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) diff --git a/_site/leetcode/115-DistinctSubsequences/official.md b/_site/leetcode/115-DistinctSubsequences/official.md new file mode 100644 index 0000000..7e9fb1c --- /dev/null +++ b/_site/leetcode/115-DistinctSubsequences/official.md @@ -0,0 +1,4 @@ +**115. 不同的子序列** +--- + +[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) diff --git a/_site/leetcode/120-Triangle/melody-l.md b/_site/leetcode/120-Triangle/melody-l.md new file mode 100644 index 0000000..806e1f1 --- /dev/null +++ b/_site/leetcode/120-Triangle/melody-l.md @@ -0,0 +1,59 @@ +**120. Triangle** + +--- +[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) + +* 该问题如果从上到下的角度考虑,即求从根节点到每一个(i, j)的最短路径。 +令F(i,j)表示从根节点开始到(i,j)的最短路径,A(i,j)表示当前位置的值,则 +F(i,j) = min{F(i-1,j), F(i-1,j-1)} + A(i,j) (其中,若i<0或j<0,则F(i,j)=0) + +* 该问题如果从下往上考虑,即求从底部到以该结点(i,j)为根节点的最短路径。 +令F(i,j)表示从底部节点到以该结点(i,j)为根节点的最短路径,则 +F(i,j) = min{F(i+1,j), F(i+1, j+1)} + A(i,j) + +* 所以,若问题求从顶部到底端每个节点的最短路径,则从上到下考虑;若问题求全局唯一路径,则采用从下往上考虑;因此,该问题采用由下到上的递推式。 + +--- + +方法一:从下往上考虑: +这里只是用了一个int[rowSize]的大小进行存储。以leetcode中的例子来简单描述一下思路: +1. 先存储最后一行[4,1,8,3] +2. 逆序遍历,以6(3,1)为根节点,从4(4,1)与1(4,2)中选择最小值,因此选择1(4,2); +3. 选择1(4,2)后,加上自己的值,存储到[4,1,8,3]的第一个位置中,原因是对于第一个位置,只有6(3,1)会用到,5(3,2)需要比较的是(4,2)和(4,3) +4. 依次类推,倒数第二行遍历完,数列为[7,6,10, 3] +5. 同理,倒数三行遍历完,数列为[9,10, 10,3] +6. 第一行,数列为[11, 10,10,3] +7. 第一个即为最终结果。 + +```java + +public class Solution { + //从下层往上层递推 + public int minimumTotal(List> triangle) { + int row = triangle.size(); // 获得行数,其中行数与最后一行的个数相等 + int[] result = new int[row]; // 因为行数与最后一行个数一致,所以直接使用row,无需重复计算 + + for (int i = 0; i < row; i++) { + result[i] = triangle.get(row - 1).get(i);// 先将最后一行赋值给结果序列 + } + + for (int i = row - 2; i >= 0; i--) { // 从倒数第二行(row-2)开始,往上层,逐行遍历,遍历至第0层,因此边界为i>=0 + for (int j = 0; j < i + 1; j++) { // 遍历当前行;当前行的数据个数与 i+1 是相等的,因此此处边界为 j maxprofit) + //将新的最大利润缓存 + maxprofit = profit; + } + } + //返回一次交易能获得的最大利润 + return maxprofit; + } + +``` + +**复杂度分析** + +时间复杂:O(n^2), +本解法使用了嵌套循环, +内循环的迭代次数随着外循环控制变量i的递增而递减, +即内循环的迭代次数是(n-1)+...+2+1 = ((n-1)+1)/2, +外循环遍历数组一次,时间复杂度是n, +所以总的时间复杂度是n*((n-1)+1)/2 = n^2/2, +消去常数系数1/2,最终时间复杂度是O(n^2) + +空间复杂度:O(1), +只使用了两个变量maxprofit和profit, +空间复杂度为O(1) + +--- + +* 官方题解2:峰谷法一次遍历 + +```java + + /** + * https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/ + * 官方解法2:峰谷法 + * + * @param prices + * @return + */ + public int maxProfit2(int prices[]) { + //定义一个最低买入价格minprice,默认值为Integer的取值上限 + int minprice = Integer.MAX_VALUE; + //定义一个最大利润maxprofit,默认值为0 + int maxprofit = 0; + //遍历价格数组prices + for (int i = 0; i < prices.length; i++) { + //当价格小于最低买入价格minprice时 + if (prices[i] < minprice) + //prices[i]缓存到minprice + minprice = prices[i]; + //prices[i] - minprice得到第i天卖出时的利润 + else if (prices[i] - minprice > maxprofit) + //如果利润大于最大利润maxprofit,将其缓存到maxprofit + maxprofit = prices[i] - minprice; + } + //返回最大利润 + return maxprofit; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +遍历了数组一次 + +空间复杂度:O(1), +只使用了minprice和maxprofit两个整数变量 + +--- + +**参考资料** + +* 官方题解: +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) diff --git a/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md b/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md new file mode 100644 index 0000000..43c034a --- /dev/null +++ b/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md @@ -0,0 +1,4 @@ +**121. 买卖股票的最佳时机** +--- + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) diff --git a/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md b/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md new file mode 100644 index 0000000..0a7e542 --- /dev/null +++ b/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md @@ -0,0 +1,52 @@ +**最佳时机买卖股票2** +---- +https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + +### 思路一 +题目的意思是不限买卖股票的次数,并且每次买股票的时候必须在上一股卖出之后,在此基础上求出最大利润。 +我们只需求出所有的有序段的差值之和即可。遍历数组,找到第一个高峰,然后计算高峰与低谷的差值,更新新的低谷,然后再继续寻找下一个高峰,累加差值即可。 +**你必然有这样的疑问,我找到高峰之后,可能后面还有更高的峰,我为什么非的此时再卖而不是在更高的峰卖呢?这样真的能达到最大值吗**? + +你这样想,你当前的高峰后面是另一个低谷,这个差值就是你分开买比一次性买到最高峰的多出来的部分啊,也就是重叠部分。如果你直接从低谷买到最高峰,那么这个差值你是赚不到。而你每一个低谷到第一个高峰都买卖啊,这个额外的差值你都赚到了。 + +![image](https://leetcode.com/media/original_images/122_maxprofit_1.PNG) +A + B > C,对吧 +```java + public int maxProfit1(int[] prices) { + int result = 0; + int low = 0; + int len = prices.length; + for (int i = 0; i < len; i++) { + //寻找当前碰到第一个高峰 + if (i + 1 == len || prices[i] >= prices[i + 1]) { + result += prices[i] - prices[low]; + //更新低谷 + low = i + 1; + } + } + return result; + } +``` + +### 思路二 +还是看上图,既然我们求的是所有的有序段的差值和,那么我们也可以不必每次都求出这个段区间后再求和。而是从小事做起,只要第二天比第一天高,我们就买卖。意味着我们不用考虑具体的有序段是什么,只需关注当前是有序,我们就累加利润即可。类似爬坡的过程,通过累加求出上图的中A的利润。 + +```java + /** + * 一阶段 + * 累加所有的增值即可 + * @param prices + * @return + */ + public int maxProfit2(int[] prices) { + int result = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + result += prices[i] - prices[i - 1]; + } + } + return result; + } +``` +参考: +- https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/ \ No newline at end of file diff --git a/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md b/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md new file mode 100644 index 0000000..9f2750e --- /dev/null +++ b/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md @@ -0,0 +1,141 @@ +**122. 买卖股票的最佳时机 II** +--- +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) + +* 官方题解1:暴力法 + +```java + + public int maxProfit(int[] prices) { + return calculate(prices, 0); + } + + public int calculate(int prices[], int s) { + //s是遍历起始的下标,如果超过数组长度直接返回0 + if (s >= prices.length) + return 0; + //定义一个最大值缓存max + int max = 0; + //外循环从起始位置起遍历元素 + for (int start = s; start < prices.length; start++) { + //定义最大利润的缓存maxprofit + int maxprofit = 0; + //i = start + 1,内循环从起始位置的第二天开始 + for (int i = start + 1; i < prices.length; i++) { + //如果当前价格大于起始位置的价格 + if (prices[start] < prices[i]) { + //prices[i] - prices[start]得到在start天买入,第i天卖出所获利润 + //因为在第i天卖出了,所以尝试在第i+1天买入 + //calculate(prices, i + 1)递归调用,得到在i+1天开始持有所能获得的最大利润 + //经过递归,profit获得的就是在第i天卖出到最后一天为止所能获得的最大利润 + int profit = calculate(prices, i + 1) + prices[i] - prices[start]; + //如果利润profit大于内循环已知的最大利润 + if (profit > maxprofit) + //将利润profit赋值给内循环最大利润maxprofit + maxprofit = profit; + } + } + //如果最大利润maxprofit大于外循环最大利润缓存max + if (maxprofit > max) + //将最大利润maxprofit赋值给max + max = maxprofit; + } + //最终返回以s天为起点的交易组合中最大利润 + return max; + } + +``` + +**复杂度分析** + +时间复杂度:O(n^n), +共调用递归n^n次 + +空间复杂度:O(n), +每递归一次占用O(1)的空间复杂度, +递归函数的调用在内循环中,最大深度是n, +所以空间复杂度是O(n) + +--- + +* 官方题解2:峰谷法 + +```java + + public int maxProfit(int[] prices) { + //定义数组的起始位置 + int i = 0; + //定义一个谷值valley + int valley = prices[0]; + //定义一个峰值peak + int peak = prices[0]; + //定义一个最大利润 + int maxprofit = 0; + //从头遍历数组 + while (i < prices.length - 1) { + //prices[i] >= prices[i + 1] 只要当天的价格大于或等于次日的价格,就一直递增 + while (i < prices.length - 1 && prices[i] >= prices[i + 1]) + i++; + //当prices中元素不满足prices[i] >= prices[i + 1]时,即prices[i] < prices[i + 1] + //说明prices[i]是最近的谷底 + valley = prices[i]; + //继续遍历,用同样的手法找到峰值 + while (i < prices.length - 1 && prices[i] <= prices[i + 1]) + i++; + peak = prices[i]; + //最大利润是峰值和谷底的差值 + //+=将所有差值不断累加,得到了最大利润总和 + maxprofit += peak - valley; + } + //返回最大利润 + return maxprofit; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +遍历一次,虽然嵌套了while循环,但是使用同一个控制变量, +最终只遍历了数组一次 + +空间复杂度:O(1), +需要常量的空间 + +--- + +* 官方题解3:一次遍历法 + +```java + + public int maxProfit(int[] prices) { + //定义一个最大利润变量maxprofit + int maxprofit = 0; + //变量价格数组 + for (int i = 1; i < prices.length; i++) { + //如果当天价格高于前一天价格 + if (prices[i] > prices[i - 1]) + //当天价格减去前一天价格,得到利润 + //maxprofit累加当天所得利润 + maxprofit += prices[i] - prices[i - 1]; + } + //最终返回的maxprofit是所有利润总和 + return maxprofit; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +遍历数组一次 + +空间复杂度:O(1), +需要常量空间 + +--- + +**参考资料** + +* 官方题解: +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) \ No newline at end of file diff --git a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md new file mode 100644 index 0000000..1c5bed7 --- /dev/null +++ b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md @@ -0,0 +1,106 @@ +**123.买卖股票的最佳时机 III** +--- +https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ + +### 思路一 +这个题是典型的动态规划问题,这里题目虽然说的要求最多购买2次,那么我们可以拓展一下,提出最多购买k次的最大值。 +主要有以下状态转移方程: +```math +dp[k][i] = max(dp[k][i - 1], dp[k - 1][j] + prices[i] - prices[j] ( j in [0, i - 1])) + +dp[k][i] = max(dp[k][i - 1], prices[i] + max(dp[k - 1][j] - prices[j] ( j in [0, i - 1]))) +``` +dp[k][i]表示第k次交易截止到第i天最大的收益,它等于第k次交易截止到第i - 1天最大的收益和第k次交易截止到第j天并且我在第j天重新买了一张,第i天卖掉的最大值。 +注意到上式中`max(dp[k - 1][j] - prices[j] ( j in [0, i - 1]))`会重复计算,所以这里我们只需在遍历时维护一个关于dp[k - 1][j] - prices[j] ( j in [0, i - 1])的最大值即可。 + +```java + /** + * + * dp[k][i] = max(dp[k][i - 1], dp[k - 1][j] + prices[i] - prices[j] ( j in [0, i - 1])) + * = max(dp[k][i - 1], prices[i] + max(dp[k - 1][j] - prices[j]) + * @param prices + * @return + */ + public int maxProfit4(int[] prices) { + if (prices == null || prices.length == 0) { + return 0; + } + int totalK = 2; + int[][] dp = new int[totalK + 1][prices.length]; + for (int k = 1; k <= totalK; k++) { + int maxProfit = - Integer.MIN_VALUE; + for (int i = 1; i < prices.length; i++) { + maxProfit = Math.max(maxProfit, dp[k - 1][i - 1] - prices[i - 1]); + dp[k][i] = Math.max(dp[k][i - 1], prices[i] + maxProfit); + } + } + return dp[totalK][prices.length - 1]; + } +``` +### 思路二 +思路二的状态方程引入冗余,为了之后的简化: +```math +dp[k][i] = max(dp[k][i - 1], dp[k - 1][j - 1] + prices[i] - prices[j] ( j in [0, i])) + +dp[k][i]= max(dp[k][i - 1], prices[i] + max(dp[k - 1][j - 1] - prices[j]) ( j in [0, i]) +``` +其中j可以取到i,意思是我们当天买,当天卖,引入这样的情况只不过是为了后续简化方便,这里我们把K放到了内循环,所以要用max来存放k不同时维护的最大值。 +```java + public int maxProfit5(int[] prices) { + if (prices == null || prices.length == 0) { + return 0; + } + int totalK = 2; + int[][] dp = new int[totalK + 1][prices.length]; + int[] max = new int[totalK + 1]; + Arrays.fill(max, - prices[0]); + for (int i = 1; i < prices.length; i++) { + for (int k = 1; k <= totalK; k++) { + max[k] = Math.max(max[k], dp[k - 1][i - 1] - prices[i]); + dp[k][i] = Math.max(dp[k][i - 1], prices[i] + max[k]); + } + } + return dp[totalK][prices.length - 1]; + } +``` + +又因为dp只依赖i - 1,所以可以压缩状态为: +```java + public int maxProfit6(int[] prices) { + if (prices == null || prices.length == 0) { + return 0; + } + int totalK = 2; + int[] dp = new int[totalK + 1]; + int[] max = new int[totalK + 1]; + Arrays.fill(max, Integer.MIN_VALUE); + for (int i = 0; i < prices.length; i++) { + for (int k = 1; k <= totalK; k++) { + //注意这里为什么可以直接dp[k - 1] - prices[i]呢? + max[k] = Math.max(max[k], dp[k - 1] - prices[i]); + dp[k] = Math.max(dp[k], prices[i] + max[k]); + } + } + return dp[totalK]; + } +``` +答:当k = 1, dp[k - 1] = 0, 对应的第一次买;当k = 2, dp[k - 1] 其实是dp[1][i],也就说我第一次买,截止到i天取得最大值,虽然这里减去- prices[i],后面会prices[i]抵消掉。这就是思路二的独特,思路一是无法这么化简的。 + +展开: +``` + public int maxProfit3(int[] prices) { + int buy1 = Integer.MIN_VALUE; + int buy2 = Integer.MIN_VALUE; + int sell1 = 0; + int sell2 = 0; + for (int price : prices) { + buy1 = Math.max(buy1, - price); + sell1 = Math.max(sell1, price + buy1); + buy2 = Math.max(buy2, sell1 - price); + sell2 = Math.max(sell2, buy2 + price); + } + return sell2; + } +``` + +参考:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution \ No newline at end of file diff --git a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md new file mode 100644 index 0000000..f205eb8 --- /dev/null +++ b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md @@ -0,0 +1,4 @@ +**123. 买卖股票的最佳时机 III** +--- + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) diff --git a/_site/leetcode/131-PalindromePartitioning/official.md b/_site/leetcode/131-PalindromePartitioning/official.md new file mode 100644 index 0000000..9dfc49f --- /dev/null +++ b/_site/leetcode/131-PalindromePartitioning/official.md @@ -0,0 +1,3 @@ +**131. 分割回文串** +--- +[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) diff --git a/_site/leetcode/132-PalindromePartitioningII/official.md b/_site/leetcode/132-PalindromePartitioningII/official.md new file mode 100644 index 0000000..e57bb22 --- /dev/null +++ b/_site/leetcode/132-PalindromePartitioningII/official.md @@ -0,0 +1,3 @@ +**132. 分割回文串 II** +--- +[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) diff --git a/_site/leetcode/139-WordBreak/official.md b/_site/leetcode/139-WordBreak/official.md new file mode 100644 index 0000000..62dd24b --- /dev/null +++ b/_site/leetcode/139-WordBreak/official.md @@ -0,0 +1,3 @@ +**139. 单词拆分** +--- +[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) diff --git a/_site/leetcode/140-WordBreakII/official.md b/_site/leetcode/140-WordBreakII/official.md new file mode 100644 index 0000000..d2a3ae5 --- /dev/null +++ b/_site/leetcode/140-WordBreakII/official.md @@ -0,0 +1,3 @@ +**140. 单词拆分 II** +--- +[https://leetcode-cn.com/problems/word-break-ii/](https://leetcode-cn.com/problems/word-break-ii/) diff --git a/_site/leetcode/141-linkedListCycle/official.md b/_site/leetcode/141-linkedListCycle/official.md new file mode 100644 index 0000000..4ec772f --- /dev/null +++ b/_site/leetcode/141-linkedListCycle/official.md @@ -0,0 +1,62 @@ +**141. 环形链表** +--- +[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) + +方法一:哈希表 +思路 + +我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。 + +常用的方法是使用哈希表。 + +算法 + +我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。 + +如果当前结点为空结点 null(即已检测到链表尾部的下一个结点), + +那么我们已经遍历完整个链表,并且该链表不是环形链表。 + +如果当前结点的引用已经存在于哈希表中,那么返回 true(即该链表为环形链表)。 + +```java + +public boolean hasCycle(ListNode head) { + //新建一个set用于存储从链表中遍历出的结点 + Set nodesSeen = new HashSet<>(); + //如果当前结点不为空,循环继续 + while (head != null) { + //set中如果已经存在当前结点,说明该链表是环形链表,返回true + if (nodesSeen.contains(head)) { + return true; + } else { + //否则将当前结点添加到set + nodesSeen.add(head); + } + //将下一个结点赋值给结点缓存head + head = head.next; + } + //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false + return false; +} + +``` + +**复杂度分析** + +时间复杂度: +O(n), 对于含有 n个元素的链表,我们访问每个元素最多一次。 添加一个结点到哈希表中只需要花费 O(1) 的时间。 + +空间复杂度: +O(n), 空间取决于添加到哈希表中的元素数目,最多可以添加 n 个元素。 + +--- + + +**参考资料** + +* 本题leetCode官方题解: +[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/142-linkedListCycleII/bigablecat.md b/_site/leetcode/142-linkedListCycleII/bigablecat.md new file mode 100644 index 0000000..439a91c --- /dev/null +++ b/_site/leetcode/142-linkedListCycleII/bigablecat.md @@ -0,0 +1,3 @@ +**142. 环形链表 II** +--- +[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/142-linkedListCycleII/official.md b/_site/leetcode/142-linkedListCycleII/official.md new file mode 100644 index 0000000..439a91c --- /dev/null +++ b/_site/leetcode/142-linkedListCycleII/official.md @@ -0,0 +1,3 @@ +**142. 环形链表 II** +--- +[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/146-lruCache/hatrick.md b/_site/leetcode/146-lruCache/hatrick.md new file mode 100644 index 0000000..6bf15ca --- /dev/null +++ b/_site/leetcode/146-lruCache/hatrick.md @@ -0,0 +1,98 @@ +**146. LRU缓存机制** +--- +[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) + +**思路** +由于LRU缓存插入和删除操作频繁,使用双向链表维护缓存节点, + +“新节点”:凡是被访问(新建/修改命中/访问命中)过的节点,一律在访问完成后移动到双向链表尾部, +保证链表尾部始终为最“新”节点; +“旧节点”:保证链表头部始终为最“旧”节点,LRU策略删除时表现为删除双向链表头部; +从链表头部到尾部,节点访问热度逐渐递增,由于链表不支持随机访问,使用HashMap+双向链表实现LRU缓存; + +HashMap中键值对: + +双向链表:维护缓存节点Node +```java + class LRUCache { + private int capacity; + private HashMap caches; + private Node first; + private Node last; + + public LRUCache(int capacity) { + this.capacity = capacity; + caches = new HashMap<>(capacity); + } + + public void put(int key, int value) { + Node node = caches.get(key); + // 首先得先判断是否存在元素 + if (node == null){ + // 如果不存在,先判断容量 + if (capacity <= caches.size()) { + // 不够,先移除最后一个 + removeLast(); + } + node = new Node(); + node.key = key; + } + node.value = value; + moveNodeToFirst(node); + caches.put(key, node); + } + + private void removeLast() { + if (last != null) { + caches.remove(last.key); + // 最后 + last = last.pre; + if (last != null) { + last.next = null; + } else { + first = null; + } + } + } + + private void moveNodeToFirst(Node node) { + if (node == first || node == null) return; + // 先连接 + if (node.pre != null) { + node.pre.next = node.next; + } + if (node.next != null) { + node.next.pre = node.pre; + } + if (node == last) { + last = last.pre; + } + if (last == null || first == null) { + last = first = node; + return; + } + node.next = first; + first.pre = node; + first = node; + node.pre = null; + } + + public int get(int key) { + Node node = caches.get(key); + if (node == null) return -1; + moveNodeToFirst(node); + return node.value; + } + + } + + class Node { + Node next; + Node pre; + int key; + int value; + } +``` + +**参考资料** +[https://segmentfault.com/a/1190000009084949](https://segmentfault.com/a/1190000009084949) diff --git a/_site/leetcode/146-lruCache/official.md b/_site/leetcode/146-lruCache/official.md new file mode 100644 index 0000000..9bca4d1 --- /dev/null +++ b/_site/leetcode/146-lruCache/official.md @@ -0,0 +1,3 @@ +**146. LRU缓存机制** +--- +[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) diff --git a/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md b/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md new file mode 100644 index 0000000..e7afa20 --- /dev/null +++ b/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md @@ -0,0 +1,43 @@ +**乘积最大子序列** +--- +https://leetcode.com/problems/maximum-product-subarray/ + +典型的动态规划问题,说实话,第一次做没做出来,菜是原罪,主要卡在了判断当前最大值上面,因为乘积的特性,使得当前的不是最大值可能由于后面的负负得正从而晋升为最大值。 + +卡在上面的原因,思维一直停留在和最大子序列那道题。在那道题里,我们判断当前最大值为之前的连续最大和加上当前的数字,或者只有当前的数字,即`dp[i] = max(dp[i - 1] + num[i], num[i])`。若加上当前的值的连续和还没有只有当前值大,说明之前的连续和没有贡献,所以新的子序列要从当前值开始。 + +在乘积里就不能这么做了,因为即使乘以当前值的累积没有只有当前值大,这种情路发生在dp[i - 1]为负数,num[i]为正数时。如果仅仅按照最大连续和的做法,就会开启新的序列,前面的dp[i - 1]就会丢弃。这时如果num[i + 1]为负数,那么`dp[i - 1] * num[i] * num[i + 1]` 显然比`num[i] * num[i + 1]`大,所以我们就会丢失这个最大值。 + +牛逼的思路就是我们不仅仅要记录以当前位置结尾累积的最大值,还要记录对应的最小值,并且在访问到负数时,之前的最大值与最小值要交换一下,以便之后的正确更新。 + +记录的最大最小值,我们就可以应对各种情况了,最大值可以在遇到正数时依旧最大,遇到负数可变为最小;最小值在遇到负数翻身别为最大,遇到正数可变为最小。 + +```java + /** + * 维护已i结尾的乘积最大值,最小值 + * + * 遇到负数,交换最大最小值,因为乘以负数时,最小值会变为最大值 + * @param nums + * @return + */ + public int maxProduct2(int[] nums) { + int result = nums[0]; + for (int i = 1, min = result, max = result; i < nums.length; i++) { + //遇到负数,交换以i - 1结尾的最大值,最小值 + if (nums[i] < 0) { + int temp = min; + min = max; + max = temp; + } + max = Math.max(nums[i], max * nums[i]); + min = Math.min(nums[i], min * nums[i]); + result = Math.max(result, max); + } + return result; + } +``` +复杂度: +- 时间复杂度:遍历一遍,O(n) +- 空间复杂度:3个变量,O(1) + +参考:https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity \ No newline at end of file diff --git a/_site/leetcode/152-MaximumProductSubarray/official.md b/_site/leetcode/152-MaximumProductSubarray/official.md new file mode 100644 index 0000000..d6f0978 --- /dev/null +++ b/_site/leetcode/152-MaximumProductSubarray/official.md @@ -0,0 +1,4 @@ +**152. 乘积最大子序列** +--- + +[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) diff --git a/_site/leetcode/167-TwoSumII/bigablecat.md b/_site/leetcode/167-TwoSumII/bigablecat.md new file mode 100644 index 0000000..8565565 --- /dev/null +++ b/_site/leetcode/167-TwoSumII/bigablecat.md @@ -0,0 +1,75 @@ +**167. 两数之和 II - 输入有序数组** +--- + +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) + + +* 双指针法 + +```java + + /** + * https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution. + * 双指针法 + * + * 时间复杂度:O(N), + * 遍历数组1次 + * + * 空间复杂度:O(1), + * 只定义了一个长度为2的整型数组变量, + * 空间复杂度为O(1) + * + * @param numbers + * @param target + * @return + */ + public static int[] twoSum(int[] numbers, int target) { + //定义一个长度为2的整数数组,用于存储返回的index1和index2 + int[] indexArr = new int[2]; + //如果输入的数组numbers为空或者长度小于2,直接返回空数组indexArr + if (numbers == null || numbers.length < 2) return indexArr; + //定义整型变量index1,从numbers初始下标0开始 + int index1 = 0; + //定义整数index2,从numbers最后一个下标numbers.length - 1开始 + int index2 = numbers.length - 1; + //从下标0开始遍历数组 + for (int index = 0; index < numbers.length; index++) { + //求得下标index1和下标index2对应元素的和sum + int sum = numbers[index1] + numbers[index2]; + //查看sum是否等于目标值target + if (sum == target) { + //符合条件则跳出for循环 + break; + } + // 如果sum不等于目标值,分别对index1和index2进行增减操作 + if (sum > target) { // 当两数相加大于目标值 + //将index2递减,右移获取更小的值 + index2--; + } else if (sum < target) { // 当两数相加小于目标值 + // 将index1递增,左移获取更大的值 + index1++; + } + } + //返回的下标从1开始计数,所以index1和index2分别加1 + indexArr[0] = index1 + 1; + indexArr[1] = index2 + 1; + return indexArr; + } + +``` + +**复杂度分析** + +时间复杂度:O(N), +遍历数组1次 + +空间复杂度:O(1), +只定义了一个长度为2的整型数组变量, +空间复杂度为O(1) + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.) \ No newline at end of file diff --git a/leetcode/167-TwoSumII/official.md b/_site/leetcode/167-TwoSumII/official.md similarity index 100% rename from leetcode/167-TwoSumII/official.md rename to _site/leetcode/167-TwoSumII/official.md diff --git a/_site/leetcode/169-majorityElement/README.md b/_site/leetcode/169-majorityElement/README.md new file mode 100644 index 0000000..e268062 --- /dev/null +++ b/_site/leetcode/169-majorityElement/README.md @@ -0,0 +1,21 @@ +**169. 求众数** +--- +[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) + +给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 + +你可以假设数组是非空的,并且给定的数组总是存在众数。 + +示例 1: + +``` +输入: [3,2,3] +输出: 3 +``` + +示例 2: + +``` +输入: [2,2,1,1,1,2,2] +输出: 2 +``` diff --git a/_site/leetcode/169-majorityElement/SpecialYang.md b/_site/leetcode/169-majorityElement/SpecialYang.md new file mode 100644 index 0000000..36cde3c --- /dev/null +++ b/_site/leetcode/169-majorityElement/SpecialYang.md @@ -0,0 +1,109 @@ +**169. 求众数** +--- +[https://leetcode.com/problems/majority-element/](https://leetcode.com/problems/majority-element/) + +### 思路一 + +因为题目明确定义了众数的概念,即出现次数大于[n / 2]的数,那么**排序后的数组最中间的那个数必为众数**。 +你可能会有疑问,有序数组如果没有众数,那么中间那个数就不是众数。But,题目强调了给定的数组必有众数。 +```java + /** + * 排序法 + * @param nums + * @return + */ + public int majorityElement1(int[] nums) { + Arrays.sort(nums); + return nums[nums.length / 2]; + } +``` +#### 复杂度 +- 时间复杂度:此思路主要消耗在排序算法上,所以时间复杂度取决于你用的什么排序算法。 +- 空间复杂度:同上 + +### 思路二 +同样,众数的概念为出现次数大于n / 2次。那么就会有以下算法,俗称阵地法: +1. 一个值pivot用来表示当前出现次数超过0的数字,另一个值count表示它出现的次数 +2. 从头开始遍历数组 +3. 若保存的数字pivot的出现次数为0,那么就把pivot更新为当前的值,并且次数 + 1 +4. 若保存的数字的次数不为0,且与当前的值相等,那么次数 + 1 +5. 若保存的数字的次数不为0,且与当前的值不相等,那么次数 - 1 +6. 直到遍历完整个数组,最终pivot的值必为出现次数大于[n / 2]的数 +```java + /** + * 阵地法 + * @param nums + * @return + */ + public int majorityElement2(int[] nums) { + int pivot = 0; + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (i == 0 || count == 0) { + pivot = nums[i]; + count++; + } else if (pivot != nums[i]) { + count--; + } else { + count++; + } + } + return pivot; + } +``` +#### 复杂度 +- 时间复杂度:需要遍历一遍数组,所以O(n) +- 空间复杂度:需要哨兵和计数器,所以O(1) + +### 思路三 +众数的概念为出现次数大于n / 2次,那么数组第[n / 2]大的数必为众数。 + +基于快排的partition方法油然而生,随机选择一个哨兵,然后把所有不大于它的数全部移动到它的左边,把所有大于的数全部移动到它的右边。判断哨兵所在的索引与n / 2 的大小关系,若大于,说明中间值在左部分,按同样的逻辑递归处理左部分;若小于,说明中间值在右部分,按同样的逻辑递归处理右部分。直到相等。 +```java + /** + * 基于快排的划分 + * @param nums + * @param low + * @param high + * @param target + */ + private void partition(int[] nums, int low, int high, int target) { + if (low < high) { + int end = low + new Random().nextInt(high - low + 1); + swap(nums, end, high); + int index = low; + for (int i = low; i < high; i++) { + if (nums[i] < nums[high]) { + swap(nums, i, index); + index++; + } + } + swap(nums, index, high); + if (index < target) { + partition(nums, index + 1, high, target); + } else if (index > target) { + partition(nums, low, index - 1, target); + } + } + } + + /** + * 交换函数 + * @param nums + * @param i + * @param j + */ + private void swap(int[] nums, int i, int j) { + if (i != j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + } +``` +#### 复杂度 +- 时间复杂度:快排的partition的时间复杂度为O(n),详细证明可参考算法导论 +- 空间复杂度:尾递归,不需要额外空间,O(1) + +### 参考 +1. [剑指Offer-30-数组中出现次数超过一半的数字](https://blog.csdn.net/dawn_after_dark/article/details/81152544) \ No newline at end of file diff --git a/_site/leetcode/169-majorityElement/bigablecat.md b/_site/leetcode/169-majorityElement/bigablecat.md new file mode 100644 index 0000000..bd70016 --- /dev/null +++ b/_site/leetcode/169-majorityElement/bigablecat.md @@ -0,0 +1,153 @@ +**169. 求众数** +--- +[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) + +* 官方题解2,hashMap + +```java + + public int majorityElement(int[] nums) { + //获取通过hashMap方法得到的数组中所有元素的计数 + Map counts = countNums(nums); + //临时变量用于存储hashMap中取出的众数 + Map.Entry majorityEntry = null; + //遍历hashMap中的每一个元素 + for (Map.Entry entry : counts.entrySet()) { + //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 + if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { + //让众数临时变量等于当前元素 + majorityEntry = entry; + } + } + //经过循环,得到计数最大的值,即所求的众数 + //majorityEntry是hashMap的元素,getKey()获得众数的数字 + return majorityEntry.getKey(); + } + + private Map countNums(int[] nums) { + //创建一个HashMap对象counts用于存储已经出现过的数字 + Map counts = new HashMap(); + //遍历int数组 + for (int num : nums) { + //查看hashMap中是否已经存在当前数字 + if (!counts.containsKey(num)) { + //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 + counts.put(num, 1); + } else { + //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 + counts.put(num, counts.get(num) + 1); + } + } + //返回hashMap + return counts; + } + + +``` + +**复杂度分析** + +时间复杂度:O(n),遍历数组时间复杂度O(n), +遍历HashMap对象的所有元素时间复杂度也是O(n), +最终时间复杂度为n+n,所以是O(n) + +空间复杂度:O(n), +众数在n个元素中最少出现的次数为 2/n+1, +那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, +众数本身也是一个元素,与其他非众数元素不同, +所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 +HashMap保存这些不同的元素需要占用n/2的空间, +所以空间复杂度是O(n/2) + +--- + +* 官方题解5,递归和分治 + +```java + + public int majorityElement(int[] nums) { + return majorityElementRec(nums, 0, nums.length - 1); + } + + /** + * 递归方法 + * + * @param nums + * @param lo + * @param hi + * @return + */ + private int majorityElementRec(int[] nums, int lo, int hi) { + //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 + if (lo == hi) { + return nums[lo]; + } + + //获取数组的中位数元素下标 + // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 + // (hi - lo) / 2 + lo得到数组中间元素的下标 + int mid = (hi - lo) / 2 + lo; + //数组的左半部分从首个元素下标lo到中间元素下标mid + int left = majorityElementRec(nums, lo, mid); + //数组的右半部分从中间元素下标mid到最后一个元素下标hi + int right = majorityElementRec(nums, mid + 1, hi); + + // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 + if (left == right) { + return left; + } + + //统计左半边众数出现的总次数 + int leftCount = countInRange(nums, left, lo, hi); + //统计右半边众数出现的总次数 + int rightCount = countInRange(nums, right, lo, hi); + + //返回较大的候选众数 + return leftCount > rightCount ? left : right; + } + + + /** + * 计算候选众数在某个数组片段中出现的总次数 + * + * @param nums + * @param num + * @param lo + * @param hi + * @return + */ + private int countInRange(int[] nums, int num, int lo, int hi) { + //定义一个计时器count + int count = 0; + //遍历从下标lo到下标hi的元素 + for (int i = lo; i <= hi; i++) { + //如果获得的元素与当前传入的候选众数num相等,计数器加1 + if (nums[i] == num) { + count++; + } + } + //返回候选众数在当前数组片段中出现的总次数 + return count; + } + +``` + +**复杂度分析** + +时间复杂度 : O(nlogn), +每次递归,n就被2分一次,n/2/2... +所以总共调用递归方法的次数是logn次, +递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), +所以总的时间复杂度是n*logn + +空间复杂度:O(logn), +因为进行了logn次的递归调用, +每次递归都占用O(1)的空间复杂度, +所以最终空间复杂度为O(logn) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) diff --git a/_site/leetcode/174-DungeonGame/passself.md b/_site/leetcode/174-DungeonGame/passself.md new file mode 100644 index 0000000..e369d4c --- /dev/null +++ b/_site/leetcode/174-DungeonGame/passself.md @@ -0,0 +1,81 @@ +#174. 地下城游戏 + +Leetcode 地址 [https://leetcode-cn.com/problems/dungeon-game/](https://leetcode-cn.com/problems/dungeon-game/) + +**题目分析** + +基本一看就是动态规划的题目, 有几个前提条件一定得注意。 + +* 1.骑士的初始健康点数为一个正整数。 +* 2.如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。即无论骑士到达哪个位置健康值必须大于等于1 + +**思路:** + +* 思路一 正向递推从左上角(0,0)到(row-1,row-1),这样效率一般会比反递推效率低很多 +* 思路二 到达最后一个房间的时候健康值至少剩下1,因此可以设置最后的状态为初始状态,由后向前依次决定在每一个位置至少需要多少健康值,这样一个位置的状态是由其下面一个和和右边一个的较小状态决定 .因此一个基本的状态方程是: + +``` +int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); +int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); +dp[i][j] = Math.min(right, down); +``` +还有一个条件就是在每个房间里面的健康值都大于等于1 ```dp[i][j] = max(dp[i][j], 1)``` + +**具体代码** + +``` +public int calculateMinimumHP(int[][] dungeon) { + if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) return 0; + int m = dungeon.length; + int n = dungeon[0].length; + int[][] dp = new int[m][n]; + for (int i = m - 1; i >= 0; i--) { + for (int j = n - 1; j >= 0; j--) { + if(i==m-1 && j==n-1) {//考虑边界 + dp[i][j]=Math.max(1 - dungeon[i][j], 1); + }else if(i==m-1) { + dp[i][j]=Math.max(dp[i][j + 1] - dungeon[i][j], 1); + }else if(j==n-1) { + dp[i][j]=Math.max(dp[i + 1][j] - dungeon[i][j], 1); + }else{ + int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); + int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); + dp[i][j] = Math.min(right, down); + } + } + } + return dp[0][0]; +} +``` + +**时间复杂度** O(M*N) + +**空间复杂度** O(M*N) + +leetcode 代码提交后发现击败了26%的commit + +**第二种解法** + +用一位数组来记录数据,空间复杂度变为o(n),执行效率和速度大幅提升 + +**具体代码** + +``` +public int calculateMinimumHP(int[][] dungeon) { + int m = dungeon.length, n = dungeon[0].length; + int[] dp = new int[n + 1]; + dp[n] = 1; + for (int i = m - 1; i >= 0; i--) { + for (int j = n - 1; j >= 0; j--) { + int health = 0; + if (i == m - 1) health = dp[j + 1] - dungeon[i][j]; + else if (j == n - 1) health = dp[j] - dungeon[i][j]; + else health = Math.min(dp[j + 1], dp[j]) - dungeon[i][j]; + dp[j] = health <= 0 ? 1 : health; + } + } + return dp[0]; +} +``` + + diff --git a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md new file mode 100644 index 0000000..3122d45 --- /dev/null +++ b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md @@ -0,0 +1,44 @@ +**买卖股票的最佳时机IV** +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) +方法一:**动态规划** +**思路** +这个题是一道明显的动态规划题,跟前面几道类似的题有区别,要求最多可以进行K次交易,当然少于K次也是可以的。首先我们可以注意到一种特殊情况,就是`K > Len(array)`,在这种情况下,其实就相当于可以进行任意次交易,因为不管进行多少次交易,一定不会超过K次。 +现在来考虑普通情况,我们用dp[i][j]表示,截止到第j天,最多i次交易所获得的最大利润。dp[i][j]的大小跟两个因素有关。 +`dp[i][j] = Max(dp[i][j-1],prices[j]-prices[m] + dp[i-1][m-1])(m > 0 && m <= j-1)`.也就是`dp[i][j] = Max(dp[i][j-1],prices[j] + max(dp[i-1][m-1] - prices[m]))`.在第一个式子中,我们可以看到m是一个范围,所以我们在第二个式子中,用max来代表m不同取值的情况。首先`dp[i][j]`跟`dp[i][j-1]`有关,有可能到第j-1天,第i次交易已经取得了最大利润,后面的天数都不会超过这个利润。`dp[i][j]`还跟`dp[i-1][m-1]`有关,也就是说,到第m-1天为止,只进行了i-1次交易,第i次交易就是`prices[j]-prices[m]`.我们要做的就是找到这个最大值。 +**算法** +先处理一下特殊情况,即`K > Len(array)`的情况。然后交易次数i从1开始,一直到K。对于每次交易,从第一天开始,一直遍历到最后一天,从而得到dp[i][j]的最大值。 + +**代码** +``` + public int maxProfit(int k, int[] prices) { + int len = prices.length; + //如果K大于数组长度的一半,就相当于可以进行任意次交易,这种情况下,只要数组局部上升,差就是我们的利润。 + if (k >= len / 2) return quickSolve(prices); + //初始化数组,i表示第i次交易,j表示进行到第j天为止 + int[][] t = new int[k + 1][len]; + for (int i = 1; i <= k; i++) { + //临时的利润最大值,其实这个就是上面思路部分所说的dp[i-1][m-1] - prices[m],通过tmpMax,我们可以在遍历j的过程中,求出dp[i-1][m-1] - prices[m]的最大值 + int tmpMax = -prices[0]; + //从1开始遍历,求截止到第j天,最多i次交易能获得的最大利润。 + for (int j = 1; j < len; j++) { + //参考思路部分 + t[i][j] = Math.max(t[i][j - 1], prices[j] + tmpMax); + tmpMax = Math.max(tmpMax, t[i - 1][j - 1] - prices[j]); + } + } + return t[k][len - 1]; + } + + + private int quickSolve(int[] prices) { + int len = prices.length, profit = 0; + for (int i = 1; i < len; i++) + //如果第i天的价格大于第i-1天的价格,就是我们可以得到的利润。 + if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1]; + return profit; + } +``` +复杂度分析: +假设数组的长度为N +空间复杂度: O(KN) +时间复杂度:·O(KN) \ No newline at end of file diff --git a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md new file mode 100644 index 0000000..095a7dd --- /dev/null +++ b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md @@ -0,0 +1,4 @@ +**188. 买卖股票的最佳时机 IV** +--- + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) diff --git a/_site/leetcode/191-NumberOf1Bits/bigablecat.md b/_site/leetcode/191-NumberOf1Bits/bigablecat.md new file mode 100644 index 0000000..6fe8774 --- /dev/null +++ b/_site/leetcode/191-NumberOf1Bits/bigablecat.md @@ -0,0 +1,102 @@ +**191. 位1的个数** +--- + +[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) + +* 官方题解1:遍历32位 + +```java + + public int hammingWeight(int n) { + //计数器,统计整数n的2进制数上有多少个1 + int bits = 0; + //定义mask默认值1,用来和整数的每一位进行与运算 + int mask = 1; + //遍历整数的32位 + for (int i = 0; i < 32; i++) { + // 在二进制的位与运算中,1 & 1 = 1, 1 & 0 = 0 + // 通过 n & mask 的位与运算,判断整数n的二进制数在第i个位上是否为1 + // (n & mask) != 0 表示n的二进制数在第i个位上的数字等于1 + if ((n & mask) != 0) { + //n二进数上每出现一次1,bits就递增一次 + bits++; + } + //位运算的左移运算符<<表示将当前整数的二进制数向左移动指定的位数 + //mask <<= 1 表示将mask左移一位 + //在mask的32位二进制数中,1不断从右向左移动,其他位上都是0 + mask <<= 1; + // 完整过程举例: + // 假设 n = 6,n的32位二进制数的最右边四位是 0110 + // 当i = 0时,mask = 1 的二进制数是 0001 + // 将 n的二进制数0110 和 mask当前的二进制数 0001 进行位与运算 + // 0110 & 0001 = 0,各个位上都没有同时为1,所以结果是0 + // 当i = 1时,mask经过位移,二进制数变成 0010 + // 0110 & 0010 = 1,在倒数第二位上同时为1,所以结果是1 + // bits在i=1时递增1以此类推 + } + //返回位1的统计结果 + return bits; + } + +``` + +**复杂度分析** + +时间复杂度:O(1), +只对整数的32位进行了一次遍历, +时间复杂度是常数,所以时间复杂度是O(1) + +空间复杂度:O(n), +没有使用额外空间,空间复杂读是O(1) + +--- + +* 官方题解2:消除最低有效的1位 + +```java + + public int hammingWeight(int n) { + //计数器,统计整数n的2进制数上有多少个1 + int sum = 0; + //当n不等于0时循环继续 + while (n != 0) { + //n不等于0说明n的二进制数中仍然有1存在 + //计数器加1 + sum++; + //n &= (n - 1)拆分后是两个步骤,即n = n & (n-1) + //将每次 n & (n-1)的结果赋值给整数n + //n & (n-1)的位与运算会消去n的二进制数中最低有效的1位 + //当消除n的二进制数中最后一个1位时,n == 0,跳出循环,任务结束 + n &= (n - 1); + // 完整过程举例: + // 假设 n = 6,n的32位二进制数的最右边四位是 0110 + // n - 1 的32位二进制数的最右边四位是 0101 + // n & (n-1),即 0110 & 0101 = 0100 + // 原本 0110 中的最低有效1位被消去,即右向左数的第一个1 + // 继续循环,0100 - 1 = 0011 + // 0100 & 0011 = 0000, + // 即0100中的1位也被消去,最终结果为0,统计得到2个1位 + } + + //返回1位的统计总数 + return sum; + } + +``` + +**复杂度分析** + +时间复杂度:O(1), +最差情况时间复杂度是32, +最终时间复杂度是O(1) + +空间复杂度:O(1), +没有使用额外的空间, +空间复杂度是O(1) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) diff --git a/_site/leetcode/198-houseRobber/hatrick.md b/_site/leetcode/198-houseRobber/hatrick.md new file mode 100644 index 0000000..921855c --- /dev/null +++ b/_site/leetcode/198-houseRobber/hatrick.md @@ -0,0 +1,49 @@ +**198. 打家劫舍** +--- +[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) + +**思路** +你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统, +如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下, +能够偷窃到的最高金额。 + +1、首先想一想如果是暴力如何做? + +假设从最后一家店铺开始抢,那么只会遇到2种情况,即:抢这家店和下下家店,或者不抢这家店。 +所以我们得到递归的公式: +Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]); + +2、上面的暴力算法虽然能够得到正确的结果,但是显然递归的效率是很低的,如果有n家店铺,每家店铺有2种可能,那么时间复杂度就是2的n次方。那么如何优化呢? + +我们分析一下: +如果我们开始抢的是第n-1家店,那么后面可以是(n-3,n-4,n-5,n-6....); +如果我们开始抢的是第n-2家店,那么后面可以是(n-4,n-5,n-6,....); +那么这两种情况显然n-3之后的n-4,n-5,n-6,....都重复计算了。显然这里有非常大的优化空间。通常我们使用空间来换时间,即用一个数组记录每次计算的结果, +这样每次情况只需要计算一次,再次遇到只需直接返回结果即可,大大优化了时间 + + +```java + class Solution { + public static int[] result; + public int solve(int[] nums,int index){ + if(index < 0){ + return 0; + } + if(result[index] >= 0){ + return result[index]; + } + result[index]=Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]); + return result[index]; + } + public int rob(int[] nums) { + result = new int[nums.length]; + for(int i=0;i 0 && grid[i-1][j] == '1') { + q = (i-1)*col + j; + uf.union(p,q); + } + if(i < row-1 && grid[i+1][j] == '1') { + q = (i+1)*col + j; + uf.union(p,q); + } + if(j > 0 && grid[i][j-1] == '1') { + q = i * col + j-1; + uf.union(p,q); + } + if(j < col - 1 && grid[i][j+1] == '1') { + q = i*col + j + 1; + uf.union(p,q); + } + } + } + //返回count,这就是最终剩下的子集的数量。 + return uf.count; + } + +} +//并查集的数据结构 +class UnionFind{ + //用于存储他们的父节点 + public int[] visited = null; + //用于记录最后子集的个数 + public int count; + public UnionFind(char[][] grid) { + int row = grid.length; + int col = grid[0].length; + //计算该矩阵中有多少个1 + for(int i = 0; i < row; i++) { + for(int j = 0; j K,说明我们要找的元素在index的左边,继续在index的左边进行寻找,如果index == K,说明我们找到了第K大的元素。 +``` +public class Solution { + public int findKthLargest(int[] ele, int k) { + int len = ele.length; + return quickSort(ele,len-k,0,len-1); + } + public int quickSort(int[] ele, int k,int start, int end) { + //如果start>end,说明并不存在第K大的数 + if(start > end) + return -1; + int index = partition(ele,start,end); + //如果index == K,说明找到了第K大的数 + if(index == k) { + return ele[index]; + //如果indexK,说明要找的数,在index的左边 + } else { + return quickSort(ele,k,start,index-1); + } + } + //返回比较元素cmp的位置 + public int partition(int[] ele, int left, int right) { + //选第一个元素为比较元素 + int cmp = ele[right]; + int index = left - 1; + for(int i = left; i < right; i++) { + //如果当前元素小于cmp,则将该元素交换到cmp的前面 + if(ele[i] < cmp) { + swap(ele,i,++index); + } + } + //将cmp交换到最终的位置。 + swap(ele,right,++index); + //返回cmp的位置 + return index; + } + //用位运算交换两个数的位置 + public void swap(int[] ele, int i, int j) { + if(ele[i] == ele[j]) return; + ele[i] ^= ele[j]; + ele[j] ^= ele[i]; + ele[i] ^= ele[j]; + } +} + +``` +**复杂度分析** +空间复杂度:O(1) +时间复杂度:近似于O(n),一般情况下比快排的平均时间复杂度O(nlogn)要好一些。最坏情况下是O(n^2),这时候就是快排的最坏时间复杂度 + +**拓展1** +快排的过程中,比较元素的取法有很多种,可以选第一个,也可以选最后一个,也可以随机选一个.随机选一个的做法是,只需要将随机选的元素跟第一个或者最后一个交换。按照下面是各种选法的代码 +``` +//选最后一个元素为比较元素 + public static int partition1(int[] ele, int left, int right) { + int pivot = ele[right]; + int index = left - 1; + for(int i = left; i < right; i++) { + if(ele[i] < pivot) { + swap(ele,i,++index); + } + } + swap(ele,right,++index); + return index; + } + //选第一个元素为比较元素 + public static int partition2(int[] ele, int left, int right) { + int pivot = ele[left]; + int index = left; + for(int i = left + 1; i <= right; i++) { + if(ele[i] pivot) right--; + if(left < right) { + swap(ele,left,right); + left++; + } + while(left < right && ele[left] < pivot) left++; + if(left < right) { + swap(ele,left,right); + right--; + } + } + return left; + } + +``` +**拓展2** +当数组中有大量重复元素的时候,用三项切分快排更合适,代码如下: +``` + public static void quickSort_3Way(int[] ele, int left, int right) { + if(left >= right) + return; + //选取比较元素 + int pivot = ele[left]; + //遍历指针 + int leftScanPtr = left + 1; + /* + 因为存在大量重复元素,所以跟pivot相等的元素可能有多个,所以遍历完一遍之后,pivot相等的值有多个,聚集在一起,lt用来记录其左端,rt用来记录其右端 + 比如说比较元素是5,经过一趟遍历之后是324255578978,lt就是4,rt就是6 + */ + int lt = left; + int rt = right; + while(leftScanPtr <= rt) { + if(ele[leftScanPtr] < pivot) { + swap(ele,lt,leftScanPtr); + leftScanPtr++; + lt++; + }else if(ele[leftScanPtr] > pivot) { + swap(ele,rt,leftScanPtr); + rt--; + }else{ + leftScanPtr++; + } + } + quickSort_3Way(ele,left,lt-1); + quickSort_3Way(ele,rt+1,right); + } +``` + diff --git a/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md new file mode 100644 index 0000000..c95274f --- /dev/null +++ b/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md @@ -0,0 +1,142 @@ +**找数组中第K大的数** +--- +[https://leetcode.com/problems/kth-largest-element-in-an-array/](https://leetcode.com/problems/kth-largest-element-in-an-array/) + +* 《程序员面试金典(第5版)》第8章:排序与查找,结合leetCode上网友高效解法: + +```java + + /** + * @param nums + * @param k + * @return + */ + public int findKthLargest(int[] nums, int k) { + //调用递归方法找到第k个最大值 + // 第k个最大元素在数组nums从右向左数的第k个位置 + // 即从左往右数第(nums.length - k + 1)个位置 + // 数组下标从0计数,第k个最大元素的下标为 (nums.length - k + 1) - 1 = nums.length - k + return quickSelect(nums, 0, nums.length - 1, nums.length - k); + } + + /** + * 《程序员面试金典(第5版)》第8章:排序与查找 + * https://leetcode-cn.com/submissions/api/detail/215/java/3/ + *

+ * 快速选择算法 + * + * @param nums 数组 + * @param left 最左侧元素下标 + * @param right 最右侧元素下标 + * @param K 目标位置 + * @return 第k个最大值 + */ + public int quickSelect(int[] nums, int left, int right, int K) { + //如果起始下标left和结尾下标right重合,即left和right所在位置即基准值 + if (left == right) { + //返回下标start在数组中对应的值nums[start] + return nums[right]; + } + // 调用分割方法partition,返回结果index是当前排序之后基准值pivot的下标 + // pivot左侧元素小于pivot,pivot右侧元素大于pivot + int index = partition(nums, left, right); + // 本方法内的大写字母K代表数组nums中第k大的值,距离当前左边界left有多远 + // (index - left)得到本轮求得的基准值坐标index距离当前左边界left有多远 + // K与(index - left)比较大小,判断K在基准值坐标index的左侧还是右侧 + if (K >= (index - left)) { + // K >= (index - left)表示nums中第k大的值在基准值右侧 + // 取值范围nums[index]到nums[right] + // K值是到左边界left的距离 + // 左边界更新为index时,当前K值减去index到左边界left的距离得到新的K值 + return quickSelect(nums, index, right, K - (index - left)); + } else { + //第k大的值比当前基准值小,在基准值左侧,取值范围nums[left]到nums[index-1]之间 + //因为左边界left没有改变,所以仍然使用当前K值 + return quickSelect(nums, left, index - 1, K); + } + } + + /** + * 使用QuickSelection快速选择算法,分割数组 + * + * @param nums 数组 + * @param left 数组最左侧元素的下标 + * @param right 数组最右侧元素的下标 + * @return + */ + public int partition(int[] nums, int left, int right) { + // 先定义一个基准值pivot + // 本方法中选用数组最左侧和最右侧下标的平均数 + // 取得一个位于数组中间位置的元素作为基准值 + int pivot = nums[(left + right) / 2]; + //在循环体中,left递增,right递减,两个下标不断靠近 + //当left和right交叉(left>right)时,当前一轮完成了排序,循环结束 + while (left <= right) { + // while循环自左向右不断检索数组nums + // 在到达或越过pivot之前,所有nums[left]都在pivot左侧 + // 当不满足条件nums[left] < pivot时 + // 得到了一个应该被放到pivot右侧的元素,它的下标为left + while (nums[left] < pivot) { + // left不断递增 + // 即指针不断向数组右侧移动 + // 直至到达或越过基准值pivot + left++; + } + // while循环自右向左不断检索数组nums + // 在到达或越过pivot之前,所有nums[right]都在pivot右侧 + // 当不满足条件nums[right] > pivot时 + // 得到了一个应该被放到pivot左侧的元素,它的下标为right + while (nums[right] > pivot) { + // right不断递增 + // 即指针不断向数组左侧移动 + // 直至到达或越过基准值pivot + right--; + } + //经过上两轮while循环,此时nums[left]>=pivot>=nums[right] + //可以推出nums[left]>=nums[right] + //如果此时left<=right,需要交换两个元素的值,保证数组按照从小到大的次序排列 + if (left <= right) { + // 调用swap方法 + // 交换数组nums中,下标left和right对应的两个元素 + swap(nums, left, right); + //交换后下标left继续递增1次,right继续递减1次 + left++; + right--; + } + } + //返回更新后的left值 + return left; + } + + /** + * swap方法,交换数组中两个元素的位置 + * + * @param nums 数组 + * @param left 左侧元素的下标 + * @param right 右侧元素的下标 + * @return + */ + public int[] swap(int[] nums, int left, int right) { + //定义一个临时变量存放右侧元素 + int temp = nums[right]; + //将左侧元素赋值给右侧元素 + nums[right] = nums[left]; + //将临时变量存储的原右侧元素赋值给左侧元素 + nums[left] = temp; + //返回交换后的数组 + return nums; + } + +``` + +**复杂度分析** + +空间复杂度:O(1), +没有使用额外空间,空间复杂读是O(1) + +**参考资料** + +* 《程序员面试金典(第5版)》第8章:排序与查找 + +* 网友高效答案: +[https://leetcode-cn.com/submissions/api/detail/215/java/3/](https://leetcode-cn.com/submissions/api/detail/215/java/3/) diff --git a/_site/leetcode/221-MaximalSquare/official.md b/_site/leetcode/221-MaximalSquare/official.md new file mode 100644 index 0000000..9be6e7b --- /dev/null +++ b/_site/leetcode/221-MaximalSquare/official.md @@ -0,0 +1,3 @@ +**221. 最大正方形** +--- +[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) diff --git a/_site/leetcode/225-implementStackUsingQueues/hatrick.md b/_site/leetcode/225-implementStackUsingQueues/hatrick.md new file mode 100644 index 0000000..ea1ce4f --- /dev/null +++ b/_site/leetcode/225-implementStackUsingQueues/hatrick.md @@ -0,0 +1,66 @@ +**232. 用栈实现队列** +--- +[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) + +解决方案 +**思路** +根据题意的描述,我们要用栈实现队列先进先出的特性,使用两个栈,每次入栈之前,将栈中元素放入辅栈,在入栈之后再拉回来 + +``` +class MyQueue { + + //设置一个flag标示位,表示每次第一个进栈的元素 + private int flag = -1; + //主栈 + private Stack s1 = new Stack<>(); + //辅助栈 + private Stack s2 = new Stack<>(); + + public MyQueue() { + } + + public void push(int x) { + //如果是第一次入栈 主栈和辅助栈都为空 + if (s1.empty()) { + //第一次进来将flag置为进栈的值 + flag = x; + } + //如果第二次进来话,需要将前面进栈的值弹出,并放到辅助栈里面 + while (!s1.empty()) { + s2.push(s1.pop()); + } + //保证当前栈中push值得时候是干净的栈,模拟队列 + s1.push(x); + //将辅助栈中的值弹出,放到主栈中,保证了主栈中先进先出的特性 + while (!s2.empty()) { + s1.push(s2.pop()); + } + } + + public int pop() { + //直接弹栈 出来的就是最先进去的哪一个 + int num = s1.pop(); + if (!s1.empty()) { + //然后将当前的s1栈顶的元素赋值给标志位 + flag = s1.peek(); + } + return num; + } + + public int peek() { + //取标志位 + return flag; + } + + public boolean empty() { + return s1.empty(); + } +} + +``` +**复杂度分析** +时间复杂度:O(N^2) +空间复杂度:O(N^2) + +**参考资料** + [https://blog.csdn.net/LaputaFallen/article/details/79998961?utm_source=blogxgwz5](https://blog.csdn.net/LaputaFallen/article/details/79998961?utm_source=blogxgwz5) \ No newline at end of file diff --git a/_site/leetcode/225-implementStackUsingQueues/official.md b/_site/leetcode/225-implementStackUsingQueues/official.md new file mode 100644 index 0000000..14dcd85 --- /dev/null +++ b/_site/leetcode/225-implementStackUsingQueues/official.md @@ -0,0 +1,4 @@ +**225. 用队列实现栈** +--- +[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) + diff --git a/_site/leetcode/231-PowerOfTwo/hatrick.md b/_site/leetcode/231-PowerOfTwo/hatrick.md new file mode 100644 index 0000000..1074205 --- /dev/null +++ b/_site/leetcode/231-PowerOfTwo/hatrick.md @@ -0,0 +1,44 @@ +**231. 2的幂** +--- + +[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) +思路: +解法一: +直接判断当前这个数字是否等于1,如果等于1则当前是2的0次幂,其次判断当前的数字取模 +能否除尽,如果不能直接返回,如果能就继续计算 +```java + private boolean is2reverse(int n) { + if (n == 1) { + return true; + } + if (n >= 2 && n % 2 == 0) { + return is2reverse(n / 2); + } + return false; + } + +``` +**复杂度分析** +时间复杂度:O(N) +空间复杂度:O(1) +--- +解法二: +2的次幂,意味着n&(n-1)的值为0,如果不是2的次幂那么返回值不是0了 +```java + private boolean is2reverse(int n) { + if (n < 0) { + return false; + } + int x = n & (n - 1); + return x == 0; + } +``` + +**复杂度分析** +时间复杂度:O(1) +空间复杂度:O(1) +--- +**参考资料** + +* 网友高票Java解法: +[https://blog.csdn.net/chenchaofuck1/article/details/51226899](https://blog.csdn.net/chenchaofuck1/article/details/51226899) diff --git a/_site/leetcode/231-PowerOfTwo/official.md b/_site/leetcode/231-PowerOfTwo/official.md new file mode 100644 index 0000000..4a455bd --- /dev/null +++ b/_site/leetcode/231-PowerOfTwo/official.md @@ -0,0 +1,4 @@ +**231. 2的幂** +--- + +[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) diff --git a/_site/leetcode/232-implementQueueUsingStacks/hatrick.md b/_site/leetcode/232-implementQueueUsingStacks/hatrick.md new file mode 100644 index 0000000..9ef68cd --- /dev/null +++ b/_site/leetcode/232-implementQueueUsingStacks/hatrick.md @@ -0,0 +1,80 @@ +**225. 用队列实现栈** +--- +[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode.com/problems/backspace-string-compare/) + +解决方案 +**思路** +根据题意的描述,我们要使用队列实现栈,我们需要两个队列,来进行值得互换,一次来保证一个当前栈,进而实现栈的特性 +**算法** +从一个队列中拿出放到另外一个队列里面,然后队列里最后一个也就是我们的"栈顶元素" +``` +class MyStack { + + //使用两个队列来交换数据格式 + private Queue q1 = new LinkedList<>(); + private Queue q2 = new LinkedList<>(); + + //保证当前的值只在一个队列里面 + public void push(int x) { + if (!q1.isEmpty()) + q1.add(x); + else + q2.add(x); + } + + public int pop() { + //如果队列1位空 + if (q1.isEmpty()) { + //则队列2有值,这里需要单独定义size 因为poll方法会使当前队列的长度动态变化 + int size = q2.size(); + //这里循环会留下q2队列最后添加的一项 + for (int i = 1; i < size; i++) { + //将队列2从头开始取添加到队列1(保证当前只有一个队列里面有元素,弹栈之后值并不完整) + q1.add(q2.poll()); + } + //将对列2中头部元素弹栈并移除,也就是队列中的最后一个进入的 + return q2.poll(); + } else { + //跟上面思路相同 + int size = q1.size(); + for (int i = 1; i < size; i++) { + q2.add(q1.poll()); + } + return q1.poll(); + } + } + + public int top() { + //定义临时变量 + int result; + //如果q1为空 + if (q1.isEmpty()) { + //这里的size方法需要单独提取出来 + int size = q2.size(); + //这里队列2会将最后进入的元素保留 + for (int i = 1; i < size; i++) { + q1.add(q2.poll()); + } + //拿到最后一个进入的元素赋值给临时变量 + result = q2.poll(); + //保证当前只有一个队列里面的元素是完整的 + q1.add(result); + } else { + int size = q1.size(); + for (int i = 1; i < size; i++) { + q2.add(q1.poll()); + } + result = q1.poll(); + q2.add(result); + } + return result; + } + + public boolean empty() { + return q1.isEmpty() && q2.isEmpty(); + } +} +``` +**复杂度分析** +时间复杂度:O(N^2),需要取出当前队列里面的n-1个元素 +空间复杂度:O(N^2),需要两个队列,取出放入组合 diff --git a/_site/leetcode/232-implementQueueUsingStacks/official.md b/_site/leetcode/232-implementQueueUsingStacks/official.md new file mode 100644 index 0000000..98ac7a7 --- /dev/null +++ b/_site/leetcode/232-implementQueueUsingStacks/official.md @@ -0,0 +1,4 @@ +**232. 用栈实现队列** +--- +[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) + diff --git a/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md b/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md new file mode 100644 index 0000000..6326f69 --- /dev/null +++ b/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md @@ -0,0 +1,91 @@ +**两个节点的最低公共祖先** +--- +[https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) +解决方案: +方法一:**递归** +**思路** +这个题,最容易想到的思路就是,先判断根节点是不是公共祖先,然后在判断根节点的左子节点和右子节点是不是公共祖先。但是这样有一个问题是,如果从上往下依次判断的话,会重复计算,所以最好的方法是从下往上开始判断。 +**算法** +假设要寻找p和q的公共祖先,在对树的遍历过程中,先判断当前节点root是否为null,或者是否为q和p中的一个,如果是的话,则返回root.如果不是的话,则对其左子树和右子树进行寻找。如果左子树返回的为null,那说明公共祖先一定在右字树。如果右子树返回的为null,说明公共祖先一定在左子树中。如果两个都不为null,说明左子树和右字树都各含有一个节点,则返回当前节点 +**代码** +``` +class Solution { + //后序遍历 + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + //如果当前节点为null,或者等于p、q中的一个,则返回当前节点 + if(root == null || root == p || root == q) return root; + //在左子树中寻找 + TreeNode left = lowestCommonAncestor(root.left,p,q); + //在右子树中寻找 + TreeNode right = lowestCommonAncestor(root.right,p,q); + //如果左子树返回的为null,那说明公共祖先一定在右子树。如果右子树返回的为null,说明公共祖先一定在左子树中。如果两个都不为null,说明左子树和右字树都各含有一个节点,则返回当前节点 + return left == null ? right : right == null ? left : root; + } + +} +``` +复杂度分析: +假设树的节点的个数为N +空间复杂度:O(N) 虽然代码中并没有用额外的空间,但是递归本身需要用到栈,最坏情况下,树的高度就是N +时间复杂度:O(N) 最坏情况下,需要都访问一遍 + +方法二:**循环遍历** +**思路**: +我们可以先找到从根节点分别到p和q的路径,然后对比两条路径,从下到上,第一个相同的节点就是他们俩的最低公共祖先。实现方式可以有多种。 +**算法** +从根节点开始找到p和q,在寻找的过程中,将节点和其父节点用hashmap存储,然后根据hashmap,我们可以找到从p和q到根节点的路径。进行对比之后,就可以找到最低公共祖先 +``` +class Solution { + + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + + //用来辅助遍历 + Deque stack = new ArrayDeque<>(); + + //存节点和其父节点 + Map parent = new HashMap<>(); + + parent.put(root, null); + stack.push(root); + + // 找p和q + while (!parent.containsKey(p) || !parent.containsKey(q)) { + + TreeNode node = stack.pop(); + + // While traversing the tree, keep saving the parent pointers. + 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<>(); + + // 找到从p到根节点的路径 + while (p != null) { + ancestors.add(p); + p = parent.get(p); + } + + // 找从q到根节点的路径,在寻找的过程中,跟p到根节点的路径进行比对,第一个相同的节点就是最低公共祖先 + while (!ancestors.contains(q)) + q = parent.get(q); + return q; + } + +} +``` +复杂度分析: +假设树节点数为N +空间复杂度:O(N),最坏情况下,树高为N +时间复杂度:O(N),最坏情况下,需要都访问一遍 + +参考资料 +- leetcode官方题解 [leetcode官方题解](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/) +- leetcode得票最多题解[leetcode discuss](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/discuss/65225/4-lines-C%2B%2BJavaPythonRuby) \ No newline at end of file diff --git a/_site/leetcode/239-slidingWindowMaximum/official.md b/_site/leetcode/239-slidingWindowMaximum/official.md new file mode 100644 index 0000000..2b651cf --- /dev/null +++ b/_site/leetcode/239-slidingWindowMaximum/official.md @@ -0,0 +1,4 @@ +**239. 滑动窗口最大值** +--- +[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) + diff --git a/_site/leetcode/242-ValidAnagram/bigablecat.md b/_site/leetcode/242-ValidAnagram/bigablecat.md new file mode 100644 index 0000000..e0fd459 --- /dev/null +++ b/_site/leetcode/242-ValidAnagram/bigablecat.md @@ -0,0 +1,92 @@ +**242. 有效的字母异位词** +--- +[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) + +* 官方题解方法1:排序后对比是否相等 + +```java + + public boolean isAnagram(String s, String t) { + if (s == null || t == null) return false; + //如果长度不等,直接返回false + if (s.length() != t.length()) return false; + + //将两个字符串转换为字符数组char[] + char[] sChar = s.toCharArray(); + char[] tChar = t.toCharArray(); + + //使用Arrays的sort方法分别为两个字符数组排序 + //Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进,时间复杂度稳定为O(nlogn) + Arrays.sort(sChar); + Arrays.sort(tChar); + + //比较排序后的两个字符数组是否相等 + return Arrays.equals(sChar, tChar); + } + +``` + +**复杂度分析** + +时间复杂度:O(nlogn),假设n是s的长度 +排序的时间复杂度O(nlogn),对比两个字符串的时间复杂度O(n) +总的复杂度是 nlogn+n,舍弃n,所以最终复杂度是O(nlogn) + +空间复杂度:O(1),如果使用堆排序,需要O(1)的辅助空间; +本题的Java解法toCharArray有复制原字符串的行为,所以使用了O(n)的辅助空间 + +--- + +
+ +* 官方题解方法2:用计数器统计每个字符出现的次数 + +```java + + if (s == null || t == null) return false; + //如果两个字符串长度不同,直接返回false + if (s.length() != t.length()) { + return false; + } + // 假设单词里的字符都在a~z的范围内,创建一个长度为26的int数组作为计数器 + // 数组中每个元素的默认值都是0,相当于为26个英文字母逐个建立了计数器 + int[] counter = new int[26]; + //遍历字符串s + for (int i = 0; i < s.length(); i++) { + //s.charAt(i)获取当前字符 + //s.charAt(i) - 'a' 得到当前字符与a的差,数值在0~25之间 + //counter[s.charAt(i) - 'a']从counter中获取当前字符所在位置的计数 + //counter[s.charAt(i) - 'a']++ 将当前字符在counter中的计数值+1 + counter[s.charAt(i) - 'a']++; + //同理,将t中当前字符在counter的计数值-1 + counter[t.charAt(i) - 'a']--; + } + //当所有字符遍历完成后,如果每个字符都出现了相同的次数,counter中所有元素都将归零 + //遍历counter查看计数器数组是否已经归零 + for (int count : counter) { + //出现非0的情况,说明有不同的字符 + if (count != 0) { + return false; + } + } + return true; + +``` + +**复杂度分析** + +时间复杂度: O(n). 遍历s的长度,时间复杂度为n + +空间复杂度: O(1),使用的counter数组容量是常数所以空间复杂度为 O(1) + +--- + + +**参考资料** + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) + + +* Collections.sort()的用法和要点: +[https://blog.csdn.net/wsll581/article/details/79953589](https://blog.csdn.net/wsll581/article/details/79953589) diff --git a/_site/leetcode/260-SingleNumberIII/README.md b/_site/leetcode/260-SingleNumberIII/README.md new file mode 100644 index 0000000..6797db8 --- /dev/null +++ b/_site/leetcode/260-SingleNumberIII/README.md @@ -0,0 +1,17 @@ +**260. 只出现一次的数字 III** +--- +[https://leetcode-cn.com/problems/single-number-iii/](https://leetcode-cn.com/problems/single-number-iii/) + +给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 + +示例 : + +``` +输入: [1,2,1,3,2,5] +输出: [3,5] +``` + +注意: + +1. 结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。 +2. 你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现? diff --git a/_site/leetcode/264-UglyNumberII/bigablecat.md b/_site/leetcode/264-UglyNumberII/bigablecat.md new file mode 100644 index 0000000..8bc4a83 --- /dev/null +++ b/_site/leetcode/264-UglyNumberII/bigablecat.md @@ -0,0 +1,86 @@ +**264. 丑数 II** +--- +[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) + +* 网友高票Java解法 + +```java + + /** + * https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution + * 网友高票Java解法 + *

+ * 思路: + * 丑数从大到小依次为 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … + * 因为丑数只能被2,3,5整除 + * 可以将丑数拆分为3组 + * (factor2) 1×2, 2×2, 3×2, 4×2, 5×2, 6x2, 8x2 … + * (factor3) 1×3, 2×3, 3×3, 4×3, 5×3, 6x3, 8x3 … + * (factor5) 1×5, 2×5, 3×5, 4×5, 5×5, 6x5, 8x5 … + *

+ * 即丑数在自身基础上不断累乘2,3,5中的一个数 + * 从这三组中依次选取最小的数存入丑数数组 + * 就得到了丑数从小到大排列的所有丑数 + * + * + * @param n + * @return + */ + public int nthUglyNumber(int n) { + //创建一个大小为n的整数数组ugly + int[] ugly = new int[n]; + //丑数从1开始,所以ugly数组的第一个元素赋值为1 + ugly[0] = 1; + //将丑数分为3组,factor2, factor3, factor5 分别与2,3,5累乘 + //定义下标index2,index3,index5获取丑数数组ugly中相应位置的数字 + int index2 = 0, index3 = 0, index5 = 0; + int factor2 = 2, factor3 = 3, factor5 = 5; + //从下标1,即ugly第二个元素开始循环,依次为ugly数组所有元素赋值 + for (int i = 1; i < n; i++) { + //获取累乘2,3,5的三组数中的最小值 + int min = Math.min(Math.min(factor2, factor3), factor5); + //让数组当前位置等于三者中最小值 + ugly[i] = min; + //下列代码 + //首先查看 ugly[i] = min 是从factor2,factor3,factor5三组中哪一组里取走数字 + // (factor2) 1×2, 2×2, 3×2, 4×2, 5×2, 6x2, 8x2 … + // (factor3) 1×3, 2×3, 3×3, 4×3, 5×3, 6x3, 8x3 … + // (factor5) 1×5, 2×5, 3×5, 4×5, 5×5, 6x5, 8x5 … + //然后通过这一组数对应的下标index2,index3或index5, + //从ugly数组中选取能够继续累乘的最小数字 + //累乘的同时,对应的索引递增,下次不会取到重复数字 + //比如ugly[1] = 2; + //此时factor2 = 2, factor3 = 3, factor5 = 5; + //即 ugly[1] = factor2 = ugly[0] x 2 = 1 x 2 + // factor2这一组的第一个数字被取走了 + // 接下来要获取factor2这一组的第二个数字 + // factor2 = ugly[1] x 2 = 2 x 2 = 4 + if (factor2 == min) + factor2 = 2 * ugly[++index2]; + if (factor3 == min) + factor3 = 3 * ugly[++index3]; + if (factor5 == min) + factor5 = 5 * ugly[++index5]; + } + //ugly数组从下标0开始获取第一个数字 + //那么第n个数字的下标就是n-1 + //所以最终返回ugly[n - 1] + return ugly[n - 1]; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +只有一个for循环进行了n次迭代 + +空间复杂度:O(n), +创建了一个大小为n的数组ugly + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) diff --git a/_site/leetcode/264-UglyNumberII/official.md b/_site/leetcode/264-UglyNumberII/official.md new file mode 100644 index 0000000..8795cdc --- /dev/null +++ b/_site/leetcode/264-UglyNumberII/official.md @@ -0,0 +1,3 @@ +**264. 丑数 II** +--- +[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) diff --git a/_site/leetcode/279-PerfectSquares/official.md b/_site/leetcode/279-PerfectSquares/official.md new file mode 100644 index 0000000..f0a46e8 --- /dev/null +++ b/_site/leetcode/279-PerfectSquares/official.md @@ -0,0 +1,3 @@ +**279. 完全平方数** +--- +[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) diff --git a/_site/leetcode/279-PerfectSquares/zengdiqing1994.md b/_site/leetcode/279-PerfectSquares/zengdiqing1994.md new file mode 100644 index 0000000..2bcefcf --- /dev/null +++ b/_site/leetcode/279-PerfectSquares/zengdiqing1994.md @@ -0,0 +1,59 @@ +279.完全平方数 + +https://leetcode-cn.com/problems/perfect-squares/ + +给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 + +示例 1: + +输入: n = 12 +输出: 3 +解释: 12 = 4 + 4 + 4. +示例 2: + +输入: n = 13 +输出: 2 +解释: 13 = 4 + 9. + +**思路:** +1.DP动态规划,关键在于状态的定义和状态方程,我们要知道12最少有多少个数构成,实际上如果我们走了一步的话,要知道11,8,3对应的步数,如果我们不走, +就需要知道12的步数,我们只要通过比较是走0步小,还是走1步那个更小即可。 + +状态转移方程: +num[n] = min(num[n],num[n-i**2]+1) + +所以可以先定一个n大小的数组(static类型),需要使数组初始化为无穷大 + +``` +class Solution: + _dp = list() #放到全局,能节省很多时间 + def numSquares(self, n): + """ + :type n: int + :rtype: int + """ + dp = self._dp + dp = [float('inf') for i in range(n+1)] #状态定义 + dp[0] = 0 + for i in range(n+1): + j = 1 + while i + j**2 <= n: + dp[i + j**2] = min(dp[i + j**2],dp[i] + 1) #状态转移方程 + j+=1 + return dp[n] +``` +但是这种方法时间复杂度O(n^2)超时了,参考了别人的代码: + +``` +class Solution: + _dp = [0] + def numSquares(self, n): + dp = self._dp + while len(dp) <= n: + dp += list((min(dp[-i*i] for i in range(1,int(len(dp)**0.5+1)))+1,)) #这里的int无法初始化list,我们只有通过加上一个',', + 将int变成tuple才可以初始化。 + return dp[n] +``` +这个时候时间复杂度是O(NlogN),时间大大减少 + +参考:https://www.codetd.com/article/2640989 diff --git a/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md b/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md new file mode 100644 index 0000000..6ecec86 --- /dev/null +++ b/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md @@ -0,0 +1,71 @@ +**找数据流的中位数** +--- +[https://leetcode.com/problems/find-median-from-data-stream/](https://leetcode.com/problems/find-median-from-data-stream/) + +近似题目 +[找数组中第K大的数](https://github.com/hollischuang/Interview/tree/master/algorithm/leetcode/215-KthLargestElementInAnArray) +[找数据流中第K大的数](https://github.com/hollischuang/Interview/tree/master/algorithm/leetcode/703-KthLargestElementInAStream) + +解决方案: +方法一:**堆** +思路: +首先,最容易想到的就是,每加进来一个数都重新排序,然后找中位数,但是这样的时间复杂度肯定是接受不了的。 +中位数可能是一个,也可能是两个,如果是两个的话,需要取平均值。这个题最重要的一点是,我们要有两个指针,可以随着数据流动态的记录两个中位数的位置或者值。如果总数是奇数,则两个指针指向同一个位置。所以这个题可以有多个解法。 +这里我们采用栈来实现,用一个最大栈,一个最小栈。在处理的过程中,我们要维持`|Size(MaxHeap) - Size(MinHeap)| <= 1`,这时候,两个栈的栈顶就相当于两个指针,他们始终指向中位数 +**算法** +创建两个堆,最大堆和最小堆。向堆里加元素的算法是: +1. 如果当前元素总数是奇数,则先将元素放入到最小堆,然后将最小堆堆顶的元素取出来,放入最大堆里面 +2. 如果当前元素总数为偶数,则先将元素放入到最大堆里面,然后将最大堆堆顶的元素取出来,放入最小堆 + +取中位数的算法是: +1. 如果当前元素总数是奇数,则直接取最大堆堆顶的元素 +2. 如果当前元素总数是偶数,则分别取最大堆和最小堆堆顶的元素,然后取平均值 + +代码: +``` +class MedianFinder { + PriorityQueue min; + PriorityQueue max; + int count;//记录元素总数 + /** initialize your data structure here. */ + public MedianFinder() { + //初始化堆和count + count = 0; + min = new PriorityQueue(); + max = new PriorityQueue(new Comparator(){ + public int compare(Integer a, Integer b) { + return b - a; + } + }); + + } + + public void addNum(int num) { + count++; + //如果当前元素总数是奇数,则先将元素放入到最小堆,然后将最小堆堆顶的元素取出来,放入最大堆里面 + if((count & 1) == 1) { + min.offer(num); + max.offer(min.poll()); + // 如果当前元素总数为偶数,则先将元素放入到最大堆里面,然后将最大堆堆顶的元素取出来,放入最小堆 + }else { + max.offer(num); + min.offer(max.poll()); + } + + } + + public double findMedian() { + //如果当前元素总数是奇数,则直接取最大堆堆顶的元素 + if((count & 1) == 1) { + return max.peek(); + //如果当前元素总数是偶数,则分别取最大堆和最小堆堆顶的元素,然后取平均值 + }else { + return ((double)(max.peek()+min.peek()))/2; + } + } +} + +``` +复杂度分析: +空间复杂度:O(n),n为数据流的长度 +时间复杂度:O(logn) \ No newline at end of file diff --git a/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md b/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md new file mode 100644 index 0000000..6d13bf9 --- /dev/null +++ b/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md @@ -0,0 +1,87 @@ +**300. LongestIncreasingSubsequence** +--- +[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) + +方法一:动态规划 + +思路:从头开始遍历,查找以当前点为数组最后位置的最长子序列。由于当前点前面的所有点的最长子序列已经遍历完成了,所以只是需要找到前面所有子序列的最大值即可。 +即令F(i)表示数组nums的从0到i位的最长子序列长度。则有F(i)=max{F(0)...F(i-1)}+1 +所以代码如下: + +```java +public class Solution { + //从前往后 + public int lengthOfLIS(int[] nums) { + if (nums.length == 0) // 测试用例中有集合为空的例子 + return 0; + + int max = 0;// 保存最大值 + int[] result = new int[nums.length];// 保存每一位最长子序列结果的数组,初始化默认值为0 + for (int i = 0; i < nums.length; i++) { // 从左至右顺序遍历每一位 + result[i] = 1; // 对于每一位,其最长子序列至少为一 + for (int j = 0; j < i; j++) {// 从数组开始到当前位置,找寻前面所有的数的最大子序列长度 + // 最大子序列长度寻找标准: + // 1.查找的数比当前位置数小(即能构成上升序列) + // 2.查找的数的最大上升子序列长度加一 比目前所记录的最大上升子序列长度大 + if (nums[j] < nums[i] && (result[j] + 1) > result[i]) { + result[i] = result[j] + 1; + } + } + // 记录从开始到当前位置所求最大上升子序列长度最大的 + max = Math.max(result[i], max); + } + + return max; + } +} +``` + +方法二: 二分法+贪心 +(官方题解称之为dp,我个人倾向于贪心) + +根据题目中的序列进行举例分析nums = [10,9,2,5,3,7,101,18],最大上升子序列为[2,3,7,101],长度为4 +思路: 以未知的最长子序列为对象进行分析。 +假设已知nums序列的一个上升子序列为x[0...n]。题目是求x[0...n]的最大长度,因此所有的行为都以能够提高长度为目的。若现在将nums[i]插入x[0...n]中,判断其对增长上升子序列长度的影响。 +* 若nums[i]>x[n],则插入nums[i]能够增加上升子序列长度; +* 若nums[i]答案示例,本人自行编写后参考LeetCode官方题库。 + +**304. 二维区域和检索-矩阵不可变** +--- +[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) + +摘要 + +本文适用于初学者,潜入深出。 + + +```java + +package algorithm_leetcode; + +//看到这道题目时,给我第一印象似乎只有一种方法来解决 +class NumMatrix2{ + //定义成员变量 + private int[][] data; + public NumMatrix2(int[][] matrix){ + data=matrix; + } + //普通的方法用来计算完对应范围的数据的和 + public int sumRegion(int row1, int col1, int row2, int col2){ + int k=0; + //走完所有的ROWS + for(int i=row1;i<=row2;i++){ + //走完所有的COLUMS + for(int j=col1;j<=col2;j++){ + //进行累加 + k+=data[i][j]; + } + } + //返回给调用者 + return k; + } +} +//认为leetCode中省略的代码 +public class T304RangeSumQuery2DImmutable2 { + public static void main(String[] args) { + int[][] matrix={ {3, 0, 1, 4, 2}, + {5, 6, 3, 2, 1}, + {1, 2, 0, 1, 5}, + {4, 1, 0, 1, 7}, + {1, 0, 4, 0, 5}}; + int row1=2; + int col1=1; + int row2=4; + int col2=3; + NumMatrix2 obj = new NumMatrix2(matrix); + int param_1 = obj.sumRegion(row1,col1,row2,col2); + System.err.println(param_1); + } +} +//如果你在自己的工具上写完后,乍一看好像没有别的好的解决方法了吧 +//但是仔细思考下会发现leetCode中用了一个有参构造方法,类是对象的模板,对象是类的实例, +//分配空间-->递归创建父类对象-->初始化本类属性-->调用本类构造方法 +//这些都是在缓存中完成的,所以如果可以借助这个构造方法来做一些计算数组的事情会提高效率 +class NumMatrix { + //成员变量 + private int[][] dp; + //有参构造方法 + public NumMatrix(int[][] matrix) { + //排除数组长度为0的情况 + if (matrix.length == 0 || matrix[0].length == 0) return; + //建一个新的数组 + dp = new int[matrix.length + 1][matrix[0].length + 1]; + //走完matrix的所有ROWS + for (int r = 0; r < matrix.length; r++) { + //走完matrix的所有COLUMS + for (int c = 0; c < matrix[0].length; c++) { + //System.out.print("dp:"+dp[r + 1][c + 1]+"=" + dp[r + 1][c] +"+"+ dp[r][c + 1]+"+" + matrix[r][c] +"-"+ dp[r][c]); + //System.out.println(); + //这样是为了实现某个数据上如 dp[1][2] 你取到的这个值就是从dp[0][0]到dp[1][2]的所有值的和 + dp[r + 1][c + 1] = dp[r + 1][c] + dp[r][c + 1] + matrix[r][c] - dp[r][c]; + } + } + } + public int sumRegion(int row1, int col1, int row2, int col2) { + //System.out.println("dp:"+dp[row2 + 1][col2 + 1]+"-" + dp[row1][col2 + 1] +"-"+ dp[row2 + 1][col1]+"+" + dp[row1][col1]); + //想求得某个区域的和,要减去两个部分区域但是这两部分区域有交集,即会多减掉一个交集。 + return dp[row2 + 1][col2 + 1] - dp[row1][col2 + 1] - dp[row2 + 1][col1] + dp[row1][col1]; + } +``` + +--- + + +**参考资料** + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) diff --git a/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md b/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md new file mode 100644 index 0000000..78ce4c3 --- /dev/null +++ b/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md @@ -0,0 +1,85 @@ +**309. 最佳买卖股票时机含冷冻期** +--- +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +* 网友高票Java答案(动态规划) + +```java + public static int maxProfit(int[] prices) { + //定义变量 + //sell表示只能卖出或持有时所得的总利润 + //prev_sell用于缓存上一次的sell值 + //buy表示只能买入或持有时所得的总利润 + //prev_buy用于缓存上一次的buy值 + int sell = 0, prev_sell = 0, buy = Integer.MIN_VALUE, prev_buy; + + for (int price : prices) { + // buy的值来自上一次循环结果,将其赋值给prev_buy + prev_buy = buy; + + // 如果当前日期只能买入或持有,buy的值有两种情况 + // 第一种情况:在当前日期进行了买入操作 + // prev_sell - price + // prev_sell 是前一次进行卖出操作时所得利润总和 + // price是当前日期价格,也就买入股票所需的支出 + // 利润-支出,得到在当前日期买入后剩余的利润 + // 第二种情况:当前日期不进行任何操作 + // 直接使用pre_buy的值即可 + // 从二者中比较出利润较大者,赋值给变量buy + // buy就是当前日期只能买入或持有时所得最大利润 + buy = Math.max(prev_sell - price, prev_buy); + + // 同理可得只能卖出或持有时所得利润sell的值 + prev_sell = sell; + + // 不同的是对的Math.max(prev_buy + price, prev_sell)部分的解释 + // prev_buy + price + // prev_buy 是前一次进行买入操作时所得利润总和 + // price是当前日期价格,也就卖出股票所得的收入 + // 利润+支出,得到在当前日期卖出后总共获得的利润 + sell = Math.max(prev_buy + price, prev_sell); + } + + //到最后一个交易日为止,最后的一次操作只能是卖出才能清仓 + //所以返回sell的值即可 + return sell; + + //上述代码中还有2个问题需要解决 + //第一个问题,会不会在同一天既买入又卖出? + //如果进行了卖出操作,sell = prev_buy + price + //prev_buy不是当天的买入的结果 + //所以同一天内,买和卖都是在上一次结果的基础上交易 + //第二个问题,会不会出现连续买入或连续卖出的情况? + //假设连续买入而没有卖出 + //在第i-1天买入,buy[i-1] = prev_sell - prices[i-1] + //在第i天继续买入,buy[i] = prev_sell - prices[i] + //因为没有卖出,所以prev_sell是相等的 + //这样buy[i]的操作实际上冲抵了buy[i-1]的操作 + //即原本在第i-1天用prev_sell买入 + //经过比较,发现第i天买入更划算 + //那么用prev_sell在第i天买入 + //可以看出,只要prev_sell的值保持不变 + //则永远只能在prev_sell的基础上发生1次买入 + //而prev_sell的值发生了变化,说明已经进行了一次卖出操作 + //再一次的买入是在新的卖出基础上进行的 + //同理,sell = prev_buy + price 中sell也只能是一种置换 + //结合冷冻期的解释,可以总结出 + //在同一天内,买和卖都只能基于上一次的交易结果 + //买和卖永远只会成对出现 + + } + +``` + +**复杂度分析** + +时间复杂度:O(n),遍历一次 + +空间复杂度:O(1),没有使用额外空间 + +--- + +**参考资料** + +* 网友高票Java答案: +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) diff --git a/_site/leetcode/312-BurstBalloons/melody-l.md b/_site/leetcode/312-BurstBalloons/melody-l.md new file mode 100644 index 0000000..e1ec007 --- /dev/null +++ b/_site/leetcode/312-BurstBalloons/melody-l.md @@ -0,0 +1,57 @@ +**312. burst-balloons** + +--- +[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) + +* 该问题主要难推导出状态转移方程。 +1. 如果是贪心的思路,即每次选择都是最大值,是无法得到最优解的。例如本题中的例子,第一步选择的是1而不是5,如果按照贪心的思路应该选择的是5。 +2. 如果死dp的思路,中间态的定义是:设`dp[i][j]`表示的是 **序列nums在从i到j都戳破的情况下,得到的硬币的最大值**。因此,`dp[1][n]`表示的是都戳破得到硬币的最大值,即为我们所求。此时,**假设nums从i到j,所有的气球都戳破了而最后戳破的是k**,则此时的硬币分数为`nums[i-1] * nums[k] * nums[j+1]` 加上之前的分数。而之前的分数是`dp[i][k-1]`和`dp[k+1][j]`,即`dp[i][j] = nums[i-1] * nums[k] * nums[j+1] + dp[i][k-1] + dp[k+1][j]`。因此,若dp表示的是最大值,则算法思路为从i到j遍历,求出来的最大值即为所求。故递推式为: `dp[i][j] = Max{ nums[i-1] * nums[k] * nums[j+1] + dp[i][k-1] + dp[k+1][j] }, 其中k表示从i到j`。 + +* 有了递推式后,需要确定遍历顺序。根据递推式可以看出,递推的顺序是按照序列的长度递增来的,即先遍历序列长度为1的组合,后遍历序列长度为2的组合。 + +--- + +方法一:动态规划 + +```java + +public class Solution { + public int maxCoins(int[] nums) { + // 为了计算方便,使用新的数组来代替之前的数组 + // 新的数组在nums的前面加上一个1,在末尾加上了一个1, + // 这样能够统一处理, + // 因此下面遍历的时候,是从1开始,到nums.length结束,包括nums.length + int[] newNum = new int[nums.length + 2]; + System.arraycopy(nums, 0, newNum, 1, nums.length); + newNum[0] = 1; + newNum[nums.length+1] = 1; + // 用来存储所有的dp结果 + // dp[i][j]表示从i到j所有的气球都戳破所得到的最大值 + int[][] dp = new int[nums.length + 2][nums.length + 2]; + + // 由上文分析可知,从nums序列长度为1的开始遍历, + // 注意:长度为1,此处length为0。 + for (int length = 0; length < nums.length; length++) { + // 开始计算当nums长度一定的情况下,所有的可能组合的dp值 + for (int i = 1; i <= nums.length - length; i++) { + // 计算长度为length+1的时候,末尾j应该处于的位置, + // 此处不需要担心j超过数组长度, + // 因为i的遍历进行了限制,i只会遍历到最后一个满足length+1长度的起始索引位置 + int j = i + length; + // 确定了i与j的范围, + // 根据递推式从i到j顺序遍历,找到dp[i][j]的最大值 + for (int k = i; k <= j; k++) { + dp[i][j] = Math.max(dp[i][j], newNum[i - 1] * newNum[k] * newNum[j+1 ] + dp[i][k - 1] + dp[k + 1][j]); + } + } + } + + return dp[1][nums.length]; + } +} + +``` + +**参考资料** +* 网友答案: +[https://www.cnblogs.com/grandyang/p/5006441.html](https://www.cnblogs.com/grandyang/p/5006441.html) diff --git a/_site/leetcode/312-BurstBalloons/official.md b/_site/leetcode/312-BurstBalloons/official.md new file mode 100644 index 0000000..81fc5b0 --- /dev/null +++ b/_site/leetcode/312-BurstBalloons/official.md @@ -0,0 +1,3 @@ +**312. 戳气球** +--- +[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) diff --git a/_site/leetcode/321-CreateMaximumNumber/README.md b/_site/leetcode/321-CreateMaximumNumber/README.md new file mode 100644 index 0000000..e379863 --- /dev/null +++ b/_site/leetcode/321-CreateMaximumNumber/README.md @@ -0,0 +1,48 @@ +**321. 拼接最大数** +--- +[https://leetcode-cn.com/problems/create-maximum-number/](https://leetcode-cn.com/problems/create-maximum-number/) + +**难度** +困难 + +**题目描述** + +给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。 + +求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。 + +说明: 请尽可能地优化你算法的时间和空间复杂度。 + +**示例 1:** +``` +输入: +nums1 = [3, 4, 6, 5] +nums2 = [9, 1, 2, 5, 8, 3] +k = 5 +输出: +[9, 8, 6, 5, 3] +``` + +**示例 2:** +``` +输入: +nums1 = [6, 7] +nums2 = [6, 0, 4] +k = 5 +输出: +[6, 7, 6, 0, 4] +``` + +**示例 3:** +``` +输入: +nums1 = [3, 9] +nums2 = [8, 9] +k = 3 +输出: +[9, 8, 9] +``` + + +**相关话题** +贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/322-CoinChange/official.md b/_site/leetcode/322-CoinChange/official.md new file mode 100644 index 0000000..1e9be82 --- /dev/null +++ b/_site/leetcode/322-CoinChange/official.md @@ -0,0 +1,3 @@ +**322. 零钱兑换** +--- +[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) diff --git a/_site/leetcode/338-CountingBits/bigablecat.md b/_site/leetcode/338-CountingBits/bigablecat.md new file mode 100644 index 0000000..c5659b9 --- /dev/null +++ b/_site/leetcode/338-CountingBits/bigablecat.md @@ -0,0 +1,104 @@ +**338. 比特位计数** +--- + +[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) + +* 网友高效Java解法 + +```java + + public int[] countBits(int num) { + //新建一个数组,数组长度为num+1 + //因为题设 0 ≤ i ≤ num,从0到num总共需要num+1的空间 + int[] res = new int[num + 1]; + //从i=1开始,在num的长度内进行遍历 + //因为0的二进制数里位1的个数为0,res[0]的值本身就等于0,所以i=0无需统计 + for (int i = 1; i <= num; i++) { + //i & (i - 1)的位与运算会消去i的二进制数中最低有效的1位 + //所以正整数i的二进制数中位1的个数,与i & (i - 1)相比少了1个 + //res[i & (i - 1)]找到正整数i & (i - 1)中位1的个数 + //再多加1个,即得到正整数i中位1的个数 + res[i] = res[i & (i - 1)] + 1; + // 完整过程举例: + // 假设 i = 6,n的32位二进制数的最右边四位是 0110 + // i - 1 的32位二进制数的最右边四位是 0101 + // i & (i-1),即 0110 & 0101 = 0100 + // 原本 0110 中的最低有效1位被消去,即右向左数的第一个1 + } + return res; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +方法只用了一个循环,取决于整数num的大小, +所以时间复杂度是O(n) + +空间复杂度:O(n), +新建数组res,占用了n+1的空间, +所以空间复杂度是O(n) + +--- + +* 网友高票Java解法 + +```java + + public int[] countBits(int num) { + //新建一个数组,数组长度为num+1 + //因为题设 0 ≤ i ≤ num,从0到num总共需要num+1的空间 + int[] f = new int[num + 1]; + //从i=1开始,在num的长度内进行遍历 + //因为0的二进制数里位1的个数为0,f[0]的值本身就等于0,所以i=0无需统计 + for (int i = 1; i <= num; i++) { + // i >> 1 二进制右移1位,相当于整数运算中的 i / 2 + // i & 1 二进制的位与运算,相当于整数运算中的 i % 2 + // 数组f记录了每个相应位置正整数的二进制数里位1的个数 + // f[i/2]就是i/2这个正整数的二进制数里位1的个数 + // 加上 i % 2,也就是这个正整数模2的余数 + // 每一个正整数i,都遵循 f[i] = f[i/2] + (i%2) + f[i] = f[i >> 1] + (i & 1); + // 为什么会有上述结果 + // 实际上是这行代码利用了正整数转二进制数计算方法中的规律; + // 正整数转二进制数就是该正整数与2相除得到的整数结果继续除以2 + // 重复上述计算,直到运算结果等于1为止, + // 假设运算过程中有n次余数为1,那么二进制数中就n+1个位1 + // 其中n加上1是最终运算结果里的1 + // 举例如下: + // 9/2 = 4...1 + // 4/2 = 2...0 + // 2/2 = 1...0 + // 9在与2相除的过程中,出现了1次余数为1的情况, + // 最终结果为1,运算中总共出现了2次1,所以9的二进制数中有2个1 + // 从上述计算中还可以发现,9的二进制数中有多少个1, + // 可以参照9/2的正整数结果4的二进制数中有多少个1, + // 用4的二进制数中1的个数,加上9/2的余数,即9的二进制数中1的个数 + // f[i] = f[i >> 1] + (i & 1); 正是利用了上述规律 + } + return f; + } + + +``` + +**复杂度分析** + +时间复杂度:O(n), +方法只用了一个循环,取决于整数num的大小, +所以时间复杂度是O(n) + +空间复杂度:O(n), +新建数组f,占用了n+1的空间, +所以空间复杂度是O(n) + +--- + +**参考资料** + +* 网友高效Java解法: +[https://leetcode-cn.com/submissions/api/detail/338/java/1](https://leetcode-cn.com/submissions/api/detail/338/java/1) + +* 网友高票Java解法: +[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) diff --git a/_site/leetcode/343-IntegerBreak/hatrick.md b/_site/leetcode/343-IntegerBreak/hatrick.md new file mode 100644 index 0000000..7f62daf --- /dev/null +++ b/_site/leetcode/343-IntegerBreak/hatrick.md @@ -0,0 +1,38 @@ +**343. 整数拆分** +--- +[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) + +解决方案 +**思路** +建立一个乘积数组,数组的下标i存放这i所能拆分之后的最大乘积,然后下标为n的数的最大乘积可以表示为两个更小的数所能拆分的乘积之和, +而这两个更小的数可以进一步拆分,不过这一步已经被记录在乘积数组中了,我们不必再考虑进一步的拆分 +``` +class Solution { + public int integerBreak(int n) { + int[] product =new int[n+1]; + //product数组用来存放数i所能拆分的最大乘积 + product[1]=1; + for(int i=1;i<=n;i++) + { + int a=1,b=i-1; + while(a<=b&&a+b==i) + { + int multi =(product[a]>a?product[a]:a)*(product[b]>b?product[b]:b); + //将数i拆分成a和b,要想产生最大乘积,我们需要选出a所拆分出的乘积和a本身中较大的一个数 + if(product[i]nums[i+1],这样循环就判断前面的数字能否整除后面的数字。定义一个数组dp,其中dp[i]表示数字nums[i]位置最大可整除的子集合的长度,还需要一个数组parent,来保存上一个整除的数字的位置,两个整型变量max和max_idx分别表示最大子集合的长度和起始数字位置,遍历数组。 + +1.数组排序 + +2.递归动态规划规律 如果nums[j]能整除nums[i], 且dp[i] < dp[j] + 1的话,更新dp[i]和parent[i],如果dp[i]大于max了,更新max和max_idx + +3.最后循环结束后,我们来填res数字,根据parent数组来找到每一个数字 + +**具体代码** + +``` +public List largestDivisibleSubset(int[] nums) { + + if (nums == null || nums.length == 0) { + return new ArrayList<>(); + } + Arrays.sort(nums); + int n = nums.length; + int[] dp = new int[n]; + int[] parent = new int[n]; + int max = 0, max_idx = 0; + for (int i = 0; i < n; i++) { + dp[i] = 1; + parent[i] = -1; + for (int j = 0; j < i; j++) { + if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) { + dp[i] = dp[j] + 1; + parent[i] = j; + } + } + if (max < dp[i]) { + max = dp[i]; + max_idx = i; + } + } + List res = new ArrayList<>(); + do { + res.add(nums[max_idx]); + max_idx = parent[max_idx]; + } while (max_idx != -1); + return res; +} + +``` +**时间复杂度** O(N^2) + + +leetcode 代码提交后执行时间48ms只击败了30%的用户有待优化 + +思路类似,cache一些数据优化执行效率42ms + +``` +public List largestDivisibleSubset(int[] nums) { + List> list = new ArrayList(); + if(nums.length < 1) return new ArrayList(); + int max = 0; + int p = 0; + for(int k = 0; k < nums.length; k++){ + list.add(k, new ArrayList()); + } + + if(nums.length >= 1){ + Arrays.sort(nums); + int[] leng = new int[nums.length]; + int j = 0; + for(int i = 0; i < nums.length; i++){ + for(j = i - 1; j >= 0; j--){ + if(nums[i] % nums[j] == 0 && nums[i] > nums[j]){ + if(leng[i] < leng[j] + 1){ + leng[i] = leng[j] + 1; + list.set(i,new ArrayList(list.get(j))); + list.get(i).add(nums[i]); + if(max < leng[i]) { + max = leng[i]; + p = i; + } + } + } + } + if(j < 0 && leng[i] == 0) { + list.get(i).add(nums[i]); + leng[i] = 1; + } + + } + } + return list.get(p); +} + +``` +leetcode上star效率更高的解法 [具体地址](https://leetcode.com/problems/largest-divisible-subset/discuss/83999/Easy-understood-Java-DP-solution-in-28ms-with-O(n2)-time) + + diff --git a/_site/leetcode/374-GuessNumberHigherOrLower/official.md b/_site/leetcode/374-GuessNumberHigherOrLower/official.md new file mode 100644 index 0000000..677d387 --- /dev/null +++ b/_site/leetcode/374-GuessNumberHigherOrLower/official.md @@ -0,0 +1,3 @@ +**374. 猜数字大小** +--- +[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) diff --git a/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md b/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md new file mode 100644 index 0000000..24d3f34 --- /dev/null +++ b/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md @@ -0,0 +1,3 @@ +**375. 猜数字大小 II** +--- +[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) diff --git a/_site/leetcode/376-WiggleSubsequence/melody-l.md b/_site/leetcode/376-WiggleSubsequence/melody-l.md new file mode 100644 index 0000000..cfe0036 --- /dev/null +++ b/_site/leetcode/376-WiggleSubsequence/melody-l.md @@ -0,0 +1,61 @@ +**376.WiggleSubsequence** +--- +[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) + +方法一:贪心算法 +官方题解的dp算法实际上也是再找波峰与波谷的个数,所以个人倾向于贪心的思想更多一点。 + +贪心的思想是:对于摆动序列,只要有序列存在摆动的地方,那么这个摆动处的元素就得加入到结果集中。我们就是要计算摆动的个数。 +所以算法思路为:记录第一次出现波峰(nums[i+1]-nums[i]>0)或者波谷(nums[i+1]-nums[i]<0)的位置和状态,序列长度加一。按顺序查找序列,寻找一个与之前状态相反的状态,(即若之前状态是波峰则当前状态应该是波谷),找到后改变当前状态,序列长度加一,继续寻找。 + +```java +class Solution { + public int wiggleMaxLength(int[] nums) { + // 如果数组长度小于2,则不会有波动 + if (nums.length < 2) return nums.length; + // 如果没有波动序列,那么值应该为1,所以初始值设为1 + int size = 1; + // 下一个应该正(波峰)还是负(波谷)的标识量 + int nextSignal = nums[0]-nums[1]; + // 由于刚开始就计算了两个,因此判断起初计算的两个有没有波峰或波谷, + // 若有,则序列长度加一 + if(nextSignal!=0) size++; + + // 从第二个开始,向后面看, + // 如果发现存在波峰波谷交替出现,那么就保存到结果中 + for (int i=1; i 0) { + // 如果当前的状态(即当前是波峰或者波谷)和标识量(下一个应该是波峰还是波谷)是一致的, + // 则将结果加一, + // 当前状态改变为相反的状态 + size++; + nextSignal = -temp; + } else if (nextSignal==0 && temp!=0){ + // 若状态码为0,则说明之前一直都是相同的数字,没有起伏 + // 若temp不为0,则说明此时索引处的数字有起伏 + // 因此,下一个状态为此时索引处的相反状态, + // 然后结果加一 + nextSignal = -temp; + size++; + } + + // 备注:两个条件可以合并,这里是为了方便理解,所以分开写 + } + + return size; + } +} +``` + +--- + + +**参考资料** + +* 官方题解: +[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) diff --git a/_site/leetcode/376-WiggleSubsequence/official.md b/_site/leetcode/376-WiggleSubsequence/official.md new file mode 100644 index 0000000..17278c7 --- /dev/null +++ b/_site/leetcode/376-WiggleSubsequence/official.md @@ -0,0 +1,3 @@ +**376. 摆动序列变** +--- +[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) diff --git a/_site/leetcode/377-CombinationSumIV/official.md b/_site/leetcode/377-CombinationSumIV/official.md new file mode 100644 index 0000000..6831959 --- /dev/null +++ b/_site/leetcode/377-CombinationSumIV/official.md @@ -0,0 +1,3 @@ +**377. 组合总和 Ⅳ** +--- +[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) diff --git a/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md b/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md new file mode 100644 index 0000000..6ed3e49 --- /dev/null +++ b/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md @@ -0,0 +1,22 @@ +**378. 有序矩阵中第K小的元素** +--- +[https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/](https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/) + +给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 +请注意,它是排序后的第k小元素,而不是第k个元素。 + +示例: + +``` +matrix = [ + [ 1, 5, 9], + [10, 11, 13], + [12, 13, 15] +], +k = 8, + +返回 13。 +``` + +**说明:** +你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。 diff --git a/_site/leetcode/392-IsSubsequence/official.md b/_site/leetcode/392-IsSubsequence/official.md new file mode 100644 index 0000000..885cbdf --- /dev/null +++ b/_site/leetcode/392-IsSubsequence/official.md @@ -0,0 +1,3 @@ +**392. 判断子序列** +--- +[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) diff --git a/_site/leetcode/392-IsSubsequence/zengdiqing1994.md b/_site/leetcode/392-IsSubsequence/zengdiqing1994.md new file mode 100644 index 0000000..f49497c --- /dev/null +++ b/_site/leetcode/392-IsSubsequence/zengdiqing1994.md @@ -0,0 +1,90 @@ +##### 392. 判断子序列 + +https://leetcode-cn.com/problems/is-subsequence/ + +给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 + +你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 + +字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 + +示例 1: +s = "abc", t = "ahbgdc" + +返回 true. + +示例 2: +s = "axc", t = "ahbgdc" + +返回 false. + +后续挑战 : + +如果有大量输入的 S,称作S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码? + +**思路:** + +这里又用到了双指针: + +s: a b c + + | + + s_p + + +t: a h b g c k + + | + + t_p + + +这里我们不断移动t_p指针,看t_p指向的元素是否和s_p指向的相等,如果不相等的话继续移动t_p,如果相等的话也一并移动s_p,直到t_p到达了t的边界。在这期间, +如果s_p已经到达了s的边界的话,就直接返回True。若整个循环结束,就是t遍历完都没有返回true的话,就说明不存在,返回false + +代码: +``` +class Solution: + def isSubsequence(self, s, t): + if s == None or t == None: #判断字符串的是否为空 + return False + + len_s = len(s) #长度获取 + len_t = len(t) + if len_t < len_s: #判断长度的真实性 + return False + if len_s == 0: + return True + j=0 + for i in range(len_t): #若对于t串来讲,若和s相等,就继续移动 + if s[j] == t[i]: + j+=1 + if j == len_s: #最终如果移动的次数和s的长度相等就返回True + return True + return False +``` +这里的时间复杂度是O(t*s) + +python内置了find()函数可以快速定位字符的位置 +``` +class Solution: + def isSubsequence(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + for seq_s in s: + s_index = t.find(seq_s) + if s_index == -1: + return False + if s_index == len(t) - 1: #如果找到的匹配的s达到了t的长度 + t = str() #字符串长度赋给t + else: + t = t[s_index+1:] #若还没匹配完,从下一个开始继续 + return True +``` +这里时间复杂度稍微低一些,为O(t*logs) + +参考:https://blog.csdn.net/fuxuemingzhu/article/details/79568772 diff --git a/_site/leetcode/403-FrogJump/README.md b/_site/leetcode/403-FrogJump/README.md new file mode 100644 index 0000000..bfb5af2 --- /dev/null +++ b/_site/leetcode/403-FrogJump/README.md @@ -0,0 +1,47 @@ +**403. 青蛙过河** +--- +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +**难度** +困难 + +**题目描述** + +一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 + +给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 + +如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 + +**请注意:** + +* 石子的数量 ≥ 2 且 < 1100; +* 每一个石子的位置序号都是一个非负整数,且其 < 231; +* 第一个石子的位置永远是0。 + +**示例 1:** +```shell +[0,1,3,5,6,8,12,17] + +总共有8个石子。 +第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, +第三个石子在序号为3的单元格的位置, 以此定义整个数组... +最后一个石子处于序号为17的单元格的位置。 + +返回 true。即青蛙可以成功过河,按照如下方案跳跃: +跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 +跳2个单位到第4块石子, 然后跳3个单位到第6块石子, +跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 +``` + +**示例 2:** +```shell + +[0,1,2,3,4,8,9,11] + +返回 false。青蛙没有办法过河。 +这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 +``` + +**相关话题** +贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/403-FrogJump/official.md b/_site/leetcode/403-FrogJump/official.md new file mode 100644 index 0000000..bfb5af2 --- /dev/null +++ b/_site/leetcode/403-FrogJump/official.md @@ -0,0 +1,47 @@ +**403. 青蛙过河** +--- +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +**难度** +困难 + +**题目描述** + +一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 + +给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 + +如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 + +**请注意:** + +* 石子的数量 ≥ 2 且 < 1100; +* 每一个石子的位置序号都是一个非负整数,且其 < 231; +* 第一个石子的位置永远是0。 + +**示例 1:** +```shell +[0,1,3,5,6,8,12,17] + +总共有8个石子。 +第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, +第三个石子在序号为3的单元格的位置, 以此定义整个数组... +最后一个石子处于序号为17的单元格的位置。 + +返回 true。即青蛙可以成功过河,按照如下方案跳跃: +跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 +跳2个单位到第4块石子, 然后跳3个单位到第6块石子, +跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 +``` + +**示例 2:** +```shell + +[0,1,2,3,4,8,9,11] + +返回 false。青蛙没有办法过河。 +这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 +``` + +**相关话题** +贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/409-LongestPalindrome/README.md b/_site/leetcode/409-LongestPalindrome/README.md new file mode 100644 index 0000000..88bd80e --- /dev/null +++ b/_site/leetcode/409-LongestPalindrome/README.md @@ -0,0 +1,23 @@ +**409. 最长回文串** +--- +[https://leetcode-cn.com/problems/longest-palindrome/](https://leetcode-cn.com/problems/longest-palindrome/) + +给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 + +在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。 + +注意: +假设字符串的长度不会超过 1010。 + +示例 1: + +``` +输入: +"abccccdd" + +输出: +7 + +解释: +我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。 +``` diff --git a/_site/leetcode/410-SplitArrayLargestSum/hatrick.md b/_site/leetcode/410-SplitArrayLargestSum/hatrick.md new file mode 100644 index 0000000..8b449ac --- /dev/null +++ b/_site/leetcode/410-SplitArrayLargestSum/hatrick.md @@ -0,0 +1,55 @@ +**410. 分割数组的最大值** +--- +[https://leetcode-cn.com/problems/split-array-largest-sum/](https://leetcode-cn.com/problems/split-array-largest-sum/) + +解决方案 +**思路** +使用二分法,首先可以发现,难点在于怎么判断分割是否可行,可以发现,当m=1的时候肯定可行(和最大,全部元素在一块), +当m=nums.length的时候也可行(和最小,为全部元素中的最大值),那么就二分这个最大和最小值就可以了,判断是否可分, +可分就将和缩小,使得需要的m值变小;反之则扩大 +``` +//使用二分法进行动态查找 +public int splitArray(int[] nums, int m) { + long left = 0, right = 0; + for (int n: nums) { + right += n; + } + if (m == 1) { + return (int)right; + } + long result = 0; + long mid; + while (left <= right) { + mid = left+right >> 1; + if (judge(mid, nums, m)) { + result = mid; + right = mid-1; + } else { + left = mid+1; + } + } + return (int)result; + } + + private boolean judge(long mid, int[] nums, int m) { + int sum = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] > mid) { + return false; + } + if (sum + nums[i] > mid) { + sum = nums[i]; + m--; + } else { + sum += nums[i]; + } + } + return m >= 1; + } +``` +**复杂度分析** +平均时间复杂度:O(nlogn) +空间复杂度:O(1) + +**参考资料** +[https://blog.csdn.net/zhangjingao/article/details/86607677](https://blog.csdn.net/zhangjingao/article/details/86607677) \ No newline at end of file diff --git a/_site/leetcode/410-SplitArrayLargestSum/official.md b/_site/leetcode/410-SplitArrayLargestSum/official.md new file mode 100644 index 0000000..6b0e45b --- /dev/null +++ b/_site/leetcode/410-SplitArrayLargestSum/official.md @@ -0,0 +1,3 @@ +**410. 分割数组的最大值** +--- +[https://leetcode-cn.com/problems/split-array-largest-sum/](https://leetcode-cn.com/problems/split-array-largest-sum/) diff --git a/_site/leetcode/413-arithmeticSlices/official.md b/_site/leetcode/413-arithmeticSlices/official.md new file mode 100644 index 0000000..d925d9a --- /dev/null +++ b/_site/leetcode/413-arithmeticSlices/official.md @@ -0,0 +1,3 @@ +**413. 等差数列划分** +--- +[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) diff --git a/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md b/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md new file mode 100644 index 0000000..85ae787 --- /dev/null +++ b/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md @@ -0,0 +1,104 @@ +**416. 分割等和子集** +--- +[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) + +* 网友高票Java解法 + +```java + + /** + * https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation + * 网友高票Java解法 + * + * @param nums + * @return + */ + public static boolean canPartition(int[] nums) { + int sum = 0; + + //遍历数组,求得所有数字之和 + for (int num : nums) { + sum += num; + } + + //sum & 1位运算用于判断数字的奇偶 + //1的二进制是0000...0001 即前面31位都是0,第32位是1 + //偶数的二进制末尾是0,奇数的二进制末尾是1 + //其他任何二进制数与1进行位与运算,结果只有0和1两种 + //如果sum是奇数,不能再分为相等的两个整数,不符合题意 + if ((sum & 1) == 1) { + return false; + } + //假设当前数组符合题意,即有两个子集的元素之和相等 + //sum /= 2得到其中一个子集的所有元素之和 + sum /= 2; + + //定义一个boolean数组dp + //数组的长度是sum+1 + //数组中的每一个元素dp[i]表示数字i能否由数组nums中的元素求和得到 + boolean[] dp = new boolean[sum + 1]; + //当和等于0时,必定有0相加得0,所以dp[0]为true + //dp[0]是整个dp数组的基数,其他元素的真值由dp[0]得到 + dp[0] = true; + + //再次遍历数组nums + for (int num : nums) { + //根据sum的大小进行sum次迭代 + for (int i = sum; i > 0; i--) { + //i的值由nums中的元素相加得到 + //下面的语句判断i是否包含了num + //当 i >= num 时,i可能包含了num + if (i >= num) { + //如果 i 包含num + //那么 i-num 是由num之外的另外若干元素相加得到 + //dp[i]表示i是否由数组中的元素相加得到 + //dp[i]的真值应该和dp[i - num]保持一致 + //只要dp[i]和dp[i - num]中有一个为真,说明dp[i]为真 + dp[i] = dp[i] || dp[i - num]; + //实际上所有真值都是通过基础值dp[0]推算而来 + //例如,当i=num时,必定有i-num = 0 + //那么dp[i] = dp[i] || dp[i-num] = dp[i] || dp[0] = dp[i] || true = true + //nums中的元素num必定可以通过自身的值求和得到,所以dp[i]为真是正确的 + } + } + } + //dp[sum]即表示sum是否可以通过数组nums的值相加而来 + return dp[sum]; + } + +``` + +**复杂度分析** + +时间复杂度:O(n^2), +根据题设,nums是正整数非空数组, +那么nums的任意一个元素nums[i]>=1, +sum是所有nums元素的和, +在进入循环前经过了折半处理, +所以sum >= nums.length()/2, +将sum看做n,那么nums.length()<=n*2, +本解法中有1个独立的for循环, +遍历nums数组1次, +时间复杂度<=O(n*2), +另有一对嵌套for循环, +嵌套for循环的外循环遍历数组nums一次, +时间复杂度<=O(n*2), +嵌套for循环的内循环与sum的大小一致, +内循环的复杂度为O(n), +嵌套循环的时间复杂<=O(n*2*n)=O(2n^2), +再加上独立的for循环, +总的时间复杂度<=O(n*2 + 2n^2), +消去低阶项n*2和常数系数2, +最终的时间复杂度<=O(n^2) + +空间复杂度:O(n), +创建了一个sum+1大小的boolean数组, +占用了n+1的空间, +空间复杂度为O(n) + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) diff --git a/_site/leetcode/416-PartitionEqualSubsetSum/official.md b/_site/leetcode/416-PartitionEqualSubsetSum/official.md new file mode 100644 index 0000000..2f25f64 --- /dev/null +++ b/_site/leetcode/416-PartitionEqualSubsetSum/official.md @@ -0,0 +1,3 @@ +**416. 分割等和子集** +--- +[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) diff --git a/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md b/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md new file mode 100644 index 0000000..76e8b99 --- /dev/null +++ b/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md @@ -0,0 +1,3 @@ +**446. 等差数列划分 II - 子序列** +--- +[https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/](https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/) diff --git a/_site/leetcode/455-AssignCookies/SpecialYang.md b/_site/leetcode/455-AssignCookies/SpecialYang.md new file mode 100644 index 0000000..94ec505 --- /dev/null +++ b/_site/leetcode/455-AssignCookies/SpecialYang.md @@ -0,0 +1,34 @@ +**分发饼干** +https://leetcode.com/problems/assign-cookies/ +--- +### 思路一 +说实话,我看的是英文版,第一次竟然没读懂题意了,打扰了! +后来看了翻译,才明白题意:现在有一堆孩子,每个孩子的胃口不一样,有一堆饼干,饼干的大小也不一。我们的目标是把这些饼干尽可能多的分配给这些小朋友,求出最多满足多少个小朋友。 +1. 只要饼干的尺寸大于等于孩子胃口,才可以满足 +2. 一个饼干只能分给一个小朋友,一个小朋友只能吃一个饼干 + + +典型的**贪心**做法,我们只需把最接近孩子胃口的饼干分配给对应的孩子即可,这样我们就可以把更大的饼干分给胃口更大的孩子。即优先使用最满足孩子胃口的饼干分配。 + +我们可以对孩子和饼干分配从小到大排序,然后遍历饼干,判断饼干与当前孩子大小关系,若满足,则分配给孩子,换下一个孩子和下一个饼干;若不满足,换下一个饼干与当前的孩子比较。 +```java + /** + * 优先把尺寸接近孩子胃口的饼干分发 + * + * 局部最优 + * @param g + * @param s + * @return + */ + public int findContentChildren(int[] g, int[] s) { + Arrays.sort(g); + Arrays.sort(s); + int child = 0, size = 0; + while (child < g.length && size < s.length) { + if (g[child] <= s[size++]) { + child++; + } + } + return child; + } +``` \ No newline at end of file diff --git a/_site/leetcode/455-AssignCookies/bigablecat.md b/_site/leetcode/455-AssignCookies/bigablecat.md new file mode 100644 index 0000000..65122e3 --- /dev/null +++ b/_site/leetcode/455-AssignCookies/bigablecat.md @@ -0,0 +1,56 @@ +**455. 分发饼干** +--- + +[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) + +* 网友高票Java解法 + +```java + + public int findContentChildren(int[] g, int[] s) { + //调用java.util.Arrays.sort排序方法 + //分别给孩子期望和饼干大小排序 + Arrays.sort(g); + Arrays.sort(s); + int i = 0; //定义数组g的下标初始值i + //遍历数组s + for (int j = 0; i < g.length && j < s.length; j++) { + //g[i]是数组g在i位置的元素,表示第i个孩子的胃口 + //s[j]是数组s在j位置的元素,表示第j个饼干的尺寸 + //经过排序,g[i]从孩子最小的胃口开始 + //g[i]<=s[j]说明j位置的饼干可以满足第i个孩子 + //此时让i++,看s[j]是否能满足更大胃口的孩子 + if (g[i] <= s[j]) i++; + } + //最后返回的i就是最多能满足多少个孩子 + return i; + } + +``` + +**复杂度分析** + +时间复杂度:O(nlogn), +设两个数组的长度分别是 m 和 n +Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进, +时间复杂度稳定为O(nlogn), +Arrays.sort使用了两次,所以排序的时间复杂度是 +mlogm + nlogn, +for循环内虽然对两个数组进行操作, +但是两个数组都没有被重复从头遍历, +所以最坏情况的遍历次数是两个数组的长度之和 +m+n, +最终的时间复杂度是 +O(mlogm + nlogn + m + n) = O(nlogn) + +空间复杂度:O(n), +Arrays.sort排序方法的空间复杂度是O(n), +使用了两次,所以空间复杂度是O(2n), +最终的空间复杂度是O(n) + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) diff --git a/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md b/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md new file mode 100644 index 0000000..e172f8f --- /dev/null +++ b/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md @@ -0,0 +1,20 @@ +**462. 最少移动次数使数组元素相等 II** +--- +[https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/](https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/) + +给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。 + +``` +例如: + +输入: +[1,2,3] + +输出: +2 + +说明: +只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1): + +[1,2,3] => [2,2,3] => [2,2,2] +``` diff --git a/_site/leetcode/464-CanIWin/official.md b/_site/leetcode/464-CanIWin/official.md new file mode 100644 index 0000000..b49b347 --- /dev/null +++ b/_site/leetcode/464-CanIWin/official.md @@ -0,0 +1,3 @@ +**464. 我能赢吗** +--- +[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) diff --git a/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md b/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md new file mode 100644 index 0000000..e046179 --- /dev/null +++ b/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md @@ -0,0 +1,85 @@ +#467. 环绕字符串中唯一的子字符串 + +Leetcode 地址 [https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) + +**题目分析** + +该题的一个非常重要的隐藏条件是,改字符串里面所有的字母都是由26个字母的顺序前后相连的。比如xyzabc,子字符串就是xyz,或者abc 这里只是穷举部分。所以题目的意思是,找出字符串p所有子串中,每个字母按照字母表顺序相连的子串。按照字母表顺序相连,即意味着前字符的ascii码比后字符小1,或者后字符比前字符小25(字符z与字符a的情况)。 + +**思路:** + +1.符合条件的子串中字符是顺序相连的,所以如果子串的前n个字符符合条件,那么第n+1个字符和第n个字符也是相连的,那么这n+1个字符肯定也是符合条件的 + +2.由于符合条件的子串中字符是顺序相连的,那么这个子串的长度有多长,就有多少种以该子串最后一个字符为结尾的小子串 + +3.题目只是找出唯一的子串数量,那么以某个字符为结尾的子串,无论该字符出现在哪,它所可能组成的子串都是一样的,所以我们只需要找到能组成最长子串的那个位置就行了。 + +4.找出每个字符所能组成的唯一子串数量,然后求和 + +**具体代码** + +``` +public int findSubstringInWraproundString(String p) { + int[] count = new int[26]; + int maxLength = 0; + + for (int i = 0; i < p.length(); i++) { + if (i > 0 && (p.charAt(i) - p.charAt(i - 1) == 1 || (p.charAt(i - 1) - p.charAt(i) == 25))) {// + maxLength++; + } + else { + maxLength = 1; + } + + int index = p.charAt(i) - 'a'; + count[index] = Math.max(count[index], maxLength); + } + + // Sum to get result + int sum = 0; + for (int i = 0; i < 26; i++) { + sum += count[i]; + } + return sum; +} + +``` +**时间复杂度** O(N) + +**空间复杂度** O(1) + +leetcode 代码提交后发现只击败了38%的用户有待优化 + +后来发现双指针解法,感叹大牛的解法代码如下 + +``` +public int findSubstringInWraproundStringPoint(String p) { + if (p == null || p.length() == 0) { + return 0; + } + int[] ways = new int[125]; + char[] cs = p.toCharArray(); + int left = 0; + int right = 1; + // NOTE: even if right == cs.length, can still go into the loop, to handle the "a" case (single char) + while (right <= cs.length) { + while (right < cs.length && ((cs[right] - cs[right-1] == 1) || (cs[right] == 'a' && cs[right-1] == 'z'))) { + right++; + } + while (left < right) { + ways[cs[left]] = Math.max(ways[cs[left]], right - left); + left++; + } + right++; + } + int sum = 0; + for (int way : ways) { + sum += way; + } + return sum; +} + +``` +[具体地址](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95440/Two-pointers-Java-solution-beats-100) + + diff --git a/_site/leetcode/472-ConcatenatedWords/official.md b/_site/leetcode/472-ConcatenatedWords/official.md new file mode 100644 index 0000000..fc433c5 --- /dev/null +++ b/_site/leetcode/472-ConcatenatedWords/official.md @@ -0,0 +1,3 @@ +**472. 连接词** +--- +[https://leetcode-cn.com/problems/concatenated-words/](https://leetcode-cn.com/problems/concatenated-words/) diff --git a/_site/leetcode/474-OnesAndZeroes/hatrick.md b/_site/leetcode/474-OnesAndZeroes/hatrick.md new file mode 100644 index 0000000..b8781a6 --- /dev/null +++ b/_site/leetcode/474-OnesAndZeroes/hatrick.md @@ -0,0 +1,47 @@ +**474. 一和零** +--- +[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) + +解决方案 +**思路** +和01背包是很相似的题目,只不过背包问题是装一种东西,而我们这道题要求的是装上两种东西,也就是1和0。 +我们的1和0相当于两类物品,n和m就是它们所对应的容量。 +我们的到第i个字符串时, 它所对应的可以组成最多的字符串个数则就对应为: +dp[m][n]=MAX(dp[m][n],dp[m-count0][n-count1]+1) +所以我们要做的就是在迭代字符串的时候,即时更新dp[m][n];也就是说每多一个字符串,我就计算一下加进来这个字符串之后,我所能拼接成的最大字符串数量。 +也就是说 当我只有一个字符串的时候,我求出我的dp[m][n],当我有两个字符串的时候,我根据上面的情况,在继续求出我现在的dp[m][n], 每多一个,就更新一下。 +注意dp[m][n]是随着迭代而更新的 +``` +class Solution { + //0-1背包问题,优化存储空间 + public int findMaxForm(String[] strs, int m, int n) { + int l = strs.length; + int zeros, ones; + // dp[i][j]代表遍历到当前字符串时使用i个0和j个1所能组成的最大字符串数量 + int[][] dp = new int[m+1][n+1]; + for(int i = 0; i < l ; i++){ + zeros = 0; + ones = 0; + for(int j = 0; j < strs[i].length(); j++){ + if(strs[i].charAt(j) == '0'){ + zeros++; + }else{ + ones++; + } + } + for(int j = m; j >= zeros; j--){ + for(int k = n; k >= ones; k--){ + dp[j][k] = Math.max(dp[j][k], dp[j-zeros][k-ones] + 1); + } + } + } + return dp[m][n]; + } +} +``` +**复杂度分析** +时间复杂度:O(n) +空间复杂度:O(n) + +**参考资料** +[https://blog.csdn.net/qq_38595487/article/details/84235304](https://blog.csdn.net/qq_38595487/article/details/84235304) \ No newline at end of file diff --git a/_site/leetcode/474-OnesAndZeroes/official.md b/_site/leetcode/474-OnesAndZeroes/official.md new file mode 100644 index 0000000..3a329af --- /dev/null +++ b/_site/leetcode/474-OnesAndZeroes/official.md @@ -0,0 +1,3 @@ +**474. 一和零** +--- +[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) diff --git a/_site/leetcode/486-PredictTheWinner/official.md b/_site/leetcode/486-PredictTheWinner/official.md new file mode 100644 index 0000000..c74a6b6 --- /dev/null +++ b/_site/leetcode/486-PredictTheWinner/official.md @@ -0,0 +1,3 @@ +**486. 预测赢家** +--- +[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) diff --git a/_site/leetcode/494-TargetSum/official.md b/_site/leetcode/494-TargetSum/official.md new file mode 100644 index 0000000..be7767e --- /dev/null +++ b/_site/leetcode/494-TargetSum/official.md @@ -0,0 +1,3 @@ +**494. 目标和** +--- +[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) diff --git a/_site/leetcode/504-Base7/README.md b/_site/leetcode/504-Base7/README.md new file mode 100644 index 0000000..9f127ba --- /dev/null +++ b/_site/leetcode/504-Base7/README.md @@ -0,0 +1,21 @@ +**504. 七进制数** +--- +[https://leetcode-cn.com/problems/base-7/](https://leetcode-cn.com/problems/base-7/) + +给定一个整数,将其转化为7进制,并以字符串形式输出。 + +示例 1: + +``` +输入: 100 +输出: "202" +``` + +示例 2: + +``` +输入: -7 +输出: "-10" +``` + +注意: 输入范围是 [-1e7, 1e7] 。 diff --git a/_site/leetcode/514-FreedomTrail/hatrick.md b/_site/leetcode/514-FreedomTrail/hatrick.md new file mode 100644 index 0000000..68cb7ca --- /dev/null +++ b/_site/leetcode/514-FreedomTrail/hatrick.md @@ -0,0 +1,49 @@ +**514. 自由之路** +--- +[https://leetcode-cn.com/problems/freedom-trail/](https://leetcode-cn.com/problems/freedom-trail/) +解决方案 +**思路** +路径搜索问题,或者字符串匹配问题,可以正向或者逆向匹配. +动态规划记录当前的状态result[i][j],即当前匹配到key的第i个字母,ring的第j个字母在12点方向, +要匹配key的下一个字母时,可以从上一个状态顺时针或者逆时针转移到现在的状态. +``` +class Solution { + public int findRotateSteps(String ring, String key) { + if (ring == null || key == null) return 0; + int m = ring.length(); + int n = key.length(); + int[][] result = new int[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + result[i][j] = Integer.MAX_VALUE; + } + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (key.charAt(i) == ring.charAt(j)) { + if (i == 0) { + result[i][j] = Math.min(j, m - j); + } else { + for (int k = 0; k < m; k++) { + if (result[i - 1][k] != Integer.MAX_VALUE) + result[i][j] = Math.min(result[i][j], result[i - 1][k] + Math.min(Math.abs(j - k), m - Math.abs(j - k))); + } + } + } + } + } + int ans = result[n - 1][0]; + for (int j = 1; j < m; j++) { + if (ans > result[n - 1][j]) + ans = result[n - 1][j]; + } + return ans + n; + } +} +``` +**复杂度分析** +平均时间复杂度:O(n*n*n) +空间复杂度:O(n) + +**参考资料** +[https://www.cnblogs.com/kexinxin/p/10372522.html](https://www.cnblogs.com/kexinxin/p/10372522.html) \ No newline at end of file diff --git a/_site/leetcode/514-FreedomTrail/official.md b/_site/leetcode/514-FreedomTrail/official.md new file mode 100644 index 0000000..53a53d6 --- /dev/null +++ b/_site/leetcode/514-FreedomTrail/official.md @@ -0,0 +1,3 @@ +**514. 自由之路** +--- +[https://leetcode-cn.com/problems/freedom-trail/](https://leetcode-cn.com/problems/freedom-trail/) diff --git a/_site/leetcode/516-LongestPalindromicSubsequence/passself.md b/_site/leetcode/516-LongestPalindromicSubsequence/passself.md new file mode 100644 index 0000000..856e1c2 --- /dev/null +++ b/_site/leetcode/516-LongestPalindromicSubsequence/passself.md @@ -0,0 +1,42 @@ +##516. 最长回文子序列 + +LeetCode 地址 [https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) + +**解法一 暴力求解:** + +找到字符串的所有子串,遍历每一个子串以验证它们是否为回文串。一个子串由子串的起点和终点确定,因此对于一个长度为n的字符串,共有n^2个子串。这些子串的平均长度大约是n/2,因此这个解法的时间复杂度是O(n^3)。 + +这样的方式很容易造成超时,比较不可取。 + + +**解法二 动态规划** + +回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,那么dp[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。 + +核心思路就是从左开始遍历,然后不断的从原字符串中拿出1到length-1长度的字串,进行判断 +这里用一个二维数组来表示回文字符串的起始位置和结束位置 + +时间复杂度 O(n^2) + +``` +public static int longestPalindromeSubseq(String s) { + if (s == null || s.length() == 0) { + return 0; + } + int[][] dp = new int[s.length()][s.length()]; + + for (int i = s.length() - 1; i >= 0; --i) { + dp[i][i] = 1; + for (int j = i + 1; j < s.length(); ++j) { + if (s.charAt(j) == s.charAt(i)) { + dp[i][j] = dp[i + 1][j - 1] + 2; + } else { + dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + } + + return dp[0][s.length() - 1]; + } +``` + diff --git a/_site/leetcode/517-SuperWashingMachines/official.md b/_site/leetcode/517-SuperWashingMachines/official.md new file mode 100644 index 0000000..d4b3317 --- /dev/null +++ b/_site/leetcode/517-SuperWashingMachines/official.md @@ -0,0 +1,3 @@ +**517. 超级洗衣机** +--- +[https://leetcode-cn.com/problems/super-washing-machines/](https://leetcode-cn.com/problems/super-washing-machines/) diff --git a/_site/leetcode/523-ContinuousSubarraySum/hatrick.md b/_site/leetcode/523-ContinuousSubarraySum/hatrick.md new file mode 100644 index 0000000..921ba1f --- /dev/null +++ b/_site/leetcode/523-ContinuousSubarraySum/hatrick.md @@ -0,0 +1,90 @@ +**523. 连续的子数组和** +--- +[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) + +解决方案 +**思路** +1.遍历不同长度的子数组,判断是不是能被整除即可.有一个优化点在于可以用动态规划的思路.在len+1长度的子数组遍历时,可以用到len长度的子数组已经计算好的值,不需要再次计算了. +``` + public boolean checkSubarraySum(int[] nums, int k) { + //新增一个数组保存上一轮的全部sum数据 + //这里容易出错的地方在于将sums的数据初始化为0.会造成基础数据就不对. + int[] sums = nums.clone(); + //从len=2开始,进行长度不同的遍历 + for(int len=2;len<=nums.length;len++) { + for(int i = 0; i<=nums.length-len; i++) { + //此时将sums[i]的数据与nums[i+len-1]的数据相加获得新值 + sums[i] += nums[i+len-1]; + //排除掉[0,0],0 的特殊情况 + if(sums[i] ==0) { + return true; + } + //判断当前值是不是可以整除,可以直接返回true + if (k!=0&& sums[i]%k==0) { + return true; + } + } + } + //默认情况 + return false; + } +``` +**复杂度分析** + 时间复杂度:O(N2) + 空间复杂度:O(N) + +--- +2.引入一个概念,前缀和(prefix sum). +给定一个数组x,数组元素为x_0,x_1,x_2,...x_{n-1},x_n +如果有数组y,满足如下条件 +y_0=x_0 +y_1=x_0+x_1 +y_2=x_0+x_1+x_2 +... +y_{n-1}=x_0+x_1+x_2+...+x_{n-1} +y_n=x_0+x_1+x_2+...+x_{n-1}+x_{n} +那么称y为x的前缀和数组 +此时可以发现,数组x的子序列和均可由前缀和数组y获得,如{x_a}至{x_b}子序列的和,可以由y_b-y_{a-1}得到. +而且也可以用到动态规划的思路,一次遍历生成y数组,然后接下来的遍历就可以复用y数组了. +可以直接看文后链接,才疏学浅,大家可以深入理解一下 +``` + public boolean checkSubarraySum(int[] nums, int k) { + //生成前缀和数组,此时已经可以判断一次了 + int[] presums = new int[nums.length]; + for(int i=0;i end) return 0; + if (res[start][end][k] > 0) return res[start][end][k]; + int ans = removeStub(start, end - 1, 0) + (k + 1) * (k + 1); + for (int i = start; i < end; i++) + if (boxes[i] == boxes[end]) { + ans = Math.max(ans, removeStub(start, i, k + 1) + removeStub(i + 1, end - 1, 0)); + } + res[start][end][k] = ans; + return ans; + } + + public int removeBoxes(int[] boxes) { + if (boxes == null || boxes.length == 0) return 0; + int n = boxes.length; + this.res = new int[n][n][n + 1]; + this.boxes = boxes; + return removeStub(0, boxes.length - 1, 0); + } + + public static void main(String[] args) { + int[] array = new int[]{1, 3, 2, 2, 2, 3, 4, 3, 1}; + Leet546 leet546 = new Leet546(); + System.out.println(leet546.removeBoxes(array)); + } +} +``` +**时间复杂度** O(N^4) + +leetcode 代码提交后发现击败了28%的commit + +思路类似,后来优化后 + +``` +class Solution { + public int removeBoxes(int[] boxes) { + if(boxes == null || boxes.length == 0) return 0; + int length = boxes.length; + int[][][] dp = new int[100][100][100]; + return calculatePoints(boxes, dp, 0, boxes.length - 1, 0); + } + + public int calculatePoints(int[] boxes, int[][][] dp, int l, int r, int k) { + if (l > r) { + return 0; + } + if (dp[l][r][k] != 0) { + return dp[l][r][k]; + } + while (r > l && boxes[r] == boxes[r - 1]) { + r--; + k++; + } + dp[l][r][k] = calculatePoints(boxes, dp, l, r - 1, 0) + (k + 1) * (k + 1); + for (int i = l; i < r; i++) { + if (boxes[i] == boxes[r]) { + dp[l][r][k] = Math.max(dp[l][r][k], + calculatePoints(boxes, dp, l, i, k + 1) + calculatePoints(boxes, dp, i + 1, r - 1, 0)); + } + } + return dp[l][r][k]; + } +} + +``` +[参考资料1](https://blog.csdn.net/Wuzihui___/article/details/78714313) + +[参考资料2](https://github.com/lydxlx1/LeetCode/blob/master/src/_546.java) + diff --git a/_site/leetcode/547-friendCircles/bigablecat.md b/_site/leetcode/547-friendCircles/bigablecat.md new file mode 100644 index 0000000..cd25033 --- /dev/null +++ b/_site/leetcode/547-friendCircles/bigablecat.md @@ -0,0 +1,126 @@ +**547. 朋友圈** +--- +[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) + +```java + + /** + * 定义一个并查集的内部类 + */ + class UnionFind { + //计数器 + private int count = 0; + //parent结点集合 + //rank深度 + private int[] parent, rank; + + //定义一个并查集构造器 + public UnionFind(int n) { + //计数器,记录集合中的分组数 + count = n; + //父结点数组 + parent = new int[n]; + //结点高度,或者说结点的辈分 + //rank值越高,结点越靠近根结点 + rank = new int[n]; + //创建时,让每个结点的父结点都指向自身 + for (int i = 0; i < n; i++) { + parent[i] = i; + } + //初始化完成后,得到这样一个并查集 + //所有结点的高度一致 + //所有结点的父结点等于自身,即每个结点自成一组 + //初始化分组数量为n + } + + + /** + * 查找指定结点p的根结点 + * @param p + * @return + */ + public int find(int p) { + //如果当前结点的父结点不等于自身 + while (p != parent[p]) { + //路径压缩,让结点p的父结点指向祖父结点 + parent[p] = parent[parent[p]]; + //让当前结点指向自身的父结点 + p = parent[p]; + } + return p; + } + + /** + * 合并方法 + * + * @param p + * @param q + */ + public void union(int p, int q) { + //查找结点p的根结点 + int rootP = find(p); + //查找结点Q的根结点 + int rootQ = find(q); + //如果两个根节点相等,说明两个结点已经在同一组 + if (rootP == rootQ) return; + //比较两个根结点的rank + if (rank[rootQ] > rank[rootP]) { + //rootQ的rank值高,说明rootQ离根结点更近 + //让rootP的父结点指向rooQ + //即rootP加入rootQ的同组 + parent[rootP] = rootQ; + } else { + //否则,让rootQ加入rootP同组 + parent[rootQ] = rootP; + //如果两个结点的rank值相等 + if (rank[rootP] == rank[rootQ]) { + // rankP已经成为父结点 + // 所以让rootP的高度递增 + rank[rootP]++; + } + } + //实现p和q的分组,计数器递减 + count--; + } + + //获取count值的方法 + public int count() { + return count; + } + } + + public int findCircleNum(int[][] M) { + int n = M.length; + //创建一个矩阵同等长度的并查集uf + UnionFind uf = new UnionFind(n); + //双重嵌套循环,遍历矩阵的每一个结点 + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { + //如果第i个同学和第j个同学互为好友 + //调用uf.union方法将两个同学分到同一个朋友圈 + if (M[i][j] == 1) uf.union(i, j); + } + } + //返回朋友圈的总个数 + return uf.count(); + } + +``` + +**复杂度分析** + +时间复杂度:O(n^n), +嵌套循环进行了n*n次循环, +时间复杂度为O(n^n) + +空间复杂度:O(n), +分别定义了大小为n的int数组parent和rank, +空间复杂度为O(2n), +消去常数项得到O(n) + +--- + +**参考资料** + +* 网友高票Java解法(unionfind): +[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) diff --git a/_site/leetcode/551-StudentAttendanceRecordI/official.md b/_site/leetcode/551-StudentAttendanceRecordI/official.md new file mode 100644 index 0000000..589b73d --- /dev/null +++ b/_site/leetcode/551-StudentAttendanceRecordI/official.md @@ -0,0 +1,3 @@ +**551. 学生出勤记录 I** +--- +[https://leetcode-cn.com/problems/student-attendance-record-i/](https://leetcode-cn.com/problems/student-attendance-record-i/) diff --git a/_site/leetcode/552-StudentAttendanceRecordII/official.md b/_site/leetcode/552-StudentAttendanceRecordII/official.md new file mode 100644 index 0000000..ac3dba7 --- /dev/null +++ b/_site/leetcode/552-StudentAttendanceRecordII/official.md @@ -0,0 +1,3 @@ +**552. 学生出勤记录 II** +--- +[https://leetcode-cn.com/problems/student-attendance-record-ii/](https://leetcode-cn.com/problems/student-attendance-record-ii/) diff --git a/_site/leetcode/576-OutOfBoundaryPaths/official.md b/_site/leetcode/576-OutOfBoundaryPaths/official.md new file mode 100644 index 0000000..dfd9e93 --- /dev/null +++ b/_site/leetcode/576-OutOfBoundaryPaths/official.md @@ -0,0 +1,3 @@ +**576. 出界的路径数** +--- +[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) diff --git a/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md b/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md new file mode 100644 index 0000000..f17f136 --- /dev/null +++ b/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md @@ -0,0 +1,66 @@ +https://leetcode-cn.com/problems/out-of-boundary-paths/ + +576. 出界的路径数 + +思路: 依然是DP动态规划 + +1.这里答案不想要的坐标不是被弃之不理,而是把上一步当前位置的元素代表的可能数加到结果的总个数中,并且此题dp数组每个元素存的不是走到这里的概率,而是 +走到这里的可能总路径数。注意在运算过程要取模。 + +``` +def findPaths(self, m, n, N, i, j): + if N == 0: + return 0 + lastStepCount = [[0 for i in range(n)] for j in range(m)] #对之前坐标进行遍历 + move = [[0, 1], [1, 0], [0, -1], [-1, 0]] #一次只能移动一个上下左右 + lastStepCount[i][j] = 1 #初始化定义 + res, mod = 0, 1000000007 + for step in range(1, N + 1): + currCount = [[0 for i in range(n)] for j in range(m)] #正则表达式循环现在的坐标 + for x in range(m): + for y in range(n): + for direction in move: + lastX, lastY = x + direction[0], y + direction[1] #对坐标进行位置移动 + if any([lastX < 0, lastX >= m, lastY < 0, lastY >= n]): + res = (res + lastStepCount[x][y]) % mod #如果出界了,就直接求出结果 + else: #否则就继续迭移动 + currCount[x][y] = (currCount[x][y] + lastStepCount[lastX][lastY]) % mod + lastStepCount = currCount #重新赋值 + return res +``` +时间复杂度O(N * m * n) + +2.另一种DP思想,从坐标[i, j]到其上、下、左、右都需要移动1步,剩余N-1步,那么问题转化为从上、下、左、右移动N-1步,一共有多少种方法。 + +``` +class Solution: + def findPaths(self, m, n, N, i, j): + tmp=[[[0 for i in range(n)] for j in range(m)] for k in range(N+1)] #坐标和移动次数的三维数组 + for k in range(1,N+1): + for p in range(m): + for q in range(n): + if 0==p: #如果横坐标是0 + up=1 #就可以向上走 + else: + up=tmp[k-1][p-1][q] #否则非0就要走N-1步 + if m-1==p: #如果横坐标已经是左移动1了,那么我们向下移动1 + down=1 + else: + down=tmp[k-1][p+1][q] #否则就是横坐标+1的地方走N-1步 + if 0==q: + left=1 + else: + left=tmp[k-1][p][q-1] #同理左右也是一样 + if n-1==q: + right=1 + else: + right=tmp[k-1][p][q+1] + tmp[k][p][q]=(up+down+left+right)%1000000007 #注意最后的结果要mod那个数 + return tmp[N][i][j] +``` +时间复杂度是O(N * m * n) + +其实这两种方法大体上都是一样的,都是想要求到上一步的情况,那么就直接用DP状态转移来进行递归。 + +参考:https://unclegem.cn/2018/11/01/Leetcode%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-576-%E5%87%BA%E7%95%8C%E7%9A%84%E8%B7%AF%E5%BE%84%E6%95%B0/ +https://www.smwenku.com/a/5c220ee2bd9eee16b4a76a6d/zh-cn/ diff --git a/_site/leetcode/629-KInversePairsArray/official.md b/_site/leetcode/629-KInversePairsArray/official.md new file mode 100644 index 0000000..7ce258c --- /dev/null +++ b/_site/leetcode/629-KInversePairsArray/official.md @@ -0,0 +1,3 @@ +**629. K个逆序对数组** +--- +[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) diff --git a/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md b/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md new file mode 100644 index 0000000..9415842 --- /dev/null +++ b/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md @@ -0,0 +1,117 @@ +![629. K个逆序对数组](https://leetcode-cn.com/problems/k-inverse-pairs-array/submissions/) + +给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。 + +逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > a[j],则其为一个逆序对;否则不是。 + +由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。 + +示例 1: + +输入: n = 3, k = 0 +输出: 1 +解释: +只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。 +示例 2: + +输入: n = 3, k = 1 +输出: 2 +解释: +数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。 + +思路: + +求递推式,时间复杂度O(n * k) + +观察下列推导过程: + +当n=1时,k的取值范围是[0, 0] + +k c + +0 1 1 + +当n=2时,k的取值范围是[0, 1] + +k c + +0 1 1 + +1 1 1 + +当n=3时,k的取值范围是[0, 3] + +k c + +0 1 1 + +1 1 1 2 + +2 1 1 2 + +3 1 1 + +当n=4时,k的取值范围是[0, 6] + +k c + +0 1 1 + +1 2 1 3 + +2 2 2 1 5 + +3 1 2 2 1 6 + +4 1 2 2 5 + +5 1 2 3 + +6 1 1 + +当n=5时,k的取值范围是[0, 10] + +k c + +0 1 1 + +1 3 1 4 + +2 5 3 1 9 + +3 6 5 3 1 15 + +4 5 6 5 3 1 20 + +5 3 5 6 5 3 22 + +6 1 3 5 6 5 20 + +7 1 3 5 6 15 + +8 1 3 5 9 + +9 1 3 4 + +10 1 1 + +这个递推的过程很难想到,就借鉴别人的 + +![思路代码](http://bookshadow.com/weblog/2017/06/25/leetcode-k-inverse-pairs-array/) + +```py +class Solution: + def kInversePairs(self, n: 'int', k: 'int') -> 'int': + MOD = 10**9 + 7 + dp = [1] + for x in range(2, n + 1): + ndp = [] + num = 0 + for y in range(min(1 + x * (x - 1) // 2, k + 1)): #分两种情况 + if y < len(dp): num = (num + dp[y]) % MOD + if y >= x: num = (MOD + num - dp[y - x]) % MOD + ndp.append(num) + dp = ndp + return k < len(dp) and dp[k] or 0 +``` + diff --git a/_site/leetcode/638-ShoppingOffers/bigablecat.md b/_site/leetcode/638-ShoppingOffers/bigablecat.md new file mode 100644 index 0000000..70f7cd4 --- /dev/null +++ b/_site/leetcode/638-ShoppingOffers/bigablecat.md @@ -0,0 +1,134 @@ +**638. 大礼包** +--- +[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) + +```java + + public int shoppingOffers(List price, List> special, List needs) { + //新建一个map用于记录每次的结果 + Map, Integer> map = new HashMap(); + return shopping(price, special, needs, map); + } + + /** + * https://leetcode.com/articles/shopping-offers/ + * 英文官方题解 + * + * + * @param price 商品价格列表 + * @param special 商品大礼包 + * @param needs 待购清单 + * @param map + * @return + */ + public int shopping(List price, List> special, List needs, Map, Integer> map) { + //如果map包含当前待购清单,不再重复计算,直接返回结果 + if (map.containsKey(needs)) + return map.get(needs); + //定义一个内循环控制变量j,用于列表needs + //调用dot方法获取不使用大礼包时,购买清单的总价格res + int j = 0, res = dot(needs, price); + //遍历大礼包,获得各种购买组合 + for (List s : special) { + //克隆待购清单clone,可以直接对该数组操作 + ArrayList clone = new ArrayList<>(needs); + //遍历待购清单 + for (j = 0; j < needs.size(); j++) { + //clone.get(j)表示待购清单中第j个商品的数量 + //s.get(j)表示礼包中当前商品的数量 + //diff是二者的差 + int diff = clone.get(j) - s.get(j); + //如果diff<0表示礼包中的商品数量大于待购清单,不合题意,排除 + if (diff < 0) + //跳出本次循环,继续下一次循环 + break; + //在克隆待购清单中当前商品对应位置存储差值 + //存储的差值表示余下还有多少量可以购买,用于传入下方的递归函数做参数 + clone.set(j, diff); + } + //j == needs.size()表示j是整数列表的长度,即needs中最后一个元素的下标 + if (j == needs.size()) + //s.get(j) 获取大礼包整数列表s第j个下标的元素,即当前大礼包的价格 + //shopping(price, special, clone, map) 递归调用shopping函数 + //第三个参数clone,记录了每种商品余下可购买的数量 + //递归调用的shopping返回余下可购买数量所能获得的最优总价 + //所以s.get(j) + shopping(price, special, clone, map) + //就是包含当前礼包所能得到的最优价格 + //Math.min比较已有结果和包含当前礼包的最优价格,取其中较小值 + res = Math.min(res, s.get(j) + shopping(price, special, clone, map)); + } + //将待购清单对应的结果存入map + map.put(needs, res); + return res; + //上述方法是如何计算礼包组合之外,单独购买的那部分总价? + //关键点有2个: + // 1) clone: + // 经过购买组合之后,待购清单的克隆数组clone里的商品数量会减少, + // 当所有可能的大礼包组合都用尽之后, + // clone里剩余的待购数量就是只能单独购买的那部分商品 + // 2) dot方法: + // dot方法获得不使用大礼包时待购清单的总价, + // 大礼包组合用尽之后的clone待购清单, + // 经过dot方法就能得到单独购买的那部分商品的总价 + } + + /** + * 两个整数列表对应下标的数值相乘,并将结果累加 + * + * @param a + * @param b + * @return + */ + public int dot(List a, List b) { + int sum = 0; + //遍历整数列表a + for (int i = 0; i < a.size(); i++) { + //将整数列表a和整数列表b对应位置的数值相乘并累加 + sum += a.get(i) * b.get(i); + } + //返回最终结果 + return sum; + } + + +``` + +**复杂度分析** + +时间复杂度:O(n^2), +设数组special的长度为m, +数组needs的长度为k, +外循环遍历special数组时间复杂度为 m, +内循环遍历needs时间复杂度为 k, +两个循环嵌套时间复杂度为 m*k, +外循环中有递归函数, +每次调用的时间复杂度也是 m*k,共调用m次, +总的时间复杂度是 m*k + m*(m*k) = m*k + m^2, +舍去低阶项 m*k,得到时间复杂度m^2*k +根据题意,商品的种类比起礼包的数量相当于一个常数, +即k的值非常小,可以看做常数, +所以最终的时间复杂度大致为O(n^2) + +空间复杂度:O(n^2), +设数组special的长度为m, +数组needs的长度为k, +使用了map存储计算结果, +每存储一个键值对使用O(1)的空间复杂度 +最多有m次递归,每次递归可能会产生一个键值对, +所以map的空间复杂度为O(m); +另外在每次外循环都克隆了一个最大为needs长度k的数组, +外循环遍历special的循环次数是m, +每次都有递归函数再次使用了m次循环, +所以有m*m次克隆一个最大长度为k的数组, +空间复杂度为 m^2*k, +因为商品种类k的值相对较小,可以看做常数, +所以克隆数组占用的空间可以看做 m^2, +总的空间复杂度为map占用的O(m)+数组占用的O(m^2), +省去低阶项,最终的空间复杂度为O(n^2) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) diff --git a/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md b/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md new file mode 100644 index 0000000..eca592c --- /dev/null +++ b/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md @@ -0,0 +1,75 @@ +**646.最长数对链** +--- +https://leetcode.com/problems/maximum-length-of-pair-chain/ +如果你把一对数捏成一个数,这不就是最长上升子序列问题吗? +### 思路一 +动态规划问题,我们首先按照第1个数的大小排序所有的数对,然后有如下状态转移方程: +```math +dp[i] = max(dp[i], dp[j] + 1) (j \in [0, i)) +``` +dp[i]表示以第i个数对结尾的最大数对链长度,那么dp[i]的值为dp[i]自身(初始为1)与 从第j个数对连接到i数对的最大值,可以联想最长上升子序列问题哈。 +```java + /** + * 最长递增子序列问题的变形 + * + * @param pairs + * @return + */ + public int findLongestChain1(int[][] pairs) { + Arrays.sort(pairs, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0] - o2[0]; + } + }); + int[] dp = new int[pairs.length + 1]; + int max = 0; + for (int i = 0; i < pairs.length; i++) { + dp[i] = 1; + for (int j = 0; j < i; j++) { + if (pairs[j][1] < pairs[i][0]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + max = Math.max(max, dp[i]); + } + return max; + } +``` +#### 复杂度 +- 时间复杂度:O(n^2) +- 空间复杂度:O(n) + +### 思路二 +按第二个数排序,这样我们优先安排第二个数最小的,因为安排当前第二个数最小比安排当前不是第二个数最小要好。 +假设全局最优的链中第i个的第二个数不是当时安排的最小,那么必然这里可以替换成最小,最终只会导致这个全局长度不变或者增大,所以最好的选择就是每次都安排最小的。 +```java + /** + * 贪心 + * 以第二数排序 + * 优先添加末尾数小的,这样可以给后面的pair更大的选择 + * @param pairs + * @return + */ + public int findLongestChain2(int[][] pairs) { + Arrays.sort(pairs, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[1] - o2[1]; + } + }); + int curEnd = Integer.MIN_VALUE; + int max = 0; + for (int[] pair : pairs) { + if (curEnd < pair[0]) { + curEnd = pair[1]; + max++; + } + } + return max; + } +``` +#### 复杂度 +- 时间复杂度:O(nlogn) +- 空间复杂度:O(1) +以上两者都依赖你所选的排序算法。 \ No newline at end of file diff --git a/_site/leetcode/646-MaximumLengthOfPairChain/official.md b/_site/leetcode/646-MaximumLengthOfPairChain/official.md new file mode 100644 index 0000000..356c896 --- /dev/null +++ b/_site/leetcode/646-MaximumLengthOfPairChain/official.md @@ -0,0 +1,3 @@ +**646. 最长数对链** +--- +[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) diff --git a/_site/leetcode/647-PalindromicSubstrings/bigablecat.md b/_site/leetcode/647-PalindromicSubstrings/bigablecat.md new file mode 100644 index 0000000..9aab0a1 --- /dev/null +++ b/_site/leetcode/647-PalindromicSubstrings/bigablecat.md @@ -0,0 +1,198 @@ +**647. 回文子串** +--- +[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) + +* 英文官方题解1:Expand Around Center + +```java + /** + * https://leetcode.com/articles/palindromic-substrings/ + * 英文官方解法1:Expand Around Center + + * + * @param S + * @return + */ + public int countSubstrings(String S) { + //定义N为数组的长度,ans是回文子串的个数 + int N = S.length(), ans = 0; + // 回文子串是以某点为中心左右对称的 + // 比如aba的中心是字母b + // abba的中心在两个字母b的中间 + // 字符串的长度为N,最多有多少个这样的中心点? + // 如果以单个字符为中心, + // 即以S[i]为中心,0<=i= 0,因为left依次递减,所以left的下限是0 + //right < N,同理right依次递增,所以right的上限是数组S的长度N + //S.charAt(left) == S.charAt(right)中心点两边的字符相等 + //说明扩展到left和right当前所在位置时,符合回文的条件 + while (left >= 0 && right < N && S.charAt(left) == S.charAt(right)) { + //发现一个回文子串,ans递增1位 + ans++; + //从中心向外扩散 + //left递减,right递增 + left--; + right++; + } + } + //返回最终累加的回文子串数目 + return ans; + } + +``` + +**复杂度分析** + +时间复杂度:O(n^2), +外循环运行2*N-1次,时间复杂度为n, +每个内循环最多运行n次,时间复杂度为n, +嵌套循环的时间复杂度是O(n^2), + +空间复杂度:O(1), +没有使用额外的存储空间 + +--- + +* 英文官方题解2:Manacher + +```java + /** + * https://leetcode.com/articles/palindromic-substrings/ + * 英文官方解法2:Manacher + * + * @param S + * @return + */ + public int countSubstrings2(String S) { + //创建字符数组A,数组长度是S长度的2倍加3 + //为什么长度定义为2 * S.length() + 3会在下方代码中体现 + char[] A = new char[2 * S.length() + 3]; + //以'@'作为数组A的开头,防止越界 + A[0] = '@'; + //在字符之前加入'#' + A[1] = '#'; + //以'$'作为数组A的结尾,防止越界 + A[A.length - 1] = '$'; + //定义数组A的长度时+ 3,即加了上述3个字符 + //数组A的下标0和1都已定义,变量t从2开始记录下标 + int t = 2; + //S.toCharArray()将字符串S转为字符数组 + //遍历字符数组的每一个元素 + for (char c : S.toCharArray()) { + //将当前字符存入字符数组,同时下标t递增 + A[t++] = c; + //在每个字符后存入一个符号'#' + A[t++] = '#'; + //定义数组A的长度时,用2*S.length() + //因为每个字符后都有一个对应的'#',即S的长度扩充了2倍 + } + //经过上述处理后,字符串S中的每个字符,左右两侧都有'#' + //即'aba'变成了'#a#b#a#' + + //定义一个新数组Z,长度与数组A相等 + // Z中每个整数元素与A中的字符元素一一对应 + // 记录A在该位置上字符的回文半径 + int[] Z = new int[A.length]; + //定义整数变量center,记录字符串中最长回文子串的中心位置,初始值为0 + //定义整数变量right,记录最长回文子串的右侧边界,初始值为0 + int center = 0, right = 0; + //从下标1开始遍历数组Z,因为第一个字符'@'作为下界,不用考虑 + for (int i = 1; i < Z.length - 1; ++i) { + //当中心i小于最长回文子串的半径右边界right时 + //说明当前中心处于已经计算过的回文子串范围内 + //那么以i为中心的回文半径可以直接获取 + if (i < right) { + // 2 * center - i = center - ( i - center) + // 得到中心i相对于最长回文中心center,在数组Z上的对称位置 + // 即以i为中心,或者以 2 * center - i 为中心, + // 以 (right-i)为半径,两个对称中心点的回文子串数量是相同的 + // 而以i为中心,目前能获得的最长回文子串半径不能超出右边界right + // 所以需要从right - i和Z[2 * center - i]中取较小值 + Z[i] = Math.min(right - i, Z[2 * center - i]); + } + //A[i + Z[i] + 1] == A[i - Z[i] - 1] + //这行代码表示以i为中心,比较i两侧对称位置的字符是否相等 + //其中 i + Z[i] + 1 表示以i为中心,半径的右侧边界所在位置 + //因为Z[i]记录了i位置上已存在的回文半径,比如aba,其回文半径为1 + // i + 已有半径 + 1 表示在已知半径递增1位后,测试是否仍然是回文 + //同理 i - Z[i] - 1 表示以i为中心,半径的左边界所在位置 + while (A[i + Z[i] + 1] == A[i - Z[i] - 1]) { + //如果中心i向左右两侧各延伸1位后,所在位置字符仍然相等 + //则Z[i]++表示以i为中心的回文半径长度递增1位 + Z[i]++; + } + //经过上述处理,i + Z[i] 表示以i为中心,最新的半径右边界 + //如果更新后的半径右边界比已知的最长回文半径右边界right更大 + if (i + Z[i] > right) { + //更新最长回文子串中心center的值 + center = i; + //更新最长回文子串的右侧边界right的值 + right = i + Z[i]; + } + } + //定义整数变量ans记录最长回文的总数 + int ans = 0; + //遍历数组Z + for (int v : Z) { + //v记录了当前位置回文子串的半径 + //即当前位置回文子串的总数 + //因为原字符串被前后插入了'#' + //所以回文子串的半径长度是实际的2倍 + //所以需要 (v + 1) / 2 进行减半处理 + //ans需要累加所有中心点的回文子串数量 + ans += (v + 1) / 2; + } + //返回最终结果 + return ans; + } + + +``` + +**复杂度分析** + +时间复杂度:O(n), +代码中总共有2个独立的for循环, +和1个for循环嵌套while循环, +独立的for循环分别遍历了字符串S一次,数组Z一次, +两次遍历的时间复杂度都是2N, +嵌套循环中,外循环遍历数组Z, +而内循环while, +只有在中心两侧字符相等的情况下才会进入循环体, +即有多少个中心点,就有多少次进入循环体, +中心点的个数是2*N-1, +所以外循环结束时, +while循环的最坏时间复杂度是2*N-1, +外循环for的时间复杂度是2N, +再加上另外两个独立的for循环, +总的时间复杂度是6N-1, +约去常数系数6和常数项1, +最终时间复杂度是O(N) + +空间复杂度:O(n), +创建了数组A和数组Z, +A和Z的大小都是2n+3, +所以总的空间复杂度最终为4n+6, +去掉常数项6和n的常数项系数4, +最终的空间复杂度是O(n) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) diff --git a/_site/leetcode/647-PalindromicSubstrings/official.md b/_site/leetcode/647-PalindromicSubstrings/official.md new file mode 100644 index 0000000..0c0833a --- /dev/null +++ b/_site/leetcode/647-PalindromicSubstrings/official.md @@ -0,0 +1,3 @@ +**647. 回文子串** +--- +[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) diff --git a/_site/leetcode/650-2KeysKeyboard/mahone.md b/_site/leetcode/650-2KeysKeyboard/mahone.md new file mode 100644 index 0000000..0432822 --- /dev/null +++ b/_site/leetcode/650-2KeysKeyboard/mahone.md @@ -0,0 +1,34 @@ +**650. 只有两个键的键盘** +--- +[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) + + +解决方案 +**思路** +思路1: 将n分解为m个数字的乘积并且m个数字的和最小,即把一个数分解为n个质数的和 + +``` +public int minStep(int n){ + int result = 0; + int d = 2; + while (n >1){ + //继续将剩下的进行分解 + while (n % d == 0 ){ + //加上次数 + result += d; + //计算剩下的n + n =n / d; + } + d++; + } + return result; + } +``` + +**复杂度分析** +时间复杂度:O(√n),当n是素数平方时,我们的循环耗时O(√n) +空间复杂度:O(1),空间只使用了result和d + +**参考资料** +* 本题leetCode英文官方题解: +[https://leetcode.com/problems/2-keys-keyboard/solution/](https://leetcode.com/problems/2-keys-keyboard/solution/) \ No newline at end of file diff --git a/_site/leetcode/650-2KeysKeyboard/official.md b/_site/leetcode/650-2KeysKeyboard/official.md new file mode 100644 index 0000000..7b54765 --- /dev/null +++ b/_site/leetcode/650-2KeysKeyboard/official.md @@ -0,0 +1,3 @@ +**650. 只有两个键的键盘** +--- +[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) diff --git a/_site/leetcode/664-StrangePrinter/official.md b/_site/leetcode/664-StrangePrinter/official.md new file mode 100644 index 0000000..bb8c3dc --- /dev/null +++ b/_site/leetcode/664-StrangePrinter/official.md @@ -0,0 +1,3 @@ +**664. 奇怪的打印机** +--- +[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) diff --git a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md new file mode 100644 index 0000000..6cb4130 --- /dev/null +++ b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md @@ -0,0 +1,95 @@ +**673. 最长递增子序列的个数** +--- +[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) + +* 英文官方题解1:暴力法 + +```java + + /** + * https://leetcode.com/articles/number-of-longest-increasing-subsequence/ + * 英文官方题解1,暴力法 + * + * @param nums + * @return + */ + public int findNumberOfLIS(int[] nums) { + //获取nums的长度N + int N = nums.length; + //如果N不大于1,直接返回N + if (N <= 1) return N; + //lengths用于记录以数字nums[i]结尾的子序列长度 + int[] lengths = new int[N]; //lengths[i] = length of longest ending in nums[i] + //counts用于记录以数字nums[i]结尾的子序列总共有多少个 + int[] counts = new int[N]; //count[i] = number of longest ending in nums[i] + // 用数字1填充lengths和counts数组 + // 即默认情况下,数组nums中每个元素都可以组成一个子序列 + // 每个子序列只有一个元素,序列长度为1,序列的个数为1 + Arrays.fill(lengths, 1); + Arrays.fill(counts, 1); + + //外循环迭代次数是数组nums的长度N + for (int j = 0; j < N; ++j) { + //内循环迭代次数是外循环的控制变量j + for (int i = 0; i < j; ++i) { + //因为是递增子序列,只针对nums[i] < nums[j]的情况进行操作 + if (nums[i] < nums[j]) { + //lengths[i]和lengths[j]分别表示以nums[i]和nums[j]结尾的子序列的长度 + if (lengths[i] >= lengths[j]) { + //因为nums[i]比nums[j]小,所以lengths[i]应该小于lengths[j] + //lengths[i] >= lengths[j]需要对lengths[j]的值进行更新 + //以nums[j]结尾的递增子序列,包含了以nums[i]结尾的子序列的所有元素,并至少多出一个元素nums[j] + //所以lengths[i] + 1表示在nums[i]结尾的子序列后面添加一个元素nums[j] + lengths[j] = lengths[i] + 1; + //counts[i]和counts[j]分别代表以nums[i]和nums[j]结尾的子序列个数 + //在所有以nums[i]结尾的子序列后面都可以添加元素nums[j]组成新的递增子序列 + //将counts[i]赋值给counts[j],counts[j]表示在nums[i]基础上以nums[j]结尾的子序列的数目 + counts[j] = counts[i]; + } else if (lengths[i] + 1 == lengths[j]) { + //如果lengths[i] + 1 == lengths[j] + //则所有以nums[i]结尾的子序列再加上一个元素nums[j] + //可以组成一批新的子序列,这批子序列都以nums[j]结尾,个数为counts[i] + //当前以num[j]结尾,长度为lengths[j]的子序列的个数为counts[j] + //在counts[j]的基础上,加上counts[i] + //即counts[j] += counts[i]得到最新的以nums[j]结尾的子序列的个数 + counts[j] += counts[i]; + } + } + } + } + //定义一个整数longest用于存储最长子序列的个数 + //定义一个整数ans作为最终结果返回 + int longest = 0, ans = 0; + //遍历所有子序列长度值 + for (int length : lengths) { + //找出其中最大的子序列长度,赋值给longest + longest = Math.max(longest, length); + } + //迭代N次,N为数组nums长度 + for (int i = 0; i < N; ++i) { + //如果以nums[i]结尾的子序列长度与最长长度相等 + if (lengths[i] == longest) { + //将以nums[i]结尾的子序列的总数存入ans + ans += counts[i]; + } + } + //返回最终结果 + return ans; + } + +``` + +**复杂度分析** + +时间复杂度:O(N^2), +嵌套for循环,最差情况迭代 N^2次 + +空间复杂度:O(N), +新建数组lengths和counts,占用空间都是N + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md new file mode 100644 index 0000000..f4ecc23 --- /dev/null +++ b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md @@ -0,0 +1,3 @@ +**673. 最长递增子序列的个数** +--- +[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/688-KnightProbabilityInChessboard/passself.md b/_site/leetcode/688-KnightProbabilityInChessboard/passself.md new file mode 100644 index 0000000..4faba33 --- /dev/null +++ b/_site/leetcode/688-KnightProbabilityInChessboard/passself.md @@ -0,0 +1,70 @@ +#688. “马”在棋盘上的概率 + +Leetcode 地址 [https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) + +**思路:** + +1.国际象棋“马”的走法类似中国象棋的**马走日字**走法,也就是说可以走八个方向,即可推出已知8个方向走法常量{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1} + +2.从K位置向后递推还在棋盘上的概率,那么根据动态规划的思维反过来考虑的话就是在board上所有位置走完K步后能到初始位置(r,c)的数目和 + +3.把棋盘上所有位置上经过K步还留在棋盘上的走法总和都算出来,然后计算 + +**具体代码** + +``` +public static double knightProbability(int N, int K, int r, int c) { + int [][] moves = {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}}; + double [][] tempDp = new double[N][N]; + for(double [] row : tempDp){ + Arrays.fill(row, 1); + } + + for(int step = 0; step=0 && row=0 && col= N || c < 0 || c >= N) return 0.0; + if (k == 0) return 1.0; + if (dp[k][r][c] != 0.0) return dp[k][r][c]; + for (int i = 0; i < 8; i++) + dp[k][r][c] += helper(dp, N, k-1, r+moves[i][0], c+moves[i][1]); + return dp[k][r][c]; + } +``` +参考了leet上star比较认可的解法 [具体地址](https://leetcode.com/problems/knight-probability-in-chessboard/discuss/108187/cjava-dp-concise-solution) + + diff --git a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md new file mode 100644 index 0000000..f549bbe --- /dev/null +++ b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md @@ -0,0 +1,130 @@ +**689. 三个无重叠子数组的最大和** +--- +[https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) + +```java + + public int[] maxSumOfThreeSubarrays(int[] nums, int K) { + // W是由数组nums中每K个元素的和组成的整数数组 + // 把间隔K看成滑动窗口的长度 + // 窗口在nums数组上从第1个元素开始滑动 + // 窗口每滑动一次,就计算一次窗口内所有元素的和,放入数组W + // 滑动窗口到nums的第nums.length - K个元素时,共计算了nums.length - K次 + // 此时nums数组中还剩K个元素,可以计算最后一次 + // 所以W的长度是nums.length - K + 1 + int[] W = new int[nums.length - K + 1]; + //定义一个整数sum用于存储每K个元素的和 + int sum = 0; + //遍历数组nums并求得W数组的所有值 + for (int i = 0; i < nums.length; i++) { + //用+=对nums中连续的元素累加求和 + sum += nums[i]; + // 如果i>=K,说明前K个元素的值已经累加完毕,窗口开始向右滑动 + // 从K个元素之后,每次滑动1个元素 + // 需要从sum里减去上一次滑动窗口的首个元素nums[i - K] + // sum -= nums[i - K]得到从第[i-K+1]个元素起到第i个元素为止的K个元素之和 + if (i >= K) sum -= nums[i - K]; + // 第一组K个元素在nums中的下标从0到K-1 + // 所以W的第一个元素是 W[i-K+1] = W[(K-1)-K+1] = W[0] + if (i >= K - 1) W[i - K + 1] = sum; + } + + // 首先需要明白本解法中nums、W和left(或right)这三个数组索引的对应关系 + // + // 先看W[i]和nums[i]的关系: + // 在前一个给W赋值的for循环代码中可以看出,W[i]对应着nums中从nums[i]算起,到nums[i+K-1],共K个元素的和 + // 如题目示例,nums=[1,2,1,2,6,7,5,1],K=2,W=[3,3,3,8,13,12,6] + // W[0]=nums[0]+nums[1]=1+2=3,即W[0]等于nums[0]到nums[0+2-1]=nums[1],共2个元素的和 + // + // 再看left[i]和W[i]的关系: + // 给left[i](或right[i])赋值时,需要找到从W[0]到W[i]为止,元素值且索引最小那个元素 + // 然后将W中这个元素的索引赋给left[i] + // 即给left[0]赋值时,比较W[0]到W[0]共1个元素, + // 给left[1]赋值时,比较W[0]到W[1]共2个元素, + // 给left[2]赋值时,比较W[0]到W[2]共3个元素...以此类推 + // 因为W[0]=w[1]=W[2]=3,而W[0]、W[1]、W[2]三个元素中W[0]的索引最小 + // 所以left[0]=left[1]=left[2]=0,都取最小的那个索引0 + // + // 同时,由于到nums[nums.length - K + 1]为止,W和nums中的索引是一一对应的 + // 而left[i]记录的又是W中的索引,所以left[i]与nums中的元素索引一一对应 + // 索引的对应关系清楚了,下面关于left和right的代码就容易理解了 + + //题目要求返回nums中和最大的3个子序列的起始索引 + //我们将这3个子序列中的第1个子序列的可能索引都存入一个整数数组left + int[] left = new int[W.length]; + //定义一个整数best,记录每次迭代时,从数组W中获取到的相对最大值在W中的索引 + //best默认值为0 + int best = 0; + //按索引从小到大遍历数组W + for (int i = 0; i < W.length; i++) { + //W[i] > W[best]表示当前第i个元素W[i],大于W中已知的最大元素W[best] + //将索引i赋值给best + if (W[i] > W[best]) best = i; + //将当前为止W中最大值的索引best赋给left[i] + left[i] = best; + } + + //题目要求返回nums中和最大的3个子序列的起始索引 + //我们将这3个子序列中的第3个子序列的可能索引都存入一个整数数组right + int[] right = new int[W.length]; + //best默认值为W数组的末尾索引 + best = W.length - 1; + //按索引从大到小遍历数组W + for (int i = W.length - 1; i >= 0; i--) { + //W[i] > W[best]表示当前第i个元素W[i],大于等于W中已知的最大元素W[best] + //将索引i赋值给best + if (W[i] >= W[best]) best = i; + //将当前为止W中最大值的索引best赋给right[i] + right[i] = best; + } + + // 定义一个整数数组ans用于返回最终结果,即3个子序列的初始索引 + int[] ans = new int[]{-1, -1, -1}; + // for循环的控制变量j在循环体中要进行j-K和j + K的操作 + // j-K要大于等于0,j+K要小于W.length + // 所以j的初始值为K,j的上限值W.length - K + for (int j = K; j < W.length - K; j++) { + // 定义3个子序列的中间序列的索引为j + // 那么W[j]等于nums[j]到nums[j+K-1]共K个元素的和 + // 因为3个子序列不重叠,所以: + // 第1个序列的索引应该小于或等于j-K + // 第3个序列的索引应该大于或等于j+K + // left[j - K]记录了到从nums[0]到nums[j-K]为止,子序列和最大初始索引最小的那个索引 + // right[j - K]记录了到nums[nums.length]到nums[j+K]为止,子序列和最大初始索引最小的那个索引 + int i = left[j - K], k = right[j + K]; + //当ans[0] == -1时,ans还没有赋值 + //当W[i] + W[j] + W[k] > W[ans[0]] + W[ans[1]] + W[ans[2]]时 + //说明找到了更大的3个子序列之和 + //满足上述两个条件之一,即对ans[0]、ans[1]、ans[2]重新赋值 + if (ans[0] == -1 || W[i] + W[j] + W[k] > + W[ans[0]] + W[ans[1]] + W[ans[2]]) { + //分别将初始索引i、j、k赋值给ans[0]、ans[1]、ans[2] + ans[0] = i; + ans[1] = j; + ans[2] = k; + } + } + //返回最终结果 + return ans; + } + +``` + +**复杂度分析** + +时间复杂度:O(N), +方法中使用了4个for循环,迭代次数都在nums的长度范围内, +所以时间复杂度为4N,消去常数项,时间复杂度为O(N) + +空间复杂度:O(N), +定义了3个整数数组W、left、right, +占用空间都在nums数组的长度范围内, +还定义了一个数组ans,长度为常数3, +所以空间复杂度是3N+3,消去常数项最终空间复杂度为O(N) + +--- + +**参考资料** + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/maximum-sum-of-3-non-overlapping-intervals/](https://leetcode.com/articles/maximum-sum-of-3-non-overlapping-intervals/) diff --git a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md new file mode 100644 index 0000000..1c6cd74 --- /dev/null +++ b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md @@ -0,0 +1,3 @@ +**689. 三个无重叠子数组的最大和** +--- +[https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) diff --git a/_site/leetcode/691-StickersToSpellWord/official.md b/_site/leetcode/691-StickersToSpellWord/official.md new file mode 100644 index 0000000..fa024ea --- /dev/null +++ b/_site/leetcode/691-StickersToSpellWord/official.md @@ -0,0 +1,3 @@ +**691. 贴纸拼词** +--- +[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) diff --git a/_site/leetcode/692-TopKFrequentWords/bigablecat.md b/_site/leetcode/692-TopKFrequentWords/bigablecat.md new file mode 100644 index 0000000..2bf2ace --- /dev/null +++ b/_site/leetcode/692-TopKFrequentWords/bigablecat.md @@ -0,0 +1,66 @@ +**692. 前K个高频单词** +--- +[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) + + +```java + + public List topKFrequent(String[] words, int k) { + //定义一个HashSet用来存储出现过的单词和计数 + Map count = new HashMap(); + //遍历数组 + for (String word : words) { + //count.getOrDefault(word, 0)获取set中已经存在的key为word的值 + //如果存在获取其计数,如果不存在给出默认值0 + //count.getOrDefault(word, 0) + 1 当前单词每出现一次计数加1 + count.put(word, count.getOrDefault(word, 0) + 1); + } + //提取set的所有key值,即words数组的全部元素,传入新建的List + List candidates = new ArrayList(count.keySet()); + + //调用Collections自带的sort方法,该方法又调用List的sort方法,并最终使用了合并排序 + //第一个参数是实现了List接口的结合candidates + //第二个参数是一个Comparator对象,在调用sort方法的同时,使用自定义的排序规则 + //(w1, w2) -> 使用了lambda表达式的写法 + /** + Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1)); + 等价于 + Collections.sort(candidates, new Comparator() { + @Override + public int compare(String w1, String w2) { + int result = count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1); + return result; + } + }); + * + */ + // count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1); + // count.get(w1).equals(count.get(w2)) 首先比较两个单词的出现次数是否相等 + // w1.compareTo(w2) 如果w1和w2的计数相等,调用w1的compareTo方法,会给出两个单词的字母顺序比对结果 + // count.get(w2) - count.get(w1) 如果w1和w2的计数不相等,那么返回两个字符串出现次数的差值 + Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ? + w1.compareTo(w2) : count.get(w2) - count.get(w1)); + //candidates.subList(0, k)截取最终结果的前k个并返回 + return candidates.subList(0, k); + } + +``` + +**复杂度分析** + +时间复杂度: +O(NlogN),N是单词数组的长度,计算每个单词出现的频率耗费O(n)的时间复杂度,对单词排序耗费O(NlogN)的时间复杂度 + +空间复杂度: +O(N), 使用了List存储n个单词 + +--- + + +**参考资料** + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) + +* Collections.sort()的用法和要点: +[https://blog.csdn.net/wsll581/article/details/79953589](https://blog.csdn.net/wsll581/article/details/79953589) diff --git a/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md b/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md new file mode 100644 index 0000000..d9fcbf9 --- /dev/null +++ b/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md @@ -0,0 +1,54 @@ +**698. 划分为k个相等的子集** +--- +[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) + +解决方案 +**思路** +先求出平均数avg,假如平均数avg不为整数,也就是说数组的数字总和不能平均的分为k份,那么直接返回false。 +创建一个布尔数组flag,来记录nums数组中数字的状态(已用还是未用),temp初始为avg,temp的作用为记录当前子集的数字总和, +当temp=0的时候,也就是新一个子集求解完,那么继续求解下一个子集,k-1,temp重新置为avg;当temp!=0时,就是子集还未求解完, +那么继续求解子集,继续从数组中取数字,递归求解 +``` +class Solution { + public boolean canPartitionKSubsets(int[] nums, int k) { + //定义临时变量,求出当前数组的和 + int sum = 0; + //当前数组的长度 + int len = nums.length; + //对数组进行遍历,拿到当前的数组元素的和 + for (int i = 0; i < len; i++) + sum += nums[i]; + //如果数组的的综合不能均分则返回false + if(sum % k != 0 ) return false; + //初始化tmp为avg,用来记录当前子集的数字总和 + int avg = sum / k; + //可以均分的时候,定义布尔数组的flag,来记录nums数组中的状态 + boolean[] flag = new boolean[len]; + //index是为了在遍历数组的位置起始位置,放置前面的数字重新计算 + return help(nums,flag,avg,k,avg,0); + } + public static boolean help(int[] nums, boolean[] flag, int avg, int k, int temp, int index ){ + if (k == 0 ) return true; + //当前avg为0的时候,子集就已经确定了 + if (temp == 0) + return help(nums,flag,avg,k-1,avg,0); + for (int i = index; i < nums.length; i++) { + //如果数组状态为true的时候,继续 + if (flag[i] == true) continue; + flag[i] = true; + //对比子集的总和当前数组的元素的大小,从数组继续取数字,给index值加1,放置重新计算 + if(temp-nums[i] >= 0 && help(nums,flag,avg,k,temp-nums[i],index+1)){ + return true; + } + flag[i] = false; + } + return false; + } +} +``` +**复杂度分析** +平均时间复杂度:O(nlogn) +空间复杂度:O(n) + +**参考资料** + [https://blog.csdn.net/qq_38595487/article/details/81535891](https://blog.csdn.net/qq_38595487/article/details/81535891) \ No newline at end of file diff --git a/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md b/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md new file mode 100644 index 0000000..45d2743 --- /dev/null +++ b/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md @@ -0,0 +1,3 @@ +**698. 划分为k个相等的子集** +--- +[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) diff --git a/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md b/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md new file mode 100644 index 0000000..52d9ad1 --- /dev/null +++ b/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md @@ -0,0 +1,47 @@ +**703. 数据流中的第K大元素** +--- +[https://leetcode.com/problems/kth-largest-element-in-a-stream/](https://leetcode.com/problems/kth-largest-element-in-a-stream/) +**解决方案** +方法一:**堆** +**思路** +这个题跟其他两题有点类似,一个是找给定数组中的第K大元素,一个是找数据流的中位数。我们分别讨论一下: +数组中的第K大元素,这个我们一般用快排来找,因为首先数组元素的个数是固定的,而快排每趟都能确定一个数的最终位置,所以在给数组排序的过程中,就可以找到第K大的数。 +数据流中的第K大元素,因为是数据流,所以数据的个数是不固定的,这时候用快排就不合适了,因为最坏的情况下,第K大的元素一直在变,每次都需要重新排序。而且占用的空间也越来越大,这时候的空间复杂度和时间复杂度都是不能接受的。所以用最小堆是最合适的,我们只要保证最小堆的大小是K,那么堆顶的元素,肯定就是第K大的元素。同理可以用最大堆来找第K小元素 +数据流的中位数,这个题跟上一个还不一样,不但数据个数是不固定的,找的“第K大元素”也一直在变化。但因为每次找的都是中位数,所以我们可以用两个堆来实现,一个最大堆,一个最小堆。用两个堆来“平分”数据流 +**算法** +创建一个最小堆,在将数据加入堆的过程中,如果待加入元素大于堆顶元素,则弹出堆顶元素,将待加入元素放入堆中,保证堆的大小是K,这样堆顶的元素就是我们要找的第K大的元素 +``` + class KthLargest { + //优先队列是用堆实现的 + final PriorityQueue q; + final int k; + + public KthLargest(int k, int[] a) { + //初始化k和优先队列 + this.k = k; + q = new PriorityQueue<>(k); + for (int n : a) + add(n); + } + + public int add(int n) { + //如果当前堆的元素个数小于K,则直接放入 + if (q.size() < k) + q.offer(n); + //如果待加入元素n大于堆顶元素,则弹出堆顶元素,将n放入堆中 + else if (q.peek() < n) { + q.poll(); + q.offer(n); + } + //返回堆顶元素 + return q.peek(); + } + } +``` +**复杂度分析** +空间复杂度:O(K) +时间复杂度:O(n),n为数据流的长度 + +**参考资料** +leetCode Discuss + [https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) diff --git a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md new file mode 100644 index 0000000..8a77e9c --- /dev/null +++ b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md @@ -0,0 +1,43 @@ +**712 最小的删除和** +[https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) +方法一:**动态规划** +**思路** +首先,这个题最暴力的解法是将所有的情况都考虑一遍,然后选出最小值。但是这种做法的时间复杂度是不能接受的。我们可以仔细分析一下这个题。假设有字符串A和字符串B,在寻找的过程中,我们最多有三种情况 +- 当前字符a和字符b相等,这种情况,无需处理,接着遍历即可 +- 删除字符a,用字符a的下一个字符跟字符b比较 +- 删除字符b,用字符b的下一个字符跟字符a比较 + +根据上面分析的情况,我们可以用动态规划来处理。我们用dp[i][j]表示A[i:]和B[j:]的最小删除和,所以我们最后要求的值就是dp[0][0]. +**算法** +根据上面的分析,我们用公式来表示上述的三种情况,因为最终要求的是dp[0][0],所以我们应该从后向前遍历。假设我们要求dp[i][j],如果`s1[i] == s2[j]`,那么很明显不用删除,此时`dp[i][j] == dp[i+1][j+1]`.如果`s1[i] != s2[j]`,我们就要删除一个字符,要么删除s1[i],要么删除s2[j],此时该如何决定呢?根据题意,我们应该选择值小的那个,也就是`dp[i][j] = Math.min(s1[i]+dp[i+1][j],s2[j]+dp[i][j+1])`。 +**代码** +``` +class Solution { + public int minimumDeleteSum(String s1, String s2) { + //获取两个字符串的长度 + int m = s1.length(), n = s2.length(), MAX = Integer.MAX_VALUE; + //将字符串转换成字符数组,数组更好处理一些,直接用字符串进行处理,会更麻烦一些,但是也可以。 + char[] a = s1.toCharArray(), b = s2.toCharArray(); + //初始化辅助数组 + int[][] dp = new int[m + 1][n + 1]; + //从后向前遍历 + for (int i = m; i >= 0; i--) { + for (int j = n; j >= 0; j--) { + //当i==m或者j==n的时候,不用处理,因为s1[m]和s2[n]字符不存在。 + if (i < m || j < n) + //下面这个公式,就是算法部分说明的公式,只不过将他们写在一起,需要注意的是,要注意边界条件,因为上面if的条件是 ||,所以下面还要检测一下。 + dp[i][j] = i < m && j < n && a[i] == b[j] ? + dp[i + 1][j + 1] : Math.min((i < m ? a[i] + dp[i + 1][j] : MAX), (j < n ? b[j] + dp[i][j + 1] : MAX)); + } + } + return dp[0][0]; + } +} +``` +复杂度分析: +假设字符串的长度分别为M,N +空间复杂度:O(M*N),辅助数组 +时间复杂度:O(M*N),两重循环 + +参考资料: +[LeetCode Discuss](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/discuss/108814/JavaC%2B%2B-Clean-Code) \ No newline at end of file diff --git a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md new file mode 100644 index 0000000..50251d0 --- /dev/null +++ b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md @@ -0,0 +1,3 @@ +**712. 两个字符串的最小ASCII删除和** +--- +[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) diff --git a/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md b/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md new file mode 100644 index 0000000..014fd54 --- /dev/null +++ b/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md @@ -0,0 +1,57 @@ +**714. 买卖股票的最佳时机含手续费** +--- +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +* 选择的关键是找到一个最大后是不是能够卖掉stock,重新开始寻找买入机会。 +比如序列1 3 2 8,如果发现2小于3就完成交易买1卖3,此时由于fee=2,(3-1-fee)+(8-2-fee)<(8-1-fee), +所以说明卖早了,令max是当前最大price,当(max-price[i]>=fee)时可以在max处卖出,且不会存在卖早的情况, +再从i开始重新寻找买入机会 +贪心解法: +```java +public class Solution { + public static int maxProfit(int[] prices, int fee) { + int n = prices.length; + if (n <= 1) { + return 0; + } + int p = 0, curP = 0; + int minP = prices[0], maxP = prices[0]; + for (int i = 1; i < n; i++) { + minP = Math.min(minP, prices[i]); + maxP = Math.max(maxP, prices[i]); + curP = Math.max(curP, prices[i] - minP - fee); + if (maxP - prices[i] >= fee) { + p += curP; + curP = 0; + maxP = prices[i]; + minP = prices[i]; + } + } + return p + curP; + } +} +``` +* 动态转移点:手上有没有股票 进行DP。对于第i天的最大收益,应分成两种情况,一是该天结束后手里没有stock, +可能是保持前一天的状态也可能是今天卖出了,此时令收益为cash;二是该天结束后手中有一个stock, +可能是保持前一天的状态,也可能是今天买入了。由于第i天的情况只和i-1天有关,所以用两个变量cash和buy就可以, +不需要用数组 + +```java +class Solution { + public int maxProfit(int[] prices, int fee) { + int n=prices.length; + if(n<=1) + return 0; + int buy=-prices[0]; + int cash=0; + for(int i=1;i 0) { // 表示此处存在值序列 + if (i - 1 == maxValueIndex) { // 最优解所对应的最大Index与插入值序列的值num相邻 + // 先求出第二大的值与插入的值序列求和值 + int temp = secondMax + count[i] * i; + // 与之前的值序列集合最大值进行比较 + if (temp > firstMax) { + // 若新插入的值使得firstMax变化,则firstMax变为第二大值 + // 第一大值改变,索引也需要改变 + secondMax = firstMax; + firstMax = temp; + maxValueIndex = i; + } else { + // 若新插入的值使得firstMax没有变化,则仅仅修改第二大值 + secondMax = temp; + } + } else { + // 最优解所对应的最大Index与插入值序列的值num不相邻 + // 则直接拿来相加,并修改对应索引 + secondMax = firstMax; + firstMax = i * count[i] + firstMax; + maxValueIndex = i; + } + } + } + + // 返回最大值 + return firstMax; + } +} +``` + +--- + + +**参考资料** + +* 官方题解: +[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) diff --git a/_site/leetcode/740-DeleteAndEarn/official.md b/_site/leetcode/740-DeleteAndEarn/official.md new file mode 100644 index 0000000..4133181 --- /dev/null +++ b/_site/leetcode/740-DeleteAndEarn/official.md @@ -0,0 +1,3 @@ +**740. 删除与获得点数** +--- +[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) diff --git a/_site/leetcode/746-minCostClimbingStairs/bigablecat.md b/_site/leetcode/746-minCostClimbingStairs/bigablecat.md new file mode 100644 index 0000000..634690d --- /dev/null +++ b/_site/leetcode/746-minCostClimbingStairs/bigablecat.md @@ -0,0 +1,61 @@ +**746. 使用最小花费爬楼梯** +--- +[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) + +```java + + /** + * https://leetcode.com/articles/min-cost-climbing-stairs/ + *

+ * 英文官方题解 + * + * @param cost + * @return + */ + public static int minCostClimbingStairs(int[] cost) { + //根据题意,爬楼可以走一个台阶或者两个台阶 + //定义两个变量f1,f2分别记录走一个台阶和两个台阶的花费 + int f1 = 0, f2 = 0; + //从尾向头方向遍历数组元素 + for (int i = cost.length - 1; i >= 0; --i) { + //cost[i]获取在第i个阶梯时的花费 + //根据题意,有走一个台阶和两个台阶两种走法 + //f1表示走到第i+1个台阶的花费 + //f2表示走到第i+2个台阶的花费 + //Math.min(f1, f2);从两种走法中获取花费较小的一种 + //f0得到从第i个阶梯继续向上走到楼顶的所有花费 + //从最后一个台阶开始计算时 + //不存在第i+1和第i+2个台阶,f1和f2初始值为0,对结果没有影响 + int f0 = cost[i] + Math.min(f1, f2); + //下一轮将计算第i-1个台阶到楼顶的花费 + //在本轮中, + //f0、f1、f2分别代表第i个、第i+1个和第i+2个台阶到楼顶的费用 + //那么下一轮,计算第i-1个台阶到楼顶的费用时,需要知道第i个,第i+1个台阶的费用 + //为下一轮的备选答案赋值 + //f1为第i+1个台阶到楼顶的花费,赋值给f2,即为下一轮走2个台阶方案的花费 + f2 = f1; + //f0位第i个台阶到楼顶的花费,赋值给f1,即为下一轮走1个台阶方案的花费 + f1 = f0; + } + //遍历完数组时 + // f1为从cost[0]开始向上到楼顶的花费 + // f2为从cost[1]开始向上到楼顶的花费 + return Math.min(f1, f2); + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +遍历长度为n的数组一次 + +空间复杂度:O(1), +f1和f2使用了常数空间 + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) diff --git a/_site/leetcode/746-minCostClimbingStairs/official.md b/_site/leetcode/746-minCostClimbingStairs/official.md new file mode 100644 index 0000000..92d26ec --- /dev/null +++ b/_site/leetcode/746-minCostClimbingStairs/official.md @@ -0,0 +1,3 @@ +**746. 使用最小花费爬楼梯** +--- +[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) diff --git a/_site/leetcode/764-LargestPlusSign/SpecialYang.md b/_site/leetcode/764-LargestPlusSign/SpecialYang.md new file mode 100644 index 0000000..5b0de24 --- /dev/null +++ b/_site/leetcode/764-LargestPlusSign/SpecialYang.md @@ -0,0 +1,145 @@ +**764.最大加号标志** +--- +https://leetcode.com/problems/largest-plus-sign/ + +题目意思是给一个`$N \times N$`的矩阵,然后再告诉你其中某些单元格的值为0。让你求出值可以为1的单元格为中心,它的四臂上,下,左,右都要为1,组成加号标志,四个方向同时都要全部为1,这样的情况下,加号的长度最大为多少。显然加号的最大的长度取决于四个方向最短全为1。其实就是**木桶效应**了。 + + - 加号中心要为1 + - 加号的四臂都要为1,且长度要一致,显然由最短的决定整体的长度 + +### 思路一 +暴力法。遍历所有的单元格,以所有的可以为1的单元格为中心,一步一步同时向四周扩散,直到某个臂为0为止,继续对下一个可以为1的单元格作同样的处理,期间维护一个最大臂长即可。 + +```java + /** + * 暴力解法 + * @param N + * @param mines + * @return + */ + public int orderOfLargestPlusSign1(int N, int[][] mines) { + int[][] dp = new int[N][N]; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + dp[i][j] = N; + } + } + for (int[] mine : mines) { + dp[mine[0]][mine[1]] = 0; + } + int max = 0; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + int k = 0; + while (i - k >= 0 && i + k < N && j - k >= 0 && j + k < N + && dp[i - k][j] == 1 + && dp[i + k][j] == 1 + && dp[i][j - k] == 1 + && dp[i][j + k] == 1) { + k++; + } + max = Math.max(max, k); + } + } + return max; + } +``` +#### 复杂度 +- 时间复杂度:O(n^3) +- 空间复杂度:O(n^2) + +### 思路二动态规划 +我们发现第i个单元格的左臂长度其实不用在重头开始计算,利用第i-1个单元格的值就可以确定第i个单元格的左臂长度。 +```math +left[i] = Math.min(left[i], left[i] == 0 ? 0 : left[i - 1] + 1) +``` +如果是这样的思路岂不是再申请3个其他方向的数组,显然不太合理,好在我们只需对每个单元格求四个方向中最短的那一长度,这就可以重用了啊,我们先求左,然后统一求右,再上,下,每次都要求最小即可,最后必然是四个方向的重叠的最小结果。 + +那就有了下面的这个代码: +```java + //以行单位 + for (int i = 0; i < N; i++) { + //求该行中所有单元格的最大左臂长 + for (int j=0, l=0; j < N; j++) { + // j is a column index, iterate from left to right + // every time check how far left it can reach. + // if grid[i][j] is 0, l needs to start over from 0 again, otherwise increment + grid[i][j] = Math.min(grid[i][j], l = (grid[i][j] == 0 ? 0 : l + 1)); + } + //求该行中所有单元格的最大右臂长 + for (int k = N-1, r=0; k >= 0; k--) { + // k is a column index, iterate from right to left + // every time check how far right it can reach. + // if grid[i][k] is 0, r needs to start over from 0 again, otherwise increment + grid[i][k] = Math.min(grid[i][k], r = (grid[i][k] == 0 ? 0 : r + 1)); + } + //求该行中所有单元格的最大上臂长 + for (int j = 0, u=0; j < N; j++) { + // j is a row index, iterate from top to bottom + // every time check how far up it can reach. + // if grid[j][i] is 0, u needs to start over from 0 again, otherwise increment + grid[j][i] = Math.min(grid[j][i], u = (grid[j][i] == 0 ? 0 : u + 1)); + } + //求该行中所有单元格的最大下臂长 + for (int k = N-1, d=0; k >= 0; k--) { + // k is a row index, iterate from bottom to top + // every time check how far down it can reach. + // if grid[k][i] is 0, d needs to start over from 0 again, otherwise increment + grid[k][i] = Math.min(grid[k][i], d = (grid[k][i] == 0 ? 0 : d + 1)); + } + + // after four loops each time taking Math.min over the grid value itself + // all grid values will eventually take the min of the 4 direcitons. + } +``` + +很显然我们可以合并这个loop,那么就有了下面的代码: +```java + /** + * 动态规划 + * + * 对每个方向都取最小,那么最终以这个为中心的就是最小长度 + * @param N + * @param mines + * @return + */ + public int orderOfLargestPlusSign2(int N, int[][] mines) { + int[][] dp = new int[N][N]; + //初始化大于等于N就行,因为我们每次求的是4臂的最小值 + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + dp[i][j] = N; + } + } + for (int[] mine : mines) { + dp[mine[0]][mine[1]] = 0; + } + for (int i = 0; i < N; i++) { + //充分利用了j, k的值 + for (int j = 0, k = N - 1, l = 0, r = 0, u = 0, d = 0; j < N; j++, k--) { + //左 + dp[i][j] = Math.min(dp[i][j], l = (dp[i][j] == 0 ? 0 : l + 1)); + //右 + dp[i][k] = Math.min(dp[i][k], r = (dp[i][k] == 0 ? 0 : r + 1)); + //上 + dp[j][i] = Math.min(dp[j][i], u = (dp[j][i] == 0 ? 0 : u + 1)); + //下 + dp[k][i] = Math.min(dp[k][i], d = (dp[k][j] == 0 ? 0 : d + 1)); + } + } + int max = 0; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + max = Math.max(0, dp[i][j]); + } + } + return max; + } +``` +#### 复杂度 +- 时间复杂度:O(n^2) +- 空间复杂度:O(n^2) + +参考: +- https://leetcode.com/problems/largest-plus-sign/discuss/113314/JavaC%2B%2BPython-O(N2)-solution-using-only-one-grid-matrix +- https://leetcode.com/problems/largest-plus-sign/solution/ \ No newline at end of file diff --git a/_site/leetcode/764-LargestPlusSign/official.md b/_site/leetcode/764-LargestPlusSign/official.md new file mode 100644 index 0000000..5ddaa33 --- /dev/null +++ b/_site/leetcode/764-LargestPlusSign/official.md @@ -0,0 +1,3 @@ +**764. 最大加号标志** +--- +[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) diff --git a/_site/leetcode/787-CheapestFlightsWithinKStops/official.md b/_site/leetcode/787-CheapestFlightsWithinKStops/official.md new file mode 100644 index 0000000..f83e072 --- /dev/null +++ b/_site/leetcode/787-CheapestFlightsWithinKStops/official.md @@ -0,0 +1,3 @@ +**787. K 站中转内最便宜的航班** +--- +[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) diff --git a/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md b/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md new file mode 100644 index 0000000..f90a41c --- /dev/null +++ b/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md @@ -0,0 +1,84 @@ +https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/ + +787. K 站中转内最便宜的航班 + +思路: + +**动态规划思想** + +1.状态转移方程: + +ans = min(ans, costs[k] + prices[k][dst]) + +其中costs[k]表示到达位置k时的最小花费,prices[k][dst]表示从k到达dst的航班价格。 + +``` +class Solution: + def findCheapestPrice(self, n, flights, src, dst, K): + """ + :type n: int + :type flights: List[List[int]] + :type src: int + :type dst: int + :type K: int + :rtype: int + """ + INF = 0x7FFFFFFF + prices = collections.defaultdict(lambda: collections.defaultdict(int)) #内置collection得到数组 + for s, t, p in flights: + prices[s][t] = p + ans = prices[src][dst] or INF #从src到dst的prices + queue = [src] #src的队列列表 + costs = {src : 0} #费用的字典 key:src,value:数字 + for x in range(K + 1): + nset = set() #一个集合 + for loc in queue: #在当前的位置 + ans = min(ans, costs[loc] + (prices[loc][dst] or INF)) + for next in prices[loc]: #下一段转的航班需要花费的费用 + costs[next] = min(costs.get(next, INF), costs[loc] + (prices[loc][next] or INF)) + nset.add(next) #next为prices的一维数组,加入集合当中 + queue = list(nset) #最后我们可以得到一个队列,存着每一个出发点,也就是航班 + return ans if ans < INF else -1 + +``` +时间复杂度是O(K * s * n) + +2.另一种动态规划的思路 + +用一个二维的dp数组,dp[i][j]表示在不超过i次转机的情况下,从j到达dst的最少费用。dp[i][j]=min(dp[i−1][k]+Pk−>j,Pk−>j) + +(从自己到自己为0,Pk−>k=0,若是没有这个线路则Pk−>j=inf) + +``` +class Solution(object): + def findCheapestPrice(self, n, flights, src, dst, K): + """ + :type n: int + :type flights: List[List[int]] + :type src: int + :type dst: int + :type K: int + :rtype: int + 176ms dp + """ + import collections + # 记录同一个终点的不同起点和价格 + flights_dict_end = collections.defaultdict(list) + for flight in flights: + flights_dict_end[flight[1]].append([flight[0], flight[2]]) + # 用来记录各种情况,n个站点,还剩K次,到达目的地最少价格 + dp = [[float('inf') for i in range(n)] for i in range(K + 1)] + # 初始化能直达的 + for i in flights_dict_end[dst]: + dp[0][i[0]] = i[1] + # 反向推回去 + for k in range(1, K + 1): + for pos in range(n): + for before in flights_dict_end[pos]: #遍历整个线路 + dp[k][before[0]] = min(dp[k][before[0]], dp[k-1][pos] + before[1]) #把转航班的加上去 + dp[k][pos] = min(dp[k][pos], dp[k-1][pos]) #状态转移方程 + ans = dp[K][src] + return ans if ans != float('inf') else -1 + +``` +时间复杂度是O(n * K * d) diff --git a/_site/leetcode/790-DominoAndTrominoTiling/mahone.md b/_site/leetcode/790-DominoAndTrominoTiling/mahone.md new file mode 100644 index 0000000..e864018 --- /dev/null +++ b/_site/leetcode/790-DominoAndTrominoTiling/mahone.md @@ -0,0 +1,44 @@ +**790. 多米诺和托米诺平铺** +--- +[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) + +解决方案 +**思路** +思路1:此道题目根据相关数据来推到结论,得到计算每一个的公式,在根据公式来计算相应的结果。 +公式推到如下: +dp[n]=dp[n-1]+dp[n-2]+ 2*(dp[n-3]+...+d[0]) + =dp[n-1]+dp[n-2]+dp[n-3]+dp[n-3]+2*(dp[n-4]+...+d[0]) + =dp[n-1]+dp[n-3]+(dp[n-2]+dp[n-3]+2*(dp[n-4]+...+d[0])) + =dp[n-1]+dp[n-3]+dp[n-1] + =2*dp[n-1]+dp[n-3] + +``` + public int numTilings(int N){ + //result: dp[i] = 2*dp[i-1] + dp[i-3]; + int md = 1000000007; + //map to save value + Map valueMap = new HashMap<>(1001); + valueMap.put(1,1L); + valueMap.put(2,2L); + valueMap.put(3,5L); + if (N <=3){ + return valueMap.get(N).intValue(); + } + for (int i = 4; i <= N;++i) { + //根据来计算值 + Long tmp = 2 * valueMap.get(i - 1) + valueMap.get(i - 3); + //取余 + Long value = tmp % md; + valueMap.put(i,Long.valueOf(value)); + } + return valueMap.get(N).intValue(); + } +``` + +**复杂度分析** +时间复杂度:O(N) ,由于计算N的值需要得到之前的数据,因此循环计算,时间复杂度位o(N) +空间复杂度:O(M*N),空间使用dp + + +**参考资料** +[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) \ No newline at end of file diff --git a/_site/leetcode/790-DominoAndTrominoTiling/official.md b/_site/leetcode/790-DominoAndTrominoTiling/official.md new file mode 100644 index 0000000..5b01baa --- /dev/null +++ b/_site/leetcode/790-DominoAndTrominoTiling/official.md @@ -0,0 +1,3 @@ +**790. 多米诺和托米诺平铺** +--- +[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) diff --git a/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md b/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md new file mode 100644 index 0000000..0fa084f --- /dev/null +++ b/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md @@ -0,0 +1,3 @@ +**801. 使序列递增的最小交换次数** +--- +[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) diff --git a/_site/leetcode/808-SoupServings/official.md b/_site/leetcode/808-SoupServings/official.md new file mode 100644 index 0000000..44ac270 --- /dev/null +++ b/_site/leetcode/808-SoupServings/official.md @@ -0,0 +1,3 @@ +**808. 分汤** +--- +[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) diff --git a/_site/leetcode/813-LargestSumOfAverages/melody-l.md b/_site/leetcode/813-LargestSumOfAverages/melody-l.md new file mode 100644 index 0000000..a7dd15f --- /dev/null +++ b/_site/leetcode/813-LargestSumOfAverages/melody-l.md @@ -0,0 +1,59 @@ +**813.LargestSumOfAverage** +--- +[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) + +方法一:动态规划 +本题的dp思路是:设result[i][k]表示序列A[0]到A[i]分成k份的最优解。假设,现在需要划分最后一组,则设第k-1份的终点为j(即第k份是从A[j]到A[i])。此时`result[i][k]=result[j-1][k-1]+{sum(j...i)/(i-j+1)}`。 +因此,算法思路为:固定i,固定k,判断此时j最合适的位置。然后扩大i,判断不同的i的时候j最适合的位置。最后扩大k。这样递推式所需要的前项结果是能够提供的。 +下面代码优化的点为:提前前i项的和sum[i]求出,这样在计算从j到i的和的平均值为:`(sum[i]-sum[j])/(i-j+1)`。对于sum[i],i表示的是序列的长度,非索引。 + +```java +class Solution { + public double largestSumOfAverages(int[] A, int K) { + int N = A.length; + + // sum[i]表示前i项的和,i表示的是序列的长度,非索引 + // sum[0]没有使用,所以长度为N+1 + double[] sum = new double[N + 1]; + for (int i = 0; i < N; i++) { + sum[i + 1] = sum[i] + A[i]; + } + + // result[i][j]保存长度为i+1的序列,分割为j份的结果 + double[][] result = new double[A.length][K+1]; + for (int k = 1; k <= K; k++) {// 将序列分成k份,k取值为1到K + for (int i = 0; i < N; i++) { // 序列从i开始遍历 + if (k == 1) { + // 只分割为1份,因此直接求平均值 + result[i][k] = sum[i + 1] / (double) (i + 1); + } else if (k > i + 1) { + // 如果要分割的份数比此时的序列长度还大, + // 就不进行计算 + continue; + } else { + // 对于固定的i(此时序列长度为i+1), + // 如果要分割为固定的k份, + // 现在,需要知道第k-1份的终止点为哪里时,效果最好, + // 因此,遍历所有的j,最大值的点即是k-1份的终止点 + for (int j = k - 1; j <= i; j++) {// 从k-1开始遍历(前面至少要有k-1份能够被平分,不然没必要遍历),遍历到i为止(此时序列长度为i+1) + double temp = (sum[i+1] - sum[j]) / (i - j + 1) + result[j - 1][k - 1];// 若k-1份的终止点为j,则根据递推式求出当前值temp + result[i][k] = Math.max(result[i][k], temp);// 比较temp选最大 + } + } + } + } + + return result[N - 1][K]; //返回长度为N,分割为K份的值 + } +} +``` + +--- + + +**参考资料** + +* 官方题解: +[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) +* 网友题解: +[https://blog.csdn.net/magicbean2/article/details/79893634](https://blog.csdn.net/magicbean2/article/details/79893634) diff --git a/_site/leetcode/813-LargestSumOfAverages/official.md b/_site/leetcode/813-LargestSumOfAverages/official.md new file mode 100644 index 0000000..65ee94b --- /dev/null +++ b/_site/leetcode/813-LargestSumOfAverages/official.md @@ -0,0 +1,3 @@ +**813. 最大平均值和的分组** +--- +[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) diff --git a/_site/leetcode/837-New21Game/official.md b/_site/leetcode/837-New21Game/official.md new file mode 100644 index 0000000..5900ca8 --- /dev/null +++ b/_site/leetcode/837-New21Game/official.md @@ -0,0 +1,3 @@ +**837. 新21点** +--- +[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) diff --git a/_site/leetcode/838-PushDominoes/official.md b/_site/leetcode/838-PushDominoes/official.md new file mode 100644 index 0000000..9d82382 --- /dev/null +++ b/_site/leetcode/838-PushDominoes/official.md @@ -0,0 +1,3 @@ +**838. 推多米诺** +--- +[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) diff --git a/_site/leetcode/844-BackspaceStringCompare/BambooYH.md b/_site/leetcode/844-BackspaceStringCompare/BambooYH.md new file mode 100644 index 0000000..2edc5b8 --- /dev/null +++ b/_site/leetcode/844-BackspaceStringCompare/BambooYH.md @@ -0,0 +1,89 @@ +**844 比较含退格的字符串** +--- +[https://leetcode.com/problems/backspace-string-compare/](https://leetcode.com/problems/backspace-string-compare/) + +解决方案 +方法一:栈 +**思路** +根据题意的描述,我们很容易的会想到最简单直接的方法,就是模拟退格操作,然后得到处理后的字符串,最后比较两个字符串是否相等。用栈来模拟退格操作是合适的,当然也可以用StringBuilder等方法,只要能模拟这个操作就可以,这里我们选用栈来实现 +**算法** +从左到右遍历字符串,遇到字母,直接压入栈;如果遇到“#”,若当前栈非空,则弹出栈顶元素。 +**代码** +``` +class Solution { + public boolean backspaceCompare(String S, String T) { + Stack stack1 = new Stack(); + //比较两个字符串是否相等 + return help(S,stack1).equals(help(T,stack1)); + } + public static String help(String S,Stack stack) { + //清空一下栈,防止受到上一次运行结果的影响 + stack.clear(); + for(int i = 0; i < S.length(); i++) { + //如果遇到“#”,当前栈非空,则弹出栈顶元素,既模拟退格操作 + if(S.charAt(i) == '#') { + if(!stack.empty()) { + stack.pop(); + } + //如果遇到字母,则压栈 + }else { + stack.push(S.charAt(i)); + } + } + return String.valueOf(stack); + } +} +``` +**复杂度分析** +设M是字符串S的长度,N是字符串T的长度 +时间复杂度:O(M+N) 既O(Max(M,N)),需要将两个字符串都遍历一遍 +空间复杂度:O(M+N) 既O(Max(M,N)),最多可以添加Max(M,N)个元素到栈里 + +方法二:双指针 +**思路** +前一个方法是从左到右遍历,当我们遍历到一个字符的时候,我们并不能确定它最终是否存在,因为这取决于后面有多少个“#”。但是如果我们倒过来看,从右向左遍历,在遍历到某个字符的时候,我们就可以确定它最终是否存在。 +**算法** +从右向左,同时遍历两个字符串,当各自确定了一个字符一定会存在的时候,比较两个字符是否相同。如果都相同,则继续遍历,如果不同,则返回false。在处理的过程中,要注意边界条件。 +**代码** +``` +class Solution { + public boolean backspaceCompare(String S, String T) { + int i = S.length() - 1, j = T.length() - 1; + int skipS = 0, skipT = 0;//用来记录字符串S和T分别有多少个“#” + + while (i >= 0 || j >= 0) { + //找到S中下一个最终会存在的字符 + while (i >= 0) { + if (S.charAt(i) == '#') {skipS++; i--;} + //如果当前字符是字母,并且有剩余的“#”,则跳过当前字符 + else if (skipS > 0) {skipS--; i--;} + else break; + } + //找到T中下一个最终会存在的字符 + while (j >= 0) { + if (T.charAt(j) == '#') {skipT++; j--;} + else if (skipT > 0) {skipT--; j--;} + else break; + } + //如果两个字符不相同,则返回false + if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) + return false; + //如果一个字符串中找到了一个字符,但是另一个字符串已经遍历完了,则返回false + if ((i >= 0) != (j >= 0)) + return false; + i--; j--; + } + return true; + } +} +``` + +**复杂度分析**: +设M是字符串S的长度,N是字符串T的长度 +空间复杂度:O(1) +时间复杂度:O(M+N) +**注意:本题的解法都没考虑字符串为null的情况,因为题目限定了字符串长度大于等于1,如果没有限定条件,还要考虑字符串为null的情况** + +**参考资料** +- 本题leetCode官方题解 + [https://leetcode.com/problems/backspace-string-compare/solution/](https://leetcode.com/problems/backspace-string-compare/solution/) \ No newline at end of file diff --git a/_site/leetcode/844-BackspaceStringCompare/bigablecat.md b/_site/leetcode/844-BackspaceStringCompare/bigablecat.md new file mode 100644 index 0000000..174ed0d --- /dev/null +++ b/_site/leetcode/844-BackspaceStringCompare/bigablecat.md @@ -0,0 +1,64 @@ +**844. 比较含退格的字符串** +--- +[https://leetcode-cn.com/problems/backspace-string-compare/submissions/](https://leetcode-cn.com/problems/backspace-string-compare/submissions/) + +* 官方题解方法2 + +```java + /** + * 从后往前反向遍历字符串中的字符,跳过要删除的字符,比较最终结果会出现的有效字符 + * + * @param S + * @param T + * @return + */ + public boolean backspaceCompare(String S, String T) { + //i和j是循环次数上界 + int i = S.length() - 1, j = T.length() - 1; + //skipS和skipT是计数器,统计循环时跳过的字符个数 + int skipS = 0, skipT = 0; + //遍历两个字符串中的字符,依次对有效字符进行对比 + while (i >= 0 || j >= 0) { + //遍历字符串S中的字符 + while (i >= 0) { // Find position of next possible char in build(S) + //如果当前位置字符是'#'退格符号,计数器skipS递增1 + if (S.charAt(i) == '#') {skipS++; i--;} + //如果当前位置不是退格键且计数器值大于零,让计数器skipS递减1 + else if (skipS > 0) {skipS--; i--;} + else break; + } + //对字符串T做同样的操作 + while (j >= 0) { + if (T.charAt(j) == '#') {skipT++; j--;} + else if (skipT > 0) {skipT--; j--;} + else break; + } + // 讲过上述语句的跳过退格符号和被退格删除的字符 + // 分别取出S和T在最终结果对等位置将出现的字符 + // 如果两个字符不相等,说明两个字符串的最终有效结果不等 + if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) + return false; + // i >= 0和j >= 0分别判断两个字符串是否遍历结束 + // 如果一个遍历结束两一个没有结束,说明没有结束的字符串包含的有效字符比另一个多 + if ((i >= 0) != (j >= 0)) + return false; + i--; j--; + } + return true; + } + +``` + +**复杂度分析** + +时间复杂度: O(M + N),M和N分别是字符串S和T的长度,遍历两个字符串的所有字符需要M+N次迭代 + +空间复杂度: O(1),没有使用额外的辅助空间,空间复杂度为O(1) + +--- + + +**参考资料** + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) diff --git a/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md b/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md new file mode 100644 index 0000000..cbbad6b --- /dev/null +++ b/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md @@ -0,0 +1,88 @@ +**847. 访问所有节点的最短路径** +--- +[https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes/](https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes/) + + +```java + + public int shortestPathLength2(int[][] graph) { + //定义一个整数N,N是图graph节点的数目 + int N = graph.length; + // 1<= 1 && res[0] >= 1) { + res[1]--; + res[0]--; + }else if(res[1] == 0 && res[0]>= 3) { + res[0] -= 3; + }else { + return false; + } + } + } + return true; + } +} +``` +复杂度分析: +假设数组长度为n +时间复杂度:O(n) +空间复杂度:O(1) \ No newline at end of file diff --git a/_site/leetcode/860-lemonadeChange/SpecialYang.md b/_site/leetcode/860-lemonadeChange/SpecialYang.md new file mode 100644 index 0000000..18b25f3 --- /dev/null +++ b/_site/leetcode/860-lemonadeChange/SpecialYang.md @@ -0,0 +1,79 @@ +**柠檬水找零** +--- +https://leetcode.com/problems/lemonade-change/ +### 思路一 +这道题属于典型的贪心算法。贪心算法的思路就是优先给当前状态分配最优解。子问题最优,从而促进父问题也最优。 + +回归问题,有这么个几种情况: +1. 顾客有5元,那再好不过了 +2. 顾客有10元,那要看看你当前有没有5元,如果没有,gg了 +3. 顾客有20元,这时要优先给他10元。因为5元很宝贵啊,5元可以适用于10,20元的情况,而10元只能适用于20元情况。给顾客10元,从而节省更多的5元为后面10元的顾客找零,这就是贪心的体现,为当前分配最优解。 + +基于以上的讨论,我们只需两个计数器统计当前剩余的5元,10元即可。 +```java + /** + * 贪心做法 + * @param bills + * @return + */ + public boolean lemonadeChange1(int[] bills) { + int five = 0; + int ten = 0; + for (int i = 0; i < bills.length; i++) { + int value = bills[i]; + if (value == 5) { //5元,计数 + five++; + } else if (value == 10) { //10元,5减一,10加1 + if (five == 0) { + return false; + } + five--; + ten++; + } else if (value == 20) { + //有10元,先给10元 + if (ten != 0) { + ten--; + value = 10; + } + //尝试给5元 + while (value > 5 && five > 0) { + value -= 5; + five--; + } + //若最终无法减为5元,说明找不开,gg + if (value > 5) { + return false; + } + } + } + return true; + } +``` + +上面的代码太啰嗦了,简化以下,瞬间清爽。 +```java + public boolean lemonadeChange2(int[] bills) { + int five = 0; + int ten = 0; + for (int i = 0; i < bills.length; i++) { + int value = bills[i]; + if (value == 5) { + five++; + } else if (value == 10) { + five--; + ten++; + } else if (ten > 0) { + ten--; + five--; + } else { + five -= 3; + } + if (five < 0) { + return false; + } + } + return true; + } + +``` +参考:https://leetcode.com/problems/lemonade-change/discuss/143719/C%2B%2BJavaPython-Straight-Forward \ No newline at end of file diff --git a/_site/leetcode/860-lemonadeChange/official.md b/_site/leetcode/860-lemonadeChange/official.md new file mode 100644 index 0000000..7a100ec --- /dev/null +++ b/_site/leetcode/860-lemonadeChange/official.md @@ -0,0 +1,4 @@ +**860. 柠檬水找零** +--- +[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) + diff --git a/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md b/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md new file mode 100644 index 0000000..60bfb85 --- /dev/null +++ b/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md @@ -0,0 +1,3 @@ +**873. 最长的斐波那契子序列的长度** +--- +[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) diff --git a/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md b/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md new file mode 100644 index 0000000..e4d298b --- /dev/null +++ b/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md @@ -0,0 +1,111 @@ +**模拟机器人行走** +--- +https://leetcode.com/problems/walking-robot-simulation/ + +note: 这道题有个大坑:就是它要求机器人**最远走多远**,并不是你最终的位置。所以这道题才被标记为贪心,意思就是希望每走完一次,都要判以下最大值。一开始以为是我的程序的bug,废了我好长时间,真不值得。 + +### 思路一 +看题目标题,意思就是模拟机器人行走。 +要额外的处理就是方向问题,机器人最开始面向北方,不妨我们使用4个数来表示东南西北吧。 +- 0 : 北方,对应坐标轴,y++ +- 1 : 东方:对应坐标轴,x++ +- 2 : 南方:对应坐标轴,y-- +- 3 : 西方:对应坐标轴,x-- + +机器人收到指令,无非是转向和前进: +- 当收到小于0的指令,便是转向。我们可以对于当前方向值进行更改,若向左转,则方向值减1,若当前为0,则要更新为3。若向右转,则方向加1,若当前为3,则要更新为0。原因:方向是个circle。 +- 当收到大于0的指令,则是前进的指令。但是我们要一步一步走,因为中途可能碰到障碍。 + +另一个要解决的问题就是如何快速判断一个位置是否是障碍,O(1)的时间只能是**集合**了,又因为给定的是数组形式,所以我们自定义我们的hash函数为:`array[][0] + "-" + array[][1]`,如此便可以给每一个位置赋予唯一的key。 + +```java + /** + * 有点啰嗦的代码 + * @param commands + * @param obstacles + * @return + */ + public int robotSim1(int[] commands, int[][] obstacles) { + int x = 0, y = 0, direction = 0, maxDistance = 0; + Set obstaclesSet = new HashSet<>(); + for (int i = 0; i < obstacles.length; i++) { + String str = obstacles[i][0] + "-" + obstacles[i][1]; + obstaclesSet.add(str); + } + for (int i = 0; i < commands.length; i++) { + int value = commands[i]; + if (value > 0) { + while (value-- > 0) { + switch (direction) { + case 0: + y++;break; + case 1: + x++;break; + case 2: + y--;break; + case 3: + x--;break; + } + String pos = x + "-" + y; + //若是障碍,要恢复如初 + if (obstaclesSet.contains(pos)) { + switch (direction) { + case 0: + y--;break; + case 1: + x--;break; + case 2: + y++;break; + case 3: + x++;break; + } + //碰到障碍,即可立即结束此次指令 + break; + } + } + maxDistance = Math.max(maxDistance, (int) (Math.pow(x, 2) + Math.pow(y, 2))); + } else { + if (value == -2) { + direction = direction - 1 == -1 ? 3 : direction - 1; + } else { + direction = direction + 1 == 4 ? 0 : direction + 1; + } + } + } + return maxDistance; + } +``` +##### 简化 +以上是我第一次写的,可能有点啰嗦,所以主要对恢复现场那进行简化。我们用一个二维数组预设前进的步伐,这样就可以用通用的代码应付各种不同的情景。 +```java + /** + * 简洁的代码 + * @param commands + * @param obstacles + * @return + */ + public int robotSim2(int[] commands, int[][] obstacles) { + Set set = new HashSet<>(); + for (int[] obs : obstacles) { + set.add(obs[0] + "-" + obs[1]); + } + int[][] steps = new int[][]{{0,1}, {1, 0}, {0, -1}, {-1, 0}}; + int x = 0, y = 0, direction = 0, maxDistance = 0; + for (int cmd : commands) { + if (cmd == -2) { + direction = direction - 1 == -1 ? 3 : direction - 1; + } else if (cmd == -1) { + direction =direction + 1 == 4 ? 0 : direction + 1; + } else { + while (cmd-- > 0 && !set.contains((x + steps[direction][0]) + + "-" + (y + steps[direction][1]))) { + x += steps[direction][0]; + y += steps[direction][1]; + } + maxDistance = Math.max(maxDistance, (int) (Math.pow(x, 2) + Math.pow(y, 2))); + } + } + return maxDi +``` + +参考:https://leetcode.com/problems/walking-robot-simulation/discuss/152322/Maximum!-This-is-crazy! \ No newline at end of file diff --git a/_site/leetcode/874-walkingRobotSimulation/hatrick.md b/_site/leetcode/874-walkingRobotSimulation/hatrick.md new file mode 100644 index 0000000..4d2dddf --- /dev/null +++ b/_site/leetcode/874-walkingRobotSimulation/hatrick.md @@ -0,0 +1,57 @@ +**874.模拟机器人行走** +--- +[https://leetcode.com/problems/walking-robot-simulation/](https://leetcode.com/problems/walking-robot-simulation/) + +解决方案 +**思路** +机器人在(0,0)点开始行走,如果(0,0)点有障碍怎么办,这种情况是不管它,开始下一步行走,一旦机器人离开(0,0)点,这个点的障碍物才生效, +后面如果回到此点则不能跨过此障碍.也就是说我们需要先走一步,再去判断这一步是否有效,有效则更新坐标,否则原地不动,继续下一次动作. +至于右转和左转实际就是改变机器人的朝向,起初机器人向北,右转则朝向东,左转则朝向西.不同的朝向,意味着向前一步改变的坐标形式不一样, +如果朝北,则x不动,y递增;如果朝南,则x不动,y递减;如果朝西,则x递减,y不动;如果朝东,则x递增,y不动;也就是在每次实施除了左转右转的动作 +(调整朝向)之外的移动操作时,需要知道机器人的朝向.知道了朝向就往前走呗,遇到了前方障碍物则不要往前,结束此次动作,开始下一次动作. + +在方向的表示层面,用坐标来表示方向不仅可以很好的确定方向之间的关系,而且还能确定此方向上的增量.考虑[0,1],[1,0],[0,-1],[-1,0]分别代表北,东,南,西. +可以看到每个坐标的左边就是它的左转方向,右边的就是它的右边方向,也就是说,给一个方向i(方向向量的索引),则左转的方向是i-1,右转的方向是i+1.等等,那两头呢, +开始的位置不能减1,末端的位置不能加1.把首和尾连接器起来就好了,因此要进行取余操作,长度为4.当然了(0-1)%4没意义,因此改写成((0-1)+4)%4,即左转为(i+3)%4, +这样对中间位置和起始位置都适用.方向确定好了,那坐标增量呢,注意到某一方向上行进一步的增量恰好就是该方向的坐标.以北为例,y方向增量是1,x方向增量是0,也就是(0,1). + +``` +class Solution { + public int robotSim(int[] commands, int[][] obstacles) { + int max = 0; + int[][] dx = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + int k = 0; + Map map = new HashMap<>(); + for (int i = 0; i < obstacles.length; i++) { + map.put(obstacles[i][0] + "," + obstacles[i][1], true); + } + int p = 0, q = 0; + for (int command : commands) { + if (command == -1) { + k = (k + 1) % 4; + } else if (command == -2) { + k = (k + 4 - 1) % 4; + } else { + int cur[] = dx[k]; + for (int i = 0; i < command; i++) { + if (map.containsKey((p + cur[0]) + "," + (q + cur[1]))) { + break; + } + p += cur[0]; + q += cur[1]; + } + max = Math.max(max, p * p + q * q); + } + } + return max; + } +} + +``` +**复杂度分析** +时间复杂度:O(N+M) N和M分别是两个数组的长度 +空间复杂度:O(N) 使用map所占用的空间 + +**参考资料** + [https://blog.csdn.net/qq_37976559/article/details/82228460](https://blog.csdn.net/qq_37976559/article/details/82228460) + [https://blog.csdn.net/Jeff_Winger/article/details/81544085](https://blog.csdn.net/Jeff_Winger/article/details/81544085) \ No newline at end of file diff --git a/_site/leetcode/874-walkingRobotSimulation/official.md b/_site/leetcode/874-walkingRobotSimulation/official.md new file mode 100644 index 0000000..abb1575 --- /dev/null +++ b/_site/leetcode/874-walkingRobotSimulation/official.md @@ -0,0 +1,4 @@ +**874. 模拟行走机器人** +--- + +[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) diff --git a/_site/leetcode/875-KokoEatingBananas/sandao.md b/_site/leetcode/875-KokoEatingBananas/sandao.md new file mode 100644 index 0000000..b24609d --- /dev/null +++ b/_site/leetcode/875-KokoEatingBananas/sandao.md @@ -0,0 +1,45 @@ +## **875. Koko吃香蕉** + +https://leetcode.com/problems/koko-eating-bananas/ + +解决方案 +**思路** + +假设piles为[A,B,C,D....],最终求出来的值为K,我们可以得出下列公式: +$$ +Math.ceil({A \over K})+Math.ceil({B \over K})+Math.ceil({C \over K})+...<=H +$$ +可以简略为 +$$ +{A \over K}+{B \over K}+{C \over K}+...<=H +$$ +此时我们能大致得出K=(A+B+C+……)/H + +此时的出来的K应该是小于我们的最终值的,递增套入公式,求出消耗时间小于H的K的最大值 + +```java +public static int minEatingSpeed(int[] piles, int H) { + //step1:求出相近值 + double sum = 0; + for (int i: piles){ + sum += (double)i/H; + } + int k = (int)sum; + //step2:从相似值开始往上找,套入公式 + for (;;k++){ + int h = 0; + for (int i: piles){ + double s = Math.ceil((double)i/k); + h += s; + } + //求出了当前情况下需要消耗的时间h,这个时间必须小于规定的H + if (h <= H ){ + return k; + } + } + } +``` + +**参考资料** + +无 \ No newline at end of file diff --git a/_site/leetcode/877-stoneGame/melody-l.md b/_site/leetcode/877-stoneGame/melody-l.md new file mode 100644 index 0000000..c6865ac --- /dev/null +++ b/_site/leetcode/877-stoneGame/melody-l.md @@ -0,0 +1,72 @@ +**877. stoneGame** +--- +[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) + +方法一:数学知识 + +因为总堆数是偶数,所以对于先手,其总能保证自己的选择是最优的。所以亚历克斯总是能够赢得比赛。 + +```java +class Solution { + public boolean stoneGame(int[] piles) { + return true; + } +} +``` + +方法二:动态规划 + +从动态规划的角度看问题。 +设stone[i][j]表示从石子堆第i堆到石子堆第j堆,最终亚力克斯比李多出的石子数。由于只能取piles[i]或者piles[j],所以有如下两种情况: +1. 若此时轮到亚力克斯取石子,则此时stone[i][j] = Max{piles[i]+stone[i+1][j], piles[j]+stone[i][j-1]} +2. 若此时轮到李取石子,则此时stone[i][j] = Min{stone[i+1][j]-piles[i], stone[i][j-1]-piles[j]} + +即若(i, j)是亚力克斯,则采用方案1;若(i, j)是李,则采用方案2。 + +而亚力克斯和李是轮着来的,所以奇数轮是亚力克斯,偶数轮是李。根据题意分析可知,若总堆数为Num,则当前轮数为Num-(j-i+1)+1 = Num-j+i。我们可以根据Num-j+i来判断当前的轮数。 + +又,stone[i][j]的值是依赖与stone[i+1][j]或者stone[i][j-1]的,即大堆的计算是依赖于小堆的计算的。这里也可以理解为,初始状态堆的结果是依赖于最终状态堆的结果,所以需要倒着往前推理,先从最后取的那个堆开始计算。因此递推的算法思路是: +计算从size为1的堆数开始计算,按照以上递归式子计算小堆数的结果。然后不断的调高size值,直至size==num。 + +```java + +class Solution { + public boolean stoneGame(int[] piles) { + int num = piles.length; // 石子堆总数 + int[][] stone = new int[num][num]; // 存储从石子堆第i堆到石子堆第j堆,最终亚力克斯比李多出的石子数 + + // 从小堆开始计算,计算到最终大堆的size为止 + // 即计算最终堆数为1,然后到最终堆数为2,依次类推 + for (int size = 1; size <= num; size++) { + // 最终堆数一定的情况下, 从i=0开始,逐步计算所有的情况 + // 假设最终堆数为2,计算所有情况,即逐步计算(0,1),(1,2)... + for (int i = 0; i + size <= num; i++) { + int j = i + size - 1; // 根据当前的size求j所在位置 + if (size == 1) { // size为1特殊处理,条件也可以为i==j + // 特殊处理的原因是:size=1若采用递推式,则数组越界 + // 所以此处采用直接赋值 + // size为1,肯定是最后一轮,由李来取石子 + stone[i][j] = -piles[i]; + } else { + int parity = (num - j + i) % 2; // 求出当前的轮数 + if (parity == 1) {// 奇数轮,由亚力克斯取石子 + stone[i][j] = Math.max(piles[i] + stone[i + 1][j], piles[j] + stone[i][j - 1]); + } else {// 偶数轮,由李取石子 + stone[i][j] = Math.min(stone[i + 1][j] - piles[i], stone[i][j - 1] - piles[j]); + } + } + } + } + + // 判断第一堆到最后一堆,亚力克斯取出的石子数能否比李的多 + return stone[0][num - 1] > 0; + } +} + +``` + +--- + +**参考资料** +* 官方题解: +[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) diff --git a/_site/leetcode/877-stoneGame/official.md b/_site/leetcode/877-stoneGame/official.md new file mode 100644 index 0000000..7bf8fa0 --- /dev/null +++ b/_site/leetcode/877-stoneGame/official.md @@ -0,0 +1,3 @@ +**877. 石子游戏** +--- +[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) diff --git a/_site/leetcode/898-BitwiseORsOfSubarrays/official.md b/_site/leetcode/898-BitwiseORsOfSubarrays/official.md new file mode 100644 index 0000000..f3bf952 --- /dev/null +++ b/_site/leetcode/898-BitwiseORsOfSubarrays/official.md @@ -0,0 +1,3 @@ +**898. 子数组按位或操作** +--- +[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) diff --git a/_site/leetcode/903-ValidPermutationsForDISequence/official.md b/_site/leetcode/903-ValidPermutationsForDISequence/official.md new file mode 100644 index 0000000..03ba849 --- /dev/null +++ b/_site/leetcode/903-ValidPermutationsForDISequence/official.md @@ -0,0 +1,3 @@ +**903. DI 序列的有效排列** +--- +[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) diff --git a/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md b/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md new file mode 100644 index 0000000..d8eb007 --- /dev/null +++ b/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md @@ -0,0 +1,57 @@ +![903. DI 序列的有效排列](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) + +我们给出 S,一个源于 {'D', 'I'} 的长度为 n 的字符串 。(这些字母代表 “减少” 和 “增加”。) +有效排列 是对整数 {0, 1, ..., n} 的一个排列 P[0], P[1], ..., P[n],使得对所有的 i: + +如果 S[i] == 'D',那么 P[i] > P[i+1],以及; +如果 S[i] == 'I',那么 P[i] < P[i+1]。 +有多少个有效排列?因为答案可能很大,所以请返回你的答案模 10^9 + 7. + + + +示例: + +输入:"DID" +输出:5 +解释: +(0, 1, 2, 3) 的五个有效排列是: +(1, 0, 3, 2) +(2, 0, 3, 1) +(2, 1, 3, 0) +(3, 0, 2, 1) +(3, 1, 2, 0) + +思路: + +为了能进行状态转移,定义dp[i][j]表示:使用1-i这些数字的情况下,以j结尾的合理数组个数,计算dp[i][j]的过程如下: + +1. 如果s[i-2]=='D',说明第i-1位的数要比j大,第i-1位的数据范围是[j+1,i],j在第i位上,所以就把大于等于j的数都往左shift一位(这样2者是等价的,满足A一 +定满足B,满足B一定满足A),这样前i-1位就又是连续的[1,i-1],就可以继续用DP数组的含义。具体到代码就是,k的范围是range(j,i),而不是range(j+1,i) + +2. 如果s[i-2]=='I',数字i不在前i-1位,不用shift + +```py +class Solution: + def numPermsDISequence(self, S): + mod = 10**9 + 7 + n = len(S)+1 #n设置为字符数列长度加1 + dp = [[0 for _ in range(n+1)] for _ in range(n+1)] #设置状态定义 + dp[1][1]=1 + for i in range(2,n+1): + for j in range(1,i+1): + if S[i-2] == 'D': #对于D来说 + for k in range(j,i): #列出状态转移方程 + dp[i][j]+=dp[i-1][k] + dp[i][j]%=mod #得到最后结果 + else: #对于I来说 + for k in range(1,j): + dp[i][j]+=dp[i-1][k] #同样的操作 + dp[i][j]%=mod + return sum(dp[n])%mod +``` +时间复杂度:显然是O(N^3) + +空间复杂度:O(n) + + +![参考](https://blog.csdn.net/zjucor/article/details/82557070) diff --git a/_site/leetcode/920-NumberOfMusicPlaylists/passself.md b/_site/leetcode/920-NumberOfMusicPlaylists/passself.md new file mode 100644 index 0000000..d016bdc --- /dev/null +++ b/_site/leetcode/920-NumberOfMusicPlaylists/passself.md @@ -0,0 +1,48 @@ +#920. 播放列表的数量 + +Leetcode 地址 [https://leetcode-cn.com/problems/number-of-music-playlists/](https://leetcode-cn.com/problems/number-of-music-playlists/) + +**题目分析** + +你的音乐播放器里有 N 首不同的歌,在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复)。请你为她按如下规则创建一个播放列表,dp的方式[参考](https://blog.csdn.net/qq_17550379/article/details/82992083)。 + +**思路:** + +可以暴力枚举所有集合,然后对这些集合中相同元素的位置比较,如果 K){ + dp[i][j] = (dp[i][j] + (dp[i-1][j] * (j-K))%mod)%mod; + } + } + } + return (int)dp[L][N]; + } +} +``` +**时间复杂度** O(L*N) + +**空间复杂度** O(L*N) + + diff --git a/_site/leetcode/931-MinimumFallingPathSum/hatrick.md b/_site/leetcode/931-MinimumFallingPathSum/hatrick.md new file mode 100644 index 0000000..418ab8e --- /dev/null +++ b/_site/leetcode/931-MinimumFallingPathSum/hatrick.md @@ -0,0 +1,53 @@ +**931. 下降路径最小和** +--- +[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) + +解决方案 +**思路** +开二维数组,存第一行的所有数,从第二行开始,找每个位置能从上一行哪些位置下降过来,将其中的最小值赋值就可以了。其实就是上面的图,将指向反过来看就可以了: +那么除了两端的特殊情况,其他都是能从3个位置下降过来,有状态转移方程: +dp[i][j] = A[i][j] + Min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]) +注意判定最左边和最右边两种情况就行了。另外,竟然破天荒给了数据范围,当n = 1的时候只有一个下降数组就是本身,这个判定一下就行。 +最终答案要for循环遍历一下最下面一层,看最小值是多少。最小值就是答案。 + +``` +class Solution { + public static int[][] dp; + + public static int Min(int a,int b){ + return a < b ? a : b; + } + + public int minFallingPathSum(int[][] A) { + int len = A[0].length; + if(len == 1) return A[0][0]; + dp = new int[len][len]; + for(int i = 0;i < len;i++){ + dp[0][i] = A[0][i]; + } + for(int i = 1;i < len;i++){ + for(int j = 0;j < len;j++){ + if(j == 0){ + dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j+1]); + }else{ + if(j == len-1){ + dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j-1]); + }else{ + dp[i][j] = A[i][j] + Min(Min(dp[i-1][j],dp[i-1][j+1]),dp[i-1][j-1]); + } + } + } + } + int ans = 20000; + for(int i = 0;i < len;i++){ + ans = Min(ans,dp[len-1][i]); + } + return ans; + } +} + +``` + + +**参考资料** +[https://www.itbox.info/p/139142/leetcode-minimum-falling-path-sum](https://www.itbox.info/p/139142/leetcode-minimum-falling-path-sum) \ No newline at end of file diff --git a/_site/leetcode/931-MinimumFallingPathSum/official.md b/_site/leetcode/931-MinimumFallingPathSum/official.md new file mode 100644 index 0000000..5dad821 --- /dev/null +++ b/_site/leetcode/931-MinimumFallingPathSum/official.md @@ -0,0 +1,3 @@ +**931. 下降路径最小和** +--- +[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) diff --git a/_site/leetcode/935-KnightDialer/official.md b/_site/leetcode/935-KnightDialer/official.md new file mode 100644 index 0000000..564178f --- /dev/null +++ b/_site/leetcode/935-KnightDialer/official.md @@ -0,0 +1,3 @@ +**935. 骑士拨号器** +--- +[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) diff --git a/_site/leetcode/940-DistinctSubsequencesII/official.md b/_site/leetcode/940-DistinctSubsequencesII/official.md new file mode 100644 index 0000000..4516f1c --- /dev/null +++ b/_site/leetcode/940-DistinctSubsequencesII/official.md @@ -0,0 +1,4 @@ +**940. 不同的子序列 II** +--- + +[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) diff --git a/_site/leetcode/943-FindTheShortestSuperstring/official.md b/_site/leetcode/943-FindTheShortestSuperstring/official.md new file mode 100644 index 0000000..e5de8c9 --- /dev/null +++ b/_site/leetcode/943-FindTheShortestSuperstring/official.md @@ -0,0 +1,3 @@ +**943. 最短超级串** +--- +[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) diff --git a/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md b/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md new file mode 100644 index 0000000..eeff370 --- /dev/null +++ b/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md @@ -0,0 +1,258 @@ +**954. 二倍数对数组** +--- + +[https://leetcode-cn.com/problems/array-of-doubled-pairs/](https://leetcode-cn.com/problems/array-of-doubled-pairs/) + +* 方法1:官方题解(英文) +>排序 + HashMap + +```java + public static boolean canReorderDoubled(int[] A) { + //定义一个HashMap对象count,用于统计每个元素在数组中出现的次数 + Map count = new HashMap(); + //遍历数组A + for (int x : A) + //count.getOrDefault(x, 0) 在count中查找key为x的value + //如果不存在x,说明在count中只出现过一次,value用默认值0 + //取出的value就是元素x的数值在数组A中出现的次数 + //+1计数每次递增 + count.put(x, count.getOrDefault(x, 0) + 1); + + // B = A as Integer[], sorted by absolute value + //定义一个与数组A等长的数组B + Integer[] B = new Integer[A.length]; + //遍历数组A + for (int i = 0; i < A.length; ++i) + //将数组A中的元素依次赋予数组B + B[i] = A[i]; + //完成for循环后,B是数组A的一份拷贝 + //Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进,时间复杂度稳定为O(nlogn) + //第二个参数Comparator.comparingInt(Math::abs)是一个实现了Comparator接口的对象 + //Math::abs是lambda表达式的写法,不使用lambda的等价写法如下 + /** + * Comparator.comparingInt(new ToIntFunction() { + * @Override + * public int applyAsInt(Integer value) { + * return Math.abs(value); + * } + * }); + */ + //在ToIntFunction接口的applyAsInt方法中调用了Math.abs对数组B中的每一个元素取绝对值 + //将数组B的元素根据绝对值大小排序 + Arrays.sort(B, Comparator.comparingInt(Math::abs)); + + //遍历数组B中的元素 + for (int x : B) { + //count.get(x) == 0 乍看令人困惑,实际上需要结合后续代码来理解 + //count.get(x)获取了元素x在count中的计数 + //后续代码对符合题设条件的x进行了计数递减的操作后放回了count + //所以如果出现count.get(x)==0的情况,说明符合条件的x计数已经归零 + //continue继续循环 + if (count.get(x) == 0) continue; + //count.getOrDefault(2 * x, 0)查找2*x的计数 + //如果2*x的计数<= 0,说明数组B中不存在2*x + //数组中没有x的二倍数,不符合题设,返回false + if (count.getOrDefault(2 * x, 0) <= 0) return false; + + //运行到此处,说明数组中存在x的二倍数2*x + //分别将x和2*x在count中的计数递减一次 + count.put(x, count.get(x) - 1); + count.put(2 * x, count.get(2 * x) - 1); + } + // 所有元素的计数都消除为0 + // 说明数组正好可以按照题设将元素两两结合分配为二倍数对 + return true; + } + +``` + +**复杂度分析** + +时间复杂度:O(nlogn), +方法中对数组进行了三次遍历,时间复杂度为3n, +同时使用了一次Arrays.sort为数组排序, +Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进, +时间复杂度稳定为O(nlogn), +总的时间复杂度为nlogn+3n,消去低阶项,最终时间复杂度为O(nlogn) + +空间复杂度:O(n), +Arrays.sort排序方法的空间复杂度是O(n), +使用了HashMap存储数组中所有对象,空间复杂度是O(n), +最终的空间复杂度是O(n) + +--- + +* 方法2:递归 +>递归+HashMap + +```java + + public boolean canReorderDoubled(int[] A) { + //定义一个HashMap对象count,用于统计每个元素在数组中出现的次数 + Map count = new HashMap(); + //遍历数组A + for (int x : A) + //count.getOrDefault(x, 0) 在count中查找key为x的value + //如果不存在x,说明在count中只出现过一次,value用默认值0 + //取出的value就是元素x的数值在数组A中出现的次数 + //+1计数每次递增 + count.put(x, count.getOrDefault(x, 0) + 1); + + //首先对数组中的0进行处理 + //如果数组中0出现的次数不是偶数,说明0无法两两配成对 + //0不能与其他元素结合成符合题设的数对,所以返回false + if (count.getOrDefault(0, 0) % 2 != 0) { + return false; + } else { + //如果0出现偶数次,所有0可以成功配对,直接将0的计数消去 + count.put(0, 0); + } + + //遍历数组A + for (int x : A) { + //如果当前元素计数已经消去,继续循环 + if (count.get(x) == 0) continue; + //将当前元素和存放计数的HashMap对象count传入递归函数findHalfNum + //findHalfNum的作用是向下溯源,为所有小于等于当前元素值的数字配对 + findHalfNum(x, count); + } + + //再次遍历数组 + for (int x : A) { + //如果数组A符合题设,所有元素完成配对,所有计数都应消去为0 + //如果存在计数大于0的元素,说明有不符合题设的元素存在,返回false + if (count.get(x) > 0) { + return false; + } + } + //满足所有条件,返回true + return true; + } + + /** + * 递归函数,找到小于等于参数x的所有二倍数进行配对 + * 对完成配对的元素,消去相应的计数 + * + * @param x + * @param count + * @return + */ + public int findHalfNum(int x, Map count) { + //x % 2 == 0 如果x不能被2整除,说明x不是其他数字的二倍数,直接返回 + //count.getOrDefault(x / 2, 0) > 0 说明存在一个元素,x是这个元素的二倍数 + if (x % 2 == 0 && count.getOrDefault(x / 2, 0) > 0) { + //递归调用当前方法,找到能够与x/2配对的更小元素 + if (findHalfNum(x / 2, count) > 0) { + //count.get(x) - count.get(x / 2)用于判断x和x/2哪个出现的次数更少 + //pairsNum得到的是x和x/2中较少的计数,也就是x和x/2最多能配成几对二倍数 + int pairsNum = (count.get(x) - count.get(x / 2)) < 0 ? (count.get(x)) : count.get(x / 2); + //分别将x和x/2配对,消去公共计数,比如pairsNum是2,说明x和x/2可以配成2对 + count.put(x, count.get(x) - pairsNum); + count.put(x / 2, count.get(x / 2) - pairsNum); + } + } + //最后返回x剩余的计数到调用递归的上一级 + //如果x的计数仍有结余,x可以和x*2继续配对 + return count.get(x); + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +方法中对数组进行了三次遍历,时间复杂度为3n, +方法中使用的递归方法取决于数组的长度,时间复杂度为n, +总的时间复杂度为4n, +最终时间复杂度为O(n) + +空间复杂度:O(n) +本方法中递归的深度取决于数组的长度n, +所以空间复杂度是O(n) + +--- + +* 方法3:网友高效数组方法 +>整数数组 + +```java + + public static boolean canReorderDoubled(int[] A) { + //根据题意,-100000 <= A[i] <= 100000 + //分别创建两个整数数组pos和neg + //pos和neg的长度100001是数组A中可能出现的最大绝对值 + //pos和neg用于计数 + int[] pos = new int[100001]; + int[] neg = new int[100001]; + //遍历数组 + for (int i : A) { + //如果数组i中的元素大于0,对pos进行操作 + //pos[i]找到pos中第i个元素的值,对其做++递增操作 + //因为数组pos中所有元素的初始值都为0 + //所以pos[i]++实际上是对i进行了计数 + if (i > 0) pos[i]++; + //同理,当i<0时,取其正值-i,对neg数组进行操作 + else neg[-i]++; + } + //上述遍历结束后,pos保存了A中所有正值元素的计数,neg保存了A中所有负值元素的计数 + //分别检查pos和neg中的元素是否符合题意 + if (!checkDoublePair(pos)) return false; + if (!checkDoublePair(neg)) return false; + //原数组A中的元素都符合题意,返回true + return true; + } + + public static boolean checkDoublePair(int[] arr) { + //从大到小遍历用于计数的数组 + //在这个数组中,数组下标i对应数组A中的一个元素绝对值 + //arr[i]是i这个值在数组A中出现的次数 + for (int i = arr.length - 1; i >= 0; i--) { + //如果arr[i]>0说明i对应的计数还没有消除为0 + while (arr[i] > 0) { + //i % 2 == 1说明i是奇数,在之前的操作中没有被消除 + //因为数组是从大到小遍历的,i是奇数,只能跟更大的数值配对 + //i是数组A中不符合题意的元素,返回false + if (i % 2 == 1) return false; + //如果i是偶数,该偶数可以与i/2配对 + //arr[i]--将i对应的计数减1 + arr[i]--; + //查看与i配对的i/2的计数 + //arr[i / 2] == 0表示没有i/2与i组成数对 + //所以i不符合题意,返回false + if (arr[i / 2] == 0) return false; + //i/2可以和i配对,将其计数减1 + arr[i / 2]--; + } + } + //数组所有元素遍历完成,都符合题意,返回true + return true; + } + +``` + +**复杂度分析** + +时间复杂度:O(n), +忽略数组A的元素取值范围和数组长度限制, +对数组A一次遍历时间复杂度为n, +用于统计数组A中正数和负数的两个数组pos和neg, +两个数组的长度之和约等于数组A的长度n, +遍历pos和neg的方法虽然用了嵌套循环, +但是遍历过的元素不会重复操作, +所以对数组pos和neg遍历的时间复杂度仍然是O(n), +综上所述,总的时间复杂度是O(n) + +空间复杂度:O(n), +创建了两个数组,虽然根据题意有固定长度, +实际上可以假设这两个数组随着数组A的长度变化, +所以空间复杂度为O(n) + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/problems/array-of-doubled-pairs/solution/](https://leetcode.com/problems/array-of-doubled-pairs/solution/) + +* 网友高效数组方法: +[https://leetcode-cn.com/submissions/api/detail/991/java/27](https://leetcode-cn.com/submissions/api/detail/991/java/27) diff --git a/_site/leetcode/956-TallestBillboard/official.md b/_site/leetcode/956-TallestBillboard/official.md new file mode 100644 index 0000000..d012226 --- /dev/null +++ b/_site/leetcode/956-TallestBillboard/official.md @@ -0,0 +1,3 @@ +**956. 最高的广告牌** +--- +[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) diff --git a/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md b/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md new file mode 100644 index 0000000..11a9258 --- /dev/null +++ b/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md @@ -0,0 +1,3 @@ +**964. 表示数字的最少运算符** +--- +[https://leetcode-cn.com/problems/least-operators-to-express-number/](https://leetcode-cn.com/problems/least-operators-to-express-number/) diff --git a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md new file mode 100644 index 0000000..1240017 --- /dev/null +++ b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md @@ -0,0 +1,89 @@ +**967. 连续差相同的数字** +--- +[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) + +* 官方DP题解 + +```java + + /** + * https://leetcode-cn.com/articles/numbers-with-same-consecutive-differences/ + * 官方题解 + * + * @param N + * @param K + * @return + */ + public static int[] numsSameConsecDiff(int N, int K) { + //新建一个HashSet对象cur,用于存储数字1到9 + Set cur = new HashSet(); + //根据题意1 <= N <= 9 + //将数字1到9存入HashSet对象cur中 + for (int i = 1; i <= 9; ++i) + cur.add(i); + + //对1到N-1的每一个数字进行相同的操作 + for (int steps = 1; steps <= N - 1; ++steps) { + //另新建一个HashSet对象cur2,用于存储最新结果并排重 + Set cur2 = new HashSet(); + //遍历cur中的元素 + for (int x : cur) { + // x % 10 得到 x的个位数字d + int d = x % 10; + + //根据题意,d与下一位数字的差的绝对值为K + //那么有两种情况: + // 如果d比下一位数字大,有d - K >= 0 + // 如果d比下一位数字小,有d + K <= 9 + + //d - K >= 0表示d比下一位数字大的情况 + if (d - K >= 0) { + // (d - K)得到下一位数字 + // 10 * x 将x扩大一个10进制,(d - K)作为10 * x的个位,相加后得到新数字 + cur2.add(10 * x + (d - K)); + } + + //d + K <= 9表示d比下一位数字小的情况 + if (d + K <= 9) { + // 10 * x 将x扩大一个10进制,(d + K)作为10 * x的个位,相加后得到新数字 + cur2.add(10 * x + (d + K)); + } + } + //将cur指向最新结果cur2 + cur = cur2; + } + //如果N为1,根据题意,单独一个数字0是有效的 + if (N == 1) + //将0加入HashSet对象cur + cur.add(0); + //创建一个与HashSet对象cur同样大小的int数组 + int[] ans = new int[cur.size()]; + //定义一个整数t作为数组ans下标 + int t = 0; + //遍历cur中的元素 + for (int x : cur) + //将cur的值存入数组ans + ans[t++] = x; + //返回数组ans + return ans; + } + +``` + + +**复杂度分析** + +时间复杂度:O(2^N) +每一位数字都有2种可能,N个数字有2^N种可能 + +空间复杂度:O(2^N) +用HashSet开辟了额外的空间, +每一位数字都有2种可能, +HashSet对象的空间最大为2^N + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode-cn.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md new file mode 100644 index 0000000..ff1d89a --- /dev/null +++ b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md @@ -0,0 +1,3 @@ +**967. 连续差相同的数字** +--- +[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) diff --git a/_site/leetcode/968-BinaryTreeCameras/official.md b/_site/leetcode/968-BinaryTreeCameras/official.md new file mode 100644 index 0000000..89ff0ee --- /dev/null +++ b/_site/leetcode/968-BinaryTreeCameras/official.md @@ -0,0 +1,3 @@ +**968. 监控二叉树** +--- +[https://leetcode-cn.com/problems/binary-tree-cameras/](https://leetcode-cn.com/problems/binary-tree-cameras/) diff --git a/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md b/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md new file mode 100644 index 0000000..1a4e5c3 --- /dev/null +++ b/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md @@ -0,0 +1,55 @@ +**968. Binary Tree Cameras** + +[Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/) + +**思路:** + +最小点覆盖和最大独立集都比较简单,只有2个状态,分别是标记和不标记 + +对于最小支配集,每个子树3个状态: + +状态0:根被标记,整个子树都被覆盖的最小标记数目 + +状态1:根未被标记,整个子树被覆盖,且至少有一个子节点被标记 + +状态2:根未被标记,整个子树被覆盖,且没有子节点被标记 + +每个状态如何递归: + +1.状态0:每个子树的3个状态的最小值之和+1: + +dp[root][0] = min(dp[root.left])+min(dp[root.right])+1 + +2.状态1:【如果根没有孩子,dp[root][1]为INF】根未被标记时子树不可以是状态3。所以是前两个状态取最小值之和。但是如果每个子节点的最小值都是状态1,那么就 +和根是状态1的假设矛盾了。所以要挑一个节点取状态0,这必然会使结果增加,那么选增加得最少的那个,即dp[u][0]-dp[u][1]最小的那个指定为状态0。 + +不可能是状态3是因为如果根没有标记,儿子没有标记,根还被覆盖了,可能是根的父亲标记了,但是如果孙子也没有标记,那么儿子就不可能被标记,矛盾。 + +2.状态2:此时子树只可能是状态1。 + +dp[root][2] = dp[root.left][1]+dp[root.right][1] + +最后取根节点的状态1和状态0里最小的那个 + +```py +class Solution: + def minCameraCover(self, root: TreeNode) -> int: + INF = 0x7fffffff + def solve(root): + if root.left and root.right: + left = solve(root.left) #左右子树递归 + right = solve(root.right) + return min(left)+min(right)+1, min(left[0]+min(right[:-1]), min(left[:-1])+right[0]),left[1]+right[1] + res = None + if root.left: #求解满足状态0,1的情况 + res = solve(root.left) + elif root.right: + res = solve(root.right) + if res!=None: + return min(res)+1, res[0], res[1] + return 1, INF, 0 + return min(solve(root)[:-1]) +``` +时间复杂度是O(nlogn) + +[参考](https://blog.csdn.net/lemonmillie/article/details/87825550) diff --git a/_site/leetcode/975-OddEvenJump/official.md b/_site/leetcode/975-OddEvenJump/official.md new file mode 100644 index 0000000..571d86a --- /dev/null +++ b/_site/leetcode/975-OddEvenJump/official.md @@ -0,0 +1,3 @@ +**975. 奇偶跳** +--- +[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) diff --git a/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md b/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md new file mode 100644 index 0000000..2df8fdd --- /dev/null +++ b/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md @@ -0,0 +1,3 @@ +**982. 按位与为零的三元组** +--- +[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) diff --git a/_site/leetcode/sample/concise.md b/_site/leetcode/sample/concise.md new file mode 100644 index 0000000..b73fe5a --- /dev/null +++ b/_site/leetcode/sample/concise.md @@ -0,0 +1,40 @@ +>精简版答案示例,摘自本题的leetCode官方题解 + +**141. 环形链表** +--- +[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) + +方法一:哈希表 +```java + +public boolean hasCycle(ListNode head) { + //新建一个set用于存储从链表中遍历出的结点 + Set nodesSeen = new HashSet<>(); + //如果当前结点不为空,循环继续 + while (head != null) { + //set中如果已经存在当前结点,说明该链表是环形链表,返回true + if (nodesSeen.contains(head)) { + return true; + } else { + //否则将当前结点添加到set + nodesSeen.add(head); + } + //将下一个结点赋值给结点缓存head + head = head.next; + } + //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false + return false; +} + +``` + +--- + + +**参考资料** + +* 本题leetCode官方题解: +[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/sample/concise.png b/_site/leetcode/sample/concise.png new file mode 100644 index 0000000000000000000000000000000000000000..d584666634ff45e555643b44aa878badc3058cf7 GIT binary patch literal 85605 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 N@>7i`rH`y${|`S@`7r详尽版答案示例,摘自本题的leetCode官方题解 + +**141. 环形链表** +--- +[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) + +摘要 + +本文适用于初学者。 + +它涉及了以下几个概念:链表,哈希表和双指针。 + +解决方案 + +方法一:哈希表 + +思路 + +我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。 + +常用的方法是使用哈希表。 + +算法 + +我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。 + +如果当前结点为空结点 null(即已检测到链表尾部的下一个结点),那么我们已经遍历完整个链表,并且该链表不是环形链表。 + +如果当前结点的引用已经存在于哈希表中,那么返回 true(即该链表为环形链表)。 + + +```java + +public boolean hasCycle(ListNode head) { + //新建一个set用于存储从链表中遍历出的结点 + Set nodesSeen = new HashSet<>(); + //如果当前结点不为空,循环继续 + while (head != null) { + //set中如果已经存在当前结点,说明该链表是环形链表,返回true + if (nodesSeen.contains(head)) { + return true; + } else { + //否则将当前结点添加到set + nodesSeen.add(head); + } + //将下一个结点赋值给结点缓存head + head = head.next; + } + //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false + return false; +} + +``` + +**复杂度分析** + +时间复杂度: +O(n), 对于含有 n个元素的链表,我们访问每个元素最多一次。 添加一个结点到哈希表中只需要花费 O(1) 的时间。 + +空间复杂度: +O(n), 空间取决于添加到哈希表中的元素数目,最多可以添加 n 个元素。 + +--- + + +**参考资料** + +* 本题leetCode官方题解: +[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) + +* 本题leetCode英文官方题解: +[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/sample/full.png b/_site/leetcode/sample/full.png new file mode 100644 index 0000000000000000000000000000000000000000..abee59c76548793d7b3e85c02813f5639ffb5d39 GIT binary patch literal 166160 zcmYIu1z3~a8#juIN*N$8h#;aMtsv4Zf}~QDoI%%MbPO;ELAoSIhm=mo_mFI6BM3KAq4B4hY!B<4JuT*eQo?FVbWXv{9Vyt|70u#QC(dw=)F) zFa*ku0>ZV1YbkUW{KL+a&^<6;Er+XZb*bK!kl_ey?Z0#qGskpB`vh*cvT9iRfo3>T zX#%IC>j(Z=ay5|G{c&{1V1TVCdQ<97N$=fg&ZnO;By^tt0KbW|#1%s!Hzr>UZrJiz z{#eL1o7fk0-)FL6f#CXG_?%aX~tfmC2bA@}i8^dMI;mYx7RW<--}Ns0mW! zX3dGw8r`eGXy^KMR?EQ9XZ7pPs$tzTH0k_v<0|Uhh=padIiwRKhYj+7+PezB;F@N>7)lPYR~4K#Vsp` z6Dlwnc)#O&KyUW_hU{6HZ)XqRy}H6OarQPu}79Otl#$!v=3(uw{j* zDL=o>#-gd=d4=_wI&Anx*+t=S;e3m-tH(Fw&s&F8tJ4oFIkIKG4+)>^xv2NP{F`JY z^UWTn-s!^Ho)BJ&SZM8vPIm#-Bc z&VM;KD6jW$iLQj*i$^MqvuE&4?aP45GZQT9k#=v+|314Bvhi?3ZsWEuH~EIvkMe~< zkFA!A+^p%5B7M^HLkkx?ueSuWv)M3$K9G9qcP9_81uMZBL+MrGpn}@hy)XKHe5HQ& zwN(E5VfB_L{@VVUcdw0qn)pF?C%xs{xk6+?WBZ;WbcpOx!&>n z(Ru!bzw-r70zb&Di;aN$QwT`Rj6Xr|5?A2B>$Pcdd8wzUk^S&dSeCpR<@O1%ON6 z1~oGtURM8=*Yf;jidahEz`X%kc8&4;z!%rcG{-e!REys)c zSxcI_1*yXZ!x4_#>Gvf(ExOI?-abPnb=~sR8B77ZjbA0W6Fw2z@CrCy zp**&I_Oon~>@31oMqkW|gr|h-*cjOj@6Q3=r|zeoO`Q;ezXHKuA}dP!oYMEC4W;ufsw_IE+FRoS zqXKgSD~|b@-(S$+H!IXDw0!&2*mM*i1*kXQgWs@;$!D)=G^_x)7+7j4=mll@MjjN! zWyhr(#2M5NX;{})e{j!q&)ITQ`plyt@nSn{P9O3TtFB_xsY8o6hHUcF6&tduPyQXxa+=XvuG%AL*SVJQGiv?P7m;9 zDZ@8|>RbZqm8_6#b2E7CCxdmIbE1MXx+I6{J|MR&o{I*HHJN)`1~)X+;Vhe88kjp- zXj+)g+6__7%e?DH5ph)bXxa&oc8!^*7e7ozqzIarXEikh-1u$%xyY@2MuQ9 zoB%E|Zw#B`n^bI77V?(9dzX3nFO<#q`?`8$dyIJLc*rm9cTfJv*q&KZTz<1yH-~Q* zSy-F5See=uSiG@dwtDc}dRA$uV-nKa)BQH5FTk*&w0YSb{aV6KA`MW88N6J+2KLKywzhC2+PTNhLiS_gF__(X4i0!rc8JJ5ASpKokzou z9>{!?iMqzdKE}2$@LR6s?x9+gd(?v>1ry0fk_`{N#RsJ;AGzA5?tUd!R7Z+@^y*RI z|8_P1D)ZI)idnO5Yb741tL9ha8lF1nPh?iOuulk7DP6zE`SY_pXKWlxjC(Zo`~KUB zhYoMs-+X;*|5CgXQn~D^<;xiq{kBgCulHl>XIig8@8r+TPg&7^Q4;acrB)9Sn8bC( z>(1Afu2HVV-xa?bey>qrF{v=waM#xVQ+qC3YD#6wJChG%@5d4!Wi@m-Nd<#KG~`p@ z0v*Px>=ZrXC7*E1@IuZ5PE$^hl!la{{WFK%y5l-xy`QZiu4Os6gQYR9v04Ej=I6Dw z5?D%XyqU-R@Mf!wv+E#M7LIs3`U~|D^(iZ~UkV|D3hKD$stbUFsU;`1RXmnijCU^| zp6{7^P{ zgR7mZ%)ZXOQ1T0dyxPfI>`LRpXBK3VB3mN2CIZKrFix0M-d^q@*^>t41~|#37Zb~T znOT#WH-0DXGdHv1)Trb5@83mZCL>HTj9H~|nmlbsvFkE9Vi97ERSgpbi+@^n4(maM zowwxYAqC{Si?&EV3#@7Li>b@g`3D;Z8F7bki9?~FwZeEcST8zG>5O5&(3RN{yAKkIR8As(LNKc|(>C{fbeC9Gi^AxCd&jJIJTz5oMY zBP?)@Ytf?52f4lpxdCxgd3iEC0h+{y^sGHy)?d%ErbjXivB)#owBQ5R32rshnC;4T zsRwM5-hQ%Rf1EgZ3)fK;B(d!<0}cJQ%6I&Fp1)iRAD_yDp_Gx{u1DefGhSeR!3EU} zc|O}slkJmBOJ_>ml`Sc*Cjo1FN2~9l#i7+9`Q(K*Ab03$ zmbtVPHHikE$1DH{HF51W2dzO9p$EHJIGH`Ka1b8L1L^a}kd-$mKZ2JSHX@_r19{t& z1408^657A*+$4S6BQGr7>OKuPFL`L2d(qLc{P_1ilPbb;la7w4_Uwt8iNDPTg)!K~ zCwG|^%ElBGl^)LX^cDAe&s1IwuIx=WPN_Gl?Xd?RttAa;D~HK38BaI*?t6du(@?8* z#q2xek+$E3E@_l6>Eo?BNEhST1=|ZbbL^i{z+3#!ro%=e4&Fyy={o7edcjNA#>%}6 za=scr6Gp5b`3L8(jcv|+HCndDZZBt#=U+S(^7OjWGr1J{-|)7>N4@_>QLzb^{u|X^ zl|1uzbo(*38_WAy_+k2g4~D0$g1=2#4e$p3zdxu8{P*a`)BbaRM`6D&o(AUsURNw} z-PoKLS1w!s85EN9t(>(&XeKhj9K&GQYbJY!c2uCsoi@WLrk1UcqshW%Vk{P`CsKOu<>8Fhtl$YY;Fg2nbpUudV z2vpDAfaM~Kt2`SAVa*0MDz60`i%H0O6_|DJmx`(KUM*WIq9LkL(j4xRGx(2twN8v{ zb!9^2K~{yGbX{qadPGKrg=J50Mnl6dxTH1;*;yX2>Hs8?K5dX!jqBP_R;WLJa+wJ+ zr$TWC%x;3G*#*uaZC_>#!aGbNzEu2`lI@OqiA@RSqn<c@&V>z8Z9 zmu;wYF|9#n&W6p&+oqujLiDOmeC9QQ(B;kiG+T^)z^SkmJ!ZDS*)8qpcnrCQ8gI7$jjB5a z(ll*exb@InO3dMRSlt^-*AME8fe%OB01^}}ujyb;G9rr*W9nr$f^oJ*W(n;kF}1v@ z9-|aJEeW6(z>kS2*u@0N=0Iu7B9c8;V;d83XFXdb5rC`WC9r+pegtV}1M6^egNZc??-I4Y)7k zb2{%M{amLZ;PGa^OqV$i$ z%%2`lXdgcb@!XaMW4)HvG=EC^K1qbVnQ3_v^0?wq z;71nhzj01t4+Y20$d(Eyy%Ls%_QxnBok{Me%P`Ni{+?2iXuOOZq-`j*%^XQ?wlNdx z?bOaB6QBzVmv!xx`QpnZ9~s}ia?D>&JHX0*IVpD>aOv~vy00YC30gO0H1>4RHw)7XC# zdb+T=;++U2bE~?&s3m_4tsa(}YD^eWsZ0afauuZ7hked@!5=T7cT3XjfzjEUcEdmf zvvu;rPy09dqmRLugd-jQ*C@B&>K(o>&o@ zh+3*+%De+8C2i3Et4X@^MGw?VK6&9M1$h!DG3>|$tDfZR`h?#j%wScZcpGqwT%(*? zW}Gt64s=hDt{(t@#gEz` z(sh<3Zn8(IXok(bby5Y4>w$Xj=lbnyOT%$Kgx?m1)A>E+#&sm<%?$-1df@?ES3rdG zUy*LRgv(fo3zphqkGUotQ+I^Yg0`y?5|>}fu*Dfe`)gS@Cw%Wn^T_)wI4(53&Bc{% zuF6klOP*|(xgO0~m0N&@+WnTw+Q)|PyG^*Q8bFeQXXA}?$tl^#_X8|f6d?;4Lim6E z$rffSeN#xfA)@~qUu(K??TLzAMo@TTN2}Td?fa;W(%0PfQ{K7@^jb(TwB61XkaMhd zVF=x*$(C*X>G71S3=U>a=0=LpbJfJ2hbFpcZ zj~iLXFSdyJ)BD}6=VCg#%yVOlv-1`yOV_{uUCb~C@g!l@Naxe!M7)Ud6EG; zf;VmFT5y@XMg=8e6-k#kn4eAZ&|hFq<>Sba(72FsDIk^WtEN+VSC*hv%!uL{?!Rz= zn4(!ShPczjuu{_Rie4^>Wl3C@zt_HUK`S?n{dMW{HfOjfe3l*C;F_RC1rSnbM-vD3 zA4D@e>jxogs4wKO-Gr@Y4&)+GAy@-DjR#P^D zT;ZY*3lRdM)?y_4i_)#5VY)Sm0oZJp#tcmHjeESO9{JOBb%%*Wk6<07@p>-jhYS9J zjyV#^4s(Ln2c_MxZ*M9}Ck>@nEW0JN3VH`Uu`gv?6i*J~^>d%T?XsnP>#giToL1%P zO`g+tuw{ug`ZbASpc3CyE{~s9l3h>MJCkZm*GhOCN}MICI;Qn#B9s55 z;o2*sk!6OwfqmhnRg6-CJpW+>oixjvH1)6C`4Dbc0< zRoAW8-)zeVxRPqe`dH-d(K?}X62Po_wS(1qvY54?L=0^6Bx?QYzYq$usb+}K)50$| z`XIVT1w(|rXbmPhy@6AM@?H#8FVa#3L6)@`J@H4SnYdc#?FX<^YXFt@U-6Pg@tXEi z>SubkGi`se`j+hT)MYy-KlWqs9>2)xByKO6hdWh)f9hvgf%=5v^lhX_bg~ACMMcaH zFefMix8_Tw4d3mnoO`BWSHMY?+0K$F{rGAt|K0V-%uhB|%+*qTa$*}B;I9Z>cmP271THwiw%=Wl zOCjaH{A(urR!VI4wG;VSJf(fIwtLDxc@i(`wOHi8BwyN8)WABXiXxIu|YdAA_W$a>xeFSYb2)!x! ztF<1b^vJ`)Lag*ep@cClbkiONiYa{slMF&}!AxtW7cRqSSzCOc#p-se&)2;fx60UW z+_x|RzbGI45@_eK^FI)coq~ul0?7Ba&(87Z*1R3P?QeF(bObwYSYA3FkT&p-m;PvD z2~Rdp=7Y%ytmvLmpwz9jzKIeRMwe-t1fdmH8GDO!EcX6KmyVpNPBr0DjQ{0W4y4;C z($<#m^KCLtf0FPAh`4M0O|dL_RBkEs))*@2$(GNuo*xve!)dq1E{7sisdG^02IF;!It?-_PNSsq7;Xz7cO@GIFax+R?I=S9w>6+ZiWfo4>qKZ3L37s148A;z>iV-cL?K@Gh zuI5*E1p3RN*41tiU@1;jBR04SoU@^8PCX+TFexAKP1M5QX9JZsHl^);o#WIDmK(m+ zBg>nHUB`?g@x{D@>CZ5fRMFkl4z@BZyJSsMuW69*_($`bxbRSlmbuir$ayZKv;U%D zxZ@x3^zgR|6Np(Ax4OV)?&*39VS04ew&&Wn4eIKt*=+KI{qR6Uc4Mcc%x{~}wW|Ru z3_gSyCD1^bN=+iOilv|nwa*zQoi$2WpVPxy-}XVv44`>htp!?m$@!U0D66Iv#19d# z6?g9f%_h+fYj>-)ayQ%addzkCcho(KHS!uwC7l94aF1YEn~Rh&^F6D?q5^rMi21HV zYlu-{Lje7EwN}3@826K^9=wP<>DJShn%5srf(>KJ<<9>_bo*(t*Bw?!AdnvSAM>7= zG_8-4coD;$_D?cq0*o3iM8f&X)e?CYG12s67Dh2 z)jBLA8`!VX3)qoJUyIfl^uan7_{}8&^L)mftZ7m7cz^bjGrOY9_fuU&M$$w3i;j#) z8!9@nZ62wMKVAn=!Y>54dZy|fqk)Ofu*c;Msiyr*pxeax8eDCg2=1#&O%nOB^uW8q zM6&jO{#fveq}}WOv7^)Iwb-m{nJ@WQ^yI}UE zzDdn@JHVI)a`@>qg8MjlV)sGOWol5xXf%Xe(%!HPC~53}$a(vEO~rE>7Y9Uh3-YG4 zo$$j77Pulfa-bkJ`x}gwHX@YDATe9ji9{8U&OwN9c> zXwjcVXdv^uv?Yd*6b?mGA` zhjrVM`AqCJtebpWFA5m(#5j-vUs-6wGfl^8RdA$eocMIue%PYVf~0` zDN&rJtOvB#XEsN8l>sz7w9_Y=W+|9D@MWIwjPcOe`kYN-U~jACR>HL68RLZ0^lLy5 zD*sf&y#*L@u#x%sOtNofhtg!d_UQcBM2-<{g}?65cR9@{V2A92+ihI8Jz$4beME#( z*()M5nC>Stgi<7oNcx8Fwqhb|FXA3SZgdMt?jaGiAA1B)sjZ=NLOzV3wA$Q)Kgqln zTHpWHYQog|$222iMUpE7r#ezEc+XEFB2s51h=yhvdF3WILcOAI^*(v1J&T3(HmU*o zKii$Is&?A060I$%!VhW#^0W`Jyz!PLZtS_(F0mhX(c2P~;`^)CV0|Z>*Axc1ECgbj z6~&0y@o;4QB~W#Oi>|e1$;rgFrVMhHRK&V|(@0U%Uc54qnP`Zl0%^f z>~mP)1V5oZl*|!uuzMc7{v%%!*UA;(5!fJa^4HM!&oia33xT=B)4eyaX2_Eg%c8An zk--#`z5}YsW9s?~FMZqJ&{;ky!Kr5>`4LA(uqqR?n&HOS%4d^uga*+`Ns}9Bax~NK zIaP*`x!Zm2WeJx;GDgY`abHNHp73bfe$A`u<*d-Owi=+Ao3V&(ubT`KR}pRZvieq{ z_iKVU6XV~V?>9XyseII1vAh`hS1t&XbVk^a>VNuGExm2~ms{ynUH^ZTE%R@^Ev$N+ z@R7UCx48ds6@1_(qy39mSX}1c0DGuckv&;!tQ=JGa>&{`x0dTE`TaFH8;Oz76WK%& z@$`BLiNu13#zok%Uk^o`8U_&ONzcexOU~VRqXyq%rZETfkY0fPIfl+$dd5W zg^X{=oT0tjlq`}TI6iao;_$RANk>P}=lzitQ_I%JEOgu?)yPiR?IEKYiwXp@>~>7N ze*UV{HBhEzH()@GXE~;2IrraaL_Bav=jJsP+g!3xx2v*hZ=JD1m{w%B+hu0^qpb9! zB!SfT6QA5#nUq_Mq6ejKTmHA`1i+bm4VI1Ed)KZ!!bO7qjOfZLeKtB`5K^1h?VVF9 zX*QAkQim@EJf~`u=#d>jbG*Yxt-{Os0@wc)bN_+7|1XBv@Ugh@rc4;pHoc+ryxzd! zHSFALN_D5^aTe0OG!!n?0GP^HZZ1BrCx324WACytjLkGNMtKT4X(xUrJSO+A&X1$! zMw5kt9ZgA5GaC2Td7l0XWL~v+>JC+@=2>K}?=?*Ca-j)~Jnsw1moBJVMX;H4A|lJX z*nWH!WBsEBqHTG@ET;wmwy@pHtMZHe@_AB#U)gAXvY7&JuT*Y6-)3@_l>RF`sK)oa?k zx)*|1`fn-ub`8NgS*V@*{P}EAaCWqEi@@k99&uc9rS*YojT6!F{ir`TLP8I0o{D0SvBPQTaPv}evh z=`&1!=R$iLZMDbf?_)Zoq5rpn9<_*~nC0Qz-UV-EjTB_B!5N%GXCz)_ihme?SFQY; z2&x_~Zjs%jGb7v!61>(N5oe&{8jGMruadxZxA5knTHQFTBEQ~Om?VUV^<|-`O4$tD3z>hR5 zZrXmUmS%fYBzii9rc5d_qq#{ZsH2q9{&S{~QQunVg9yrwx0DxdXi$Qh5SPn+eC|Q{ z3c`T<&L!J-{}Ji&MOvobeB(z+C4uxe6P#bTG+^VlM&7KVUJq&e3Cdo-`2CeGjCXSh zYNn=VAy<#F`!cyUI#)Md-sLR{e;BAer;~X8-m22OJC!b*dYgBS_Ls|hcJ_y#0)^IT zU?Gb(NhP|=l@i5~v||l&! zle80k?{*lW>8VlTeywE?-eqY20+XKw`sc0sKiKIz5qhidyEP4W-5WRhc=pP#79WP2 z1V-7n{&|JIc1<`J0@B!!;wB&D-jb$P_9M&NG& zjta^DSd>(g_YZz);9HG#Uibm_7X3Ph!=CLyKF@|#|F0*L^OTe;TpM`x?(`jK{@aep zl^Mpe=96K;LtQth9N%c%a&RP$SZa24*zSL=n;gf6Y)Cll_opf7E@zSq6`XjZt#6bA zl<6dtiT5%@-)}pgJFmP{0(GnmSs1KhGiACu_9#%csPK<4Elqx76z; zeaRqCU(BY^W^E3*cjmmRHyiceLtA0lcETr{0M{Ai>5OXQ6k0d-6c))Yxa=XWI}>%r z%FJcP>=tFya#@)|-J2@3+=5Aqj|KCZhL4ed$^(>gF|v+7&`j}Nl%JN-8koo$VO!~S}My$!$R&!6Cf!&S)^bhdM+>CnpSK(RZT z#z>7!aYc~If;YuXZui^PvqrNi)-r}01DgKmTIOzYVx#y18_-|GJCiqh&z0*>HA7fm{()Z z0*`yErg5eZk=Hn{A@EN9$$zZTkqxviI^5uTa?K_gQB#soF=tphW=oim9uO>TN`kH3 zc$xf6Y3Xn=cM&1etkY(wUATU&c>iO|sh*l!75%M+eDwvq?mhW8!f=l$x%cEH<~5RA zleVii|Aj>arODeBAF~o|iEAG}XZr15uKLg2q_4vhgp8w7XbA|xGDJmlQHSy$pAYIK z7k{?V+gSi~@+0+T1qSN!(f>m*4teNlhE5o^-^%RWhJV$R`y#)WW_a66)3cQ4aQ*Da zX3oS3eTj`ehnNhVhMBV=)Yuj zJcDs&^vzJPdz;Os1hW>G{q4%ENnjO!Hy86iK8Z5J9zQeC=cQ$;{11=~>Qh6LBV%6T zErwIr1_6O=$TXhtv&Zto`r&7&_yBW%Pn1%~O+e>9Q%XAs%`VAp zCV;&ru^dD-a*73LtybtvNrj`l>OAOQI_R&kQZJ#)S4*I+AFcw;MV70ElrOHl;7gAG zt}1~W^q=LFe1;U4dwV`+h;ZI*k;#F?D0C;cHZ0)f88E5+tn&X@OUYnA?3sc!P>dH_ zr){v+kNMW&X|%6e#S~JPJVifBw$I6500X|Kv>o()&?wMz=w}SBH1fWF=K5uNzJKGg zFy#X2S6_@mR`Or;J=HvIAlgg|3vOi#^xaV8a~Ld=Jq7~BHH{U@t)X)_&t7d*lL? z7~_gJMd!%hB%B*5L7T4rM(U?42S(0d!7((EU?`CoVhW*stDKoi{%|}P7 zAlj5Qxa6lE##i(*Cs#Q-nX{Yy6tFmE5F!j(v z?gg~`aZ(`lgGjM9&~@@&-*$Q00aHiLF+g00t^MG-RkDzVeqM|E+F5*?K=Kx+Z;5{# zn;b^NMKVK#&nVhY;SQTQDcw$A!20B5C_#NEWGqB(<*_uD?>w&Fe0gQM4DmPfvhG^b zG~$B>7=$hDu&AsHq7ev%QbZrdOzYwo@0C|)1*%%CE`VIp7$vi(=C;Ngw5Mj3ERH`< zJVAf6sXs9W3|#S14ed&fDRK-xY%(0~xvznK-l9Fk|4RKG-~U$F@F;Ts?xe&fCq2Jq zXSs;ot76!-r=*0-E2d*Lt!m;So-bB*U{ux<{Q?d{GYbp6Ua9mRR}OA}FJ`0FY|iZ$ z;bSn@1KUbU?a5f(+GR?~P-55gSd&VNlKoYmMi73Co^i$Mv=??O8LD^~u}_P{W~@VA zU@aN6nmX=LDzHgV?uXZhk#=qIG=nriC!bW)Eh$V;!M@$$%FpIvToz~`6JwAeG`TiF zeA8*>3)NNLBh9})nmCcc9hZg(3ZjbU!aHBn4I4M8)Q?+5*EkY=IdPVYeI=1?*5BOh z{IyLKwIaBg{BsAUxFgjzo1>#bgWUuhzqK0IZnFNv)ubE8kkbkbaw`sQe+7uYl<9h! zT}|z~2iBTJs~_A81tFew3_|KkZ(in9%8(!Tbb3jR_#Au^MSC~S;a0aaCxe>^Js#Gh zlkd|~$SkJGSmMI1yqKS)Iaxy$Q_U{akc^Qt3O&UJ-Pj9sD|f31KeLwJq#2NT`s35y zxljV{#3mOAHX{=f0(HvA_WUE!tMY0Ua`!q8e!jB?6VjZWWH9vO0AydYt#GEY!ErpP zL1a+h9Er)eY>6M-LnAoMRWKoPRq01l*N*7nwm;xon&7m^B9yqma!ayk0!F`ecqGCh-*swjUq-}x!te5z%+M|p{-w5uC zaly^J@nn{WnZO-OgS+TQ$Lsad)m%#NMzj;n9Oj}QKib{z8CU+m4U7DaQfGj&YFli3~maJQ;2Vq^xf9Oa@8Gt71QMoFMB+N#(pznWgH`q zKa%4y^Aoyk-G;Dm_p+Cl;#^@l)s%BOglvcmf@W2?^EMze{owb*fGBi-MVmpt6zz3_ z$>%*X^J0r){d&rAp)Y)9>}TIqLDt+9VrQv?8npJb^VUH|v=d(2pOt4`m+!p1wAU`; zgZ+22H>Y?>yzZvnprtA8xY4y&aLRlt_{3oL!w(*1-x*UuZH7BS8pt{~*7f;dOZ<~J zQ>fNyxw=$vObDus|;P{a9$m8u$z++X=8Dw zfaROB&nweJf0l|@!85NA={)Xb2Wmtv`74`Qnv1_?|2aKnXwZn5NLR2mJNmhxkR-1m zA$VKG0Kq5`B2Z%^uU!%^nLPaLC8nRA`j}32*)c%f;5dS7v8a>fs-9a>SL#*t@wlll zNIN&RnnTXG?eSaxiOy5+bnz>oIL3z8)odDRwJADuERma}i7G-db^rt&EaSMUg)TYjC_C$M7oNKhS0bJe)dJjo|t+IJS4@e?39lIb3CA#$PqT$3L1 zw7|OQwy6l99XTt@&YgD$PgJvO*tE?qTH46O$E z)bOZ(`MQEgH9Jf$KMb@&5LGOOU}6i(58*$?7A}9CWRJZrzB*;o>fa7AYZdJ-83+nS zJ74r}>b{&22Tj0-hMF8$gW|V<&fK zWPK~Mll(lbGt_JWmP)u9iF%AGCGDCQk|ju(Ay zjKSTMp)%`2j>u@|LOuUeh{Qh<6f_C9x}cH(r2Wy6qYU5YtQK6`Z2U0?=diW|VV50P z(z5VgM-$g0aW|)fS-LtM)1j3|IVUeSM|HQqZ3BN9Vrkz*u^iXFn2%ALt2BF+b~75N zzg|t|0k_we5vkkjK9g(pJVX7}f^*5^lG;?8j)}Bq6dZ~I?f)!@P39O|7dxTQ1@YK3 zrKl(uD7&QbdY@NZDG(^3vwF;JrdBI3mKNs?V z)6v9Yq}`~R7YA^S(uz+w!2re_27oN-+dv29-TfdCER)tNVcX5jVX@aaKUI&9?Payg zo^qJ6T*ASz1Hdn&eUkl}UB`2HNY}HB-C?b@`ckRvM1V{ue<;Cl6Fd))Na0=GEIa7@ z)Tf+ow!X)|upAIIOj;_7v70EqQv(Mpc08V~Egad&?AOOw-3C4m<>L=cE9&U{y2SigYPnLHu*<(y;>oG%R>$LggWm?_>z&vyNK~;01(cN}dRU$2^~$WH zYRqMg$Ew-`A!70Sk@W>*S)SSAp1y4@o3sgeOy4aP>el)#%2r_E+sV1>_L;t|g~e2C z)oKM$CRtQVK5dp5*cVE{_bs&|=Wh7WLbnfhgO&o{Q~p_R>M2D%S{(ILfKz1FnrOad ziyBf+SOEx@{+2|}!|S4Jo}0OS$45RceWq(ZkEs(@q{E$~X8B_Z>Rp_*AnIIry9S` zk&AODMs|~6TZbM1ufB_oarV>^b4KMkvRhxMDd|W`8Y;9`bc^cNr`O0+bIiM)b!o^Y zpt)j%8q&8$9z4)?t=LH8A7hA=-+Hkpxv(8N{VS=CdA4qLTd|-$Vlo0wIx?9p!F1Jq z_(U0+3mvC)(%c7*8!?5g+YskA7$&x{ren?%UA<`k9?97lH||3FNjv_o=V42-@mNB1 zSi9K=QBanv=uyvZ_-1vpe3O8UG7L`J0_0NW2e%a-&();YH1fj+HjnfIpjnjdPU>KN ze8{m)A9j^A5I;5e5hqWMImTuQWo9@?&$j7Tl8S?}Xj`xP^g1!lv>7W8#J6hWw60~T zfecIoY5bj^JXKxaPXe&!^%X))2OYsdo6CCGUMOWPY|6n3$=MR0yXC(fK$haedkOJF z?F_O?s@ExckfvhU!ilONp0g@wsi>W~lZ|3}=gG0aL!Y(dS`s}bBn##6DM-n#wnqMh z_V~0_QBk~DpOxGv3snROIDlU{^p*3vuN>mw+up&!dq4{mq;gDXbBTGa#`D{#3R7le z=f>ei7|hr~_FMkqTP&uda&eKj>5GD9Vyl=sZw;uu36F_i`8o|LKF z-x_%eL};!EI{~(#@Jiskya0NGY87V{2(Rq8*HWYEvRFEDn_}0+1g(E!4gNHvq=p+$ z&zU>Jdm0o%ufn{)4eCx-56JZtEm)vi2a(|4aT`Y_6QRF=6LU&BPaUR^l!G=;O@dt` z7UHegp%u?R;37M{1Mh6VOHuwnRkcs8@Yxx1Aas-MGas&30CmheduqnE=@ZxCfoi8Q zlfrX%GuozH_8k5FMb58x;2hjC@g2XdBnJeC7JHt zh8ehR1LDcCe`xB;Q+sj2i_4|>R?7%vywO}UZ~thlGnP2nOJBoPbdbRkQ2vw2I%sn= z4AKB)lHheEa-ll!a8?6Sr)(tJB8zjYCfvRU3Eg}#mqp(R&K*=}(+D{kV6cxaQD(Sl zi1Yyb+N@O8wW`Ac7B6OZItH z3>sHI@r5`A2THA;9+P*t)37|c)tF+bvJ_&5Rsf&{8i7!bCh>O$X^}O10go2AiNF3l zToHBg{{i=#ZBzsUJXc|>^HGu~cRGX(bSvb3^H#+@fUC4?z{x*A#kRZCb?{yKqyBAI zUz?1zI$O_!@_6Mjt)p9DjE*t=k8z!*Rr-2#u_~1jSDM6AkcjK0UjTsw4&~;&wYo7SRgW z0?jdSun^91J3#F=(KWdqx5_Lfq4~mVL0u(F&p?(k^&JDc5x+4V5gdqfL@cA0Vt6a{ zw*y3k!=?;M``mCGt0`4UG2A3!vbZ$1+(J>xKBI}Fgq!QREW`}(CzvDCBZax}<-j-` zs&qbRsFnMH-d3feR<&ZVmCo2YWRaI;0J;6uCsP3EK(7l0-0D5ax9Ql1pcnd`#^qCdPKSBZqV0vl#>JVOBuNZOT_n5d*)OqRd#6 z>~GNzvptJv_bc2zn3H4rK^;%smV}Zv0`!@$XX&rBNcu!UwSLV`+wCMf-@39m2k^Q6&c*&P6pSS8w>ArE~>T?Ao&cY?I$0M9r7#ai*-ct$Yi+7{u zFm*JWa|Jt(w}fNt5cmya3ZCqj$#q+KQy%jUUFkyEE}R~@^ecp`(?gZ&_sJD1H3AM^ z)vcTVrIJ)AsoA+pby{eoPG8#9L%1~^3l>da%@jM`a zMoN}QXHCk2%L*CN23S}vfy#X7GW2$qt`ZOhhCsFE0CG}%bl!5aZFi@?7yLOq$6w;} zxD(Tm3A@GPJjAhZa2lV?*FHE9(5y`3wBi_IYRt7{q825fxJAO9Q|6PJPeVv*NyeZJ*vsAD}id^fQ z@QM!JdfO}kOcJtPE448!n#ZazD_M^4S{1Q0DJ$NqIlhsp{Fb(+vck>jc55SJIe1wL zyU+s7+2Pi=ujh7PO<;`7UUpg@P_3V1U@_V|q6!5_soeS#tQio?s9%!@K~d*%iGDt$ z7BAaw-f7Gp{}kufx*&F#14tq@AYr~EJ=N<1 zGJTw*db{R+qDC{6pQC;6Q}A-eMbK1m2TlLXj($z>eL>!$KRJzw z>FC(LTCp%*?$zC9$oaJP*`dsEBoPAbmzpykZ9XxW*x)!?GhGYo(@R1tNk4}_vMQlz z5jz82pZBMfi|aNyKwEc^^mb|9{l}YH>O-%Jm|&{a#tb?V8%OtvgYNkT$RMHhl{@8M zidd4c)F%^>+4C;@00wi1c8iXmqgfh3B$Bkm)_D{OfJjjESG=<3S5Z z=bV~Q@sl6B0lVRuTBOGcWJMSO?c?^K@gi@A*xc-?4cVr+wz%X;7uC4p)iBDwi7BB+ zqBK%&UpU~jYW1QxbSOJbhHK0r6P5;ao-O(KhGKWvcwG5$&5O|E8)T%uvmB7HvQ0bP zQ@}AY5fg`Gl;9;%PKJo}ce5bU)Qn4~ha_3RQvxS?>(cM zYP)t(EQlh4kBEp;1f@zd5s=V9kPgy&4=pr-fP|_D*eRifj`WTRMM^+Hr4u@YDpHeB zloF($1^Djo+xxuZjCY)W-`MLPWwm?Fd)8}SvwXRF?JaU|&pMcN%VQrGd>glyetQiW z3`w~{Z7%jfAzncI7R)EVrC=<5JFj|f=aEdD!#TQG{r-p~|5x>Ub{Ku`Y`KY+2Fs#7 zb7ZRqGJJ$;>Je?5Si^R>*J8mK$Nbxp$v6 zb`zF7SNc`xAT;Oa;Z6SFz_nPj_0(#+?W(P%-Tm~fS#BA(X!l~tSTwCSOUAT;ws&hS zZpXpipQgiW&Z8Vf$kw>jJn zus1CVfVp17AwAS@um&k81=ZFp3j{)vIPL+X!2Y+Uoht?POy|zOe zqhS{RY)_is?wg`(#>FHY)Q#pHw7E>NlsKCQ+<|2`O70xe(pfUj9LNrt!{hJg2hQxo zwQVh2lnA;z6}TZ_oK>ee*Ri|WCU#JTuViD57pZJ1`BD5+X6%dc0DJ;4zqX+rp zoMz8}R)gdW$M&Sv{-l@d&A}T71&R%opY$!NSW9RQWB3OvUkxmD4$O5!r1(jO4FXdT zpZA?$-;T1Wjy3~g%he4YCQ4clEQ9v9vUIygH(O??TG<*7QR7)FS*u&A z2@VNuDj-1S&Xn)*_ldjFFJFsy}s-d z;-wi#HE5$pacy5sF=(wLvUu10aG(WE5aSS=@_t4m=8I9kF4$OK)fiBJNDps}oJG-d zEs5{SZ<7>n&u+tT|7>r~4DHkfAtAr~S6ymWKnsjMQd-~8hi-xMTH<2L8%O4}D~SaisLy<>4+WRcFUZHg|zG5|+X)eG0=sn<;H3fZ zZl3MUx2HfRSQ&@KmLhV=f@b@p+uaG&6Jx@bf)K;fn}h6HGBZmN>8)xCIOO5(FGtc_ zcYHCaThyb8tu68Z-I(J4>yx^vHSq?)b^V7h9+a70-_YWctijg4Gu#k$*R7^!P}emi zV7ptb1P&o@ksh$fsAb7^!)L`)VH|(pU8)WzD&W&#ELAVj%2ygGL#7{dPi@dCmf)-Z>ZW>GRKzg*7U!nS?i}7O)hPOsQ zBbls_q80#4f_z)eo^Dw+{QUHzu%8=azD2J?0y0ypzYcC z)^Wce1;uvnU=8hmc4A3}d~OwhRR#G}E`f&wm(5F7z?N0a_x^&6dzKMqTDetfuc1}< z+he*k?El`OcFdUNbxlfckrq79AEaRdF(F!7-lES|F?d@N^KQP%v9P%1eMMScuX@MC zEK~xj@J-w6Z==z|BGD`_M1iY13!PJ|G@A(r*?vN06EeNP-xdxI$R&Jn?ehTm+LXPy zn0Lo7ul33kt&=vx#qCCLZlNU>md|KI7+fLOG_Yij=sL{ZF1egR~hE)uzC>%PR4|tt~a0tA7nzf}X|m z>IBbd77U0aiN4Vza!fT8W(OI5EcP9Q_5H2hQ|zFnO_97z)Prq41<~`P)J#rOcR)|% zJRQg9`9w0+<5xYyJGQT0(E3GFiD6B4`onU9W2B%!5AL%grD5YEI>sC#Xa|(0Z=s#V zH|^c3>*4yv$N>r>(6l{>%>?=ldNO?!ph~Xv*u>*^p+NWSv-kg^#{WVfU0N^mFPlQU zIUFt}!(ut-H*!Ku)cp;|6n?ck+tI=QKCWk9Xher1!O2@sse53n z-{Gy=&=XZBh*clX6cDD)tdr|Sr9P)d(Xu#R<-HppJzqQaB1}U(<+p1-4d!(~GWfgk zmsl-3CDCFtWLbCQuvx?b|o&_s*}7!xD0W= zf4m|gtc68hsTNFsnGQDK=BcEO;-;ySC+AT^>U91Q;h zE;a;~&jp&!?OY0qM_{Eb74G^4v3g?4$u+dc%N6o;$4VL9-DJ=%7n&Pd zaKt`P*;#xGR$NySA2?r?HVue>w;RgKGh1#x{A|#!!7(L498a+9rl*@{}fQ|xLf%zN0r8pT9!{w3<4>jRW7Lfq%o zOoJP?#MaFWZu>jmwM#@L#X^-Gq_jS|4B!e%H7%;ZB1^}DosmEQ6gWkA2ci74L`7%6 zxBE5djC%UmxCUL_4GZ?07Va_jd9I~8kptGzup~>&iUXB$8=+vj?M0Xb)Xx~j{FHk~ zxGwEcghV$al|xN*uq_6qTTH?ae&s{nOGte4z5F#?M@G&45zeFP)x{-(^G$JbNuRZL z+`#TR^-*oqW74ESE~V@0!_Rh8N}rEaylfDIZ0ps_*B-bUzEc<7s)%^GJ>KFJ^z19= zH{$Pioq^nOhAvrb4Z<@TaFxaUAp|Ijw3ZveuRS!R3z5n(^)V@Cc5!M*l z9!~{(*xp_YLw13kqT*HPBGk^hLYACj-{tzo1}EDLHm;G)ItWY8cPdM!k%;8W z!pFLz$Cw&o=M2mLNUbPT#_DR$rYmJ=?_Ssra=FfjbmynXSFnF#>^-uKJVX0^5%x6^ zkpyJKX+^CZ7y7Zp;bi{^*h@1#&Ui1%@*+;*Nsk@?e zv^v_rZQC}n?r~o8qWyQ3>BRdT9M{i*q2EA#X6kb{l=7;Kf7a-RcSD`I)bDp(_g0dL zkoHdvGMnSd8@|eZ<#;K~bAHKl(F=2iJ8qYEuW^Zhc;952HuE{#`59;N`}MGB;ziQE zpQ0tZ@!#c}Z_@wTxOGGq1NC~hbkD&#*#)ARL(476Z=jMJ^D_j~NLhZGyK&Pl3Fc@v z@Iwn%Mw<}ReBQiyuJ4Az?D6duX~Gyls1TJ1(doRzVTD{`@s4^g>})}cq~2}hP2_a! zgemvZ{q58?S|_eZChJnh^Ai{~D)mx0Xqnyr<>X3^Zj4C5`-;|6o9R<~W0YSoP-ja5 zt1ef?#R)32=CjL9v(nGv@^WavCytY!zA!sdWT5S=dYdjjqPH?ez2_=?ar_sxacSr| z-Q;|oeaopXg~H+=-(PUH4ZRC%-0ZoZ-s5WY4dPUV5XCP+400`WU2+eQBFtsH0lN~@ zI(~0D`?oZBsZaJzt(x2mb;KtmL&`(iL}o6>J}i=hHWd9PM1p7+=rE|-{&nN*+Uhf; z;`C~1c0{f5DLtfQwTih=G6xbXf?=EG=9KNRpH{Psaup|d+X4Sf4ng9 zJjxc(2?rIMm#G)3cU8IE^dTNA0)K# zHjwGlnOwkhhWDT8*flY@oQo!R(RH$EJ3t%$4tmkm?afyA%(v~(I2Mmi~q z$|vsj|6!Of*=DML&Wz{~AhUcJtRa_}2%v>48DnWximh#pdmS)!3X`R29Aoa|Ojo`x zVoEfkIXQDLBRGDj5M$uhShpeuK8<)T{Qi$~(Gg~+blH0{ZGeE`Rk`#=xr%>lwpOI* zx@6rZl!Zr$n(KHec+8F*w735XDUFW|BjfPDqCvwGSS%3P{Kf7x#UtykKV)vTc1_1|s} zu1uZ(o77*k2Ncm#2*{2_5F4f=abL#;;kuTN+}#3A3|}-&J3TKoKdb zCB=i)YDuzN%2_V%S5cDoFHjjYLh<*AjqmE}Nk8)ICyEd5^2S?}Usx2C$hp#2T0A7q z*7O9nT*&$m?%us$H@$B!&sWFLy*oi0rX!R7^93q`Hvf{Ls3I4g*l};6cMS$|)l0mK zDoeF9C;JT@F{`UIm#!zb^-4jsR3!t7&Kv&eCv$58^y%B0)x<6h^wSTh`5d}F`ytd_ ze16Q%Fk|akudYnGQZ9kY_jb0*fo_2w2KbcP;%<_mqsoC{3^!V4g-=jN)xQ!R>szTLclT^9)!bx89xKW`4DR ztpkd(Qkf-L2ZHeZUc-`PfmPS##F?!T;h}X1j<7KJ{?P_$va)g}5X>nwPHMx_v`;?T zw_M#X@ukASzR&%#p11BE5(TrH+TT1|ntYwqZ7kDWdv8pXSZ_iS{%Enh?Loc>lgjPV zB?ii){8apD!8qgPU_UDXQd|*)oJ6`%8ramJrTnJ$U9A%neF{9iuWxI20B++x=Cb9r zyFc$Ifb$oD-5W}ml93z3gVWRE37g|MmW}N!%87X~_n<9}F}i(=7T=r6@l^+2V^zRA z%W4fkYu-PWZJukl+b-pD3X+OA&LKFc+b zBNRrP)6jm>u(7z|my62=rd)M~HQ{FnfqGq8lZUmXO6o^;_Rx|$ZgPJ=#%9yPId)ly zCGNt-&0QFf>(K3o)BUr$E0~vdZ{pEbz{h#h5_ci&J3cW2?pB_mMge~nIW?(g8ah-3 zFHy)_u(Dwx43Fx?eZrO#DJTQxcZ%6$$iFIVm2wO6pOxpmr`t`g?&l($44djx;;$M}f);#R|Cu#Y&){ei+WEi`b*6{?KVYtkv4+BI-QSYW&KH0*1wLLxE!g2!m6`SxQ+I7I1AN0XuiE4epbWm zmjA#S>2izA^*#lM&M(EZ7V5Wzt24hfh+o^SS!S2BuOpZ!Cref)diQJq?Xkv?9N6n; zrtFT0&sNK;xq|&GXCg}KAeG7X2?-{<)?3%^t}>I$1*BYhrCjtrl3AiT=O!UaZGrZE zIx41-ysKKUF$ln3EQ%3G|k0FVdC_aq_wkT1#t2z^=RR7>e5 zf$>Vs8Nq#2-L7%v{($sR(k;WEL8;Y_}hns)i z;EoJd7LDHGEn;n-h59~q{%5X9`WB{%t|(U}_eV$iL~=nw-=>TA=WPFbXE%zO3_c3p zapa5pHuS|M75iS@{pBTwZ$l-TbYk4I7`mhmyH3ve!cRin#?Rgs?Dj2{Dk2xn=a$)R zaV=>#eMhkmPLnNn{brV?e9lAsj5VAyVyuQD#LKG@FCU&)$4Vh|k_gWhhE0WgA=n?a zGTfgxhjKkfcHfIRdXkwY>Nh(#*3Je7U5aC>B+t~#J((Ozr!_P0$I87Q^gK`9?|)`g zDmLYp<48`{U}MQzl~}8E9|zSyu&p3GUaV$i!@qCaOwE|PLF&V}x|SsO545z`IwSGO z-D@?cTWzzWB}!7|Ba2{mXhL*MS9xx+>u9u(uv6*NudlqHV3ceHie8v3 zx+O{M{i_oEHw6;5!!I#On%WAO`jT7APcy99`mu|pzb4{{$bnHb4o2(bG=3UhCZAX3f#@#81_ABHh<30xttgv%na_z^rQntyi z_J86m-M>5}g|ll=iIUhoQO#om8Er2{R^SPan$KLc^65unto4AExG=s*IvSRklgy&CL-jF;i+{k{J$Ey2$jip4m>_O4#77ETDVid^ zvJ&lGT8>>~ay7|2zyfPRu@jQU1mX-TF{HBG`3##sKYVIUn@O}+x(DrFmVYMe>wcGU zf|-a;v4ya6Ot8?YL)HsJ+Lz!z?$;D+4*8$HSoi*&lV(YNvDW_NoxAF*l%&sSFx_W* z1x+-j&aM>x3&xgDxjDYbuSqB5-)d+QWlQNTP4#xg+9}PiiY}Z1>uyIwIq@Y$EL&~) z!mN9K=hOV}L~(`<2stR0m4=I4X0~+!_Qx?yUHFTfjbltH!yL6%F?`_$-|)?MsDjW` zO3;@jp=Yl8$P3Rl$jW3TRZ;HFwyILIlphaHWA@kB|2cTD`p(x>r#b5=;4TUMDy-Jb zIs{nUN3`e(>{odc4jzpEHNjxV)SXVTu`eRyn!%#k0bHhCE0u{l5*-z0h}TDn4Q1kE zc3m4~m2FLwJ?(sP=xO*5#{25+kSMin_*B38<=H8<&#Sk3uA=p+G}qnqsOHtuscDQ- zEPp59I)C3XXW{Q!sR(85SK}m6blP7+ew4o%Xyvdaxfo+XVPLgLqo77-4FXer+^HbF z@*5(_3m~OsQ}u6mC=RPr=eOChm?fuOGms?^;nU#RyB^nL5li1S^m!@Y*GU(9fu~>9 zy=wsjj;EuSJG^rVl5cZke zQ9GO0?p5@&L1u7QX)9l6%yO6>gK)`x@kn6~6lkyKyQ;ZqVO~Z?wGq8Q3AjYZJ%6X8 zl~`mAV*}M7nA9P{!_0raiRbrFg**vo$A`JVAAr9U!eb|s+lKDkgiFO12Yp*roqS$j zgKoZ%H~)Bk6wYH+bVqdH$LC zj!yX9R+9&VwTT8uUUmfbgZfe+r&46K%O`3De}AsII_@M|nhn?@rph(nV3oeIp>Imp zr!0M?Xqh3CJKC8*Qj+ODt8UWnwAJN}EBHe%U?Y14wvXD{S~AwWTUZlU;5Eyjd*8_BQ#FdxlbK^(w#Km zt(*KK9zq$XebRp`vs@=;a$|_{h^CRP3pajF(>zlf;P@CcVMygpS4+!0_-x<`iK3`< z7Z$K&zU&p1L)%$wQ{%S+g>HgC%?rn{}>vm2z6n}__oH(XbleLq={HjhEv~AnH7>M?Xq0b(X zQVO6AxUy09lZ<+^7t!#bu{-bFY5Hr0p*P_fVr@70a?@ty%!~5gAOLR4#$UtN@`TqFmeYInFnXN3EAgk}z}1`*tC2q|%XjS9FYW=1k3& z%3T@{MDx{->)5gf&7qR;x(!tM+C&zQnEm0C&GWy>0o0J)REzM3LUCXHyJ&AMSqR$u z6O#;fI$zaZ-u{(#H zK9AmG_spb>1CuJ*jy^MwGM2**t@Uly8j*AdaR|#onxEy1`_3iX~XxQy(oJ0vU))m;d&oSYsMb3)frYhZ25{s zhj2NkAD6Ni&6DCv?X>WHK${r5-QBXIi_7%4;d&jl5J_7F(5Y(b-kQuaj3vGGX<*m8 zQ<_#RE#T~4Zlo^kvMiMPkK2(OfYmEIk1D2U@{(QMxcr0|ZZw>l$!%f4qsw_yql{uI zq>Z_Lo9-D{Dx*^*@K#y^rU`1!T&E~Xoa6?7gD9&dYhhC~SE&L$3NK2SHb3*mJ=3I3 zGMhG7X*LXyPuBFw5XIX*qPuu;h>PGm^L{TACuzHXNs;y?>gD4}({9OyF=O8Y8eWQQ z^jy%XA=(8$=s8-M|6J; zsta#74lBSm?wC%;Kt3hoomoc0HZ{v5Ui|@Th-u9PtR36em6|7cgJZWAo?~)b^frEu z*gIO;rZQ`nE&Ij`l5P#XxXs&vx^f?`LwAEkn2@2g_56Zy3qU%<<$7KxwnAQMCr!*>o8t+I^D_ zDb^v~<;9&TlVX~y$RDf$2)2~5TRxw2C)F}3e_oQ1?GAbhomOV?aoh}16K9f58%|&0 ztrq6t*+TpGi?7E!?szpRHkQ&R7PG3C?gtquzT+3dRKHu_{xEgd=cNn6*GDmA*|s{3 z4Qnw-dUOG-o4AEG7c13s>v@*$=YF)4S~G5cJq|u=nKLej(i8pKV=MQ2vx~u))bX)zNm^cPB#}+YD)_+ET&m^zNCw<0UJRN_bn-1&cv&7i{~f<-){$t$ z+6ZlZUn$sCyB2upXfHvzO0t(m<9*TBejTh=ERi|EQ~3G_sWr?&O3RMRBhtrH=@;hx zN`}F^_CMB=$3nLl94u9X1seUl;zexN&FvQ|pS$^vj7k0hcLw^0ZwUfRqy6Kk4&NHZ zE4n2Y(=2{#T@%;pFB>Bn^=eP@)iCXYe9|4w*0_l^d#iX(&(;B!y{h1|D^a}q+9T7D ze2rpc$Qh&IgN3o$om*rnk#y%tB&pRR9@yviaqPPo%qk)NiKR;Yd+z+!s~)q8pUIxH z6+)ZdD3-^+BWHkk@v}SnIA@xN9kA6DDN%==&jF zmUhFt`wkN|HJqfc>)Qx&ng?h{l1}v$87bT_wM)ZkcPtUut@JsP1BuU}3UrF_OLHWE z_wE2Vmtw;Y$m^Z(Edf8sA0_!-V~!b=j^eQYVygeYEpzv8(}23H6(XGpF&~Sd={2l| z4e7wtE8xh$Fc`FYpCtE=YOXK3EB{x4mQ^cNuhbcoU|Z{5q29f)ew<6C@J9ddi80Y+ zwe38G^mdIC;(V)I@ujg&21_V9U>JhBXJ$TLXENX572%S9-FfQjXGHg3&`4*68Gd~s zDMA>cezz=oV&2(}qv6`|BP}A2E=AHSuWWgN}doLt^nxk9$_sKyW5GL+#_Vz517*!w}-oX+lKsVI7Vhr!w zLm&qMKu8-@*AC77P~1D?v4+qQydeF;#pRY&3y7k@k_f$*sGj}6==!Xie|%iQnD_bk zAX5*u)y%ji8b*HW#1p3CMQiF0+`1-_A2QM)xl~b45j@*l%ASZ@s7dWr;zBXF8mb-d zcRqE(v_06-(k*4XYr*SC+$lmD3Rf>BywOf?y+QVYX9dbkj5%35*(j$7WJpH`t#om8 zI2g1Fr&~jVrelMx;siBYVOs3|rNHF9abj~~~1FC|EGa@sC*#NT#KV$~6=x*yb)6Z4Z9 zahfHry2Mq7JFYfdC;S>D(ph}TLSv`KphFt=!4z5CBlQWuZipXay8ypMo00)Uke}eR zT?W_G06y+=pGX`~4)qhyN}|8|EhC~RhhfX7vP*yd{g+X}n&yVp(i^CynyyONw?u*CETOvko3|IQs> z6hP#K?ROTWyeT@qp$U|(*Eg5|*zHj3o%EB+5e3gxDceseRlX4}71RNFiHXMCTJmVl4NFN7E>7m}%d^J;d zjA1Ap_8#522Ql&z&{7@a?ci(<_$&EHR(g=J!d!c9>ukQl+rg_E(zo5D9ZejJg49Lm#eOD5iR21eiew+3NI^Y( z0_-9ILs*XY!m=1qcjFCi4uT@P=&SzY5sY|{x-yp)k)_}EEJXK!WTJtLe;sJ)6jd`P z0ZrO`;1wafQ|tqjl#?C@;g+l1<5+_XIXBCMqAu7cVTw@+oTsUuAJ^qVD9jT`Bh=a4 zNONWX&K$YSuJgm%_xksoLE_D=#XB1MAe_+I(K-_@0oT~J4(Fv^+Onv*j)(EFW$}Sz zDfvWJZ8=6o$ap_s`??cjB}A{+K!koy%V5YL&fLxy*a&0Eilp zjCFi10$1OJz>V!*36imeZAm8uDD9Wjx9rx!<$bi$)fIX{D02&ELEhY`DyfIvhc)n? zf%+mP+Rg#%NUbui{xhn;godBzt&L2Z&*AeAhQnGy5jTx96W~=3=mobKHdq1hgm+oa z8q0h`it$N>^lI8^CP85NF7_+11GLGpnNDs#%5!JsY6W#vfYQ{*@Ih#Po!x1cJVV_N zTTung*=KU?w*qbq!Hm|EUC2@OsnXA4OBtb44zC6hGu{6o%4wKct(e|k%UFk;)ja;- z8NyeUr&mwso+(?q5q&t!$!vm6qRza5aQ{Tr>$X!v=_@0<~V`DoUlsitx|(^UB0_O!Qf=ETL^Me zC}OrJQ2I)FMXNIpXw7-&mkrmfDn$lbW0V35G}A6#f~N?pRvy*EbVJ3rBC95km4xi7 zr$K~`VBYqBaoQHZmQD5f;*yWb1;-%D>kqfyqKqBPQ?NBE*R(1Gcly}-fogNk!6uMG zQzu~ocJL8C{DUG*VvZ_bGR#iPHH-#aoeSY}eH7jN= z=GS?C7m*KQ@_JRXnA3c%NDz65nj<>keJ_?$4xBli`!>em^+g!4ed@RuTWX%y00pAh zPmQQFP}d;GP*Wef^&A)WV7M)u$ajRV!p(SRe8UrupOMF#k_iNi$I$grL#fw6EC8EP zM|^l=&?_e;ZEB=$l={KOp=h-a@&tEz7ZU(4c#zRqeXxA$y0bCi;?PMYL$kQU}iE>r0>AFi6Ws?d)saaR#lHD-8)EpIxIn(@cC z_ZbD~8I=QHNu9+NR1S*&b-~w4J|BZ!4XEw_zzo|{i&<+`rTTN1`1sovYS^JXDJvz} zqzi=SlWCaPOG0tqDr*-sQ}vXJd1L8n4I>$7N}NHuo(cH^b7DYI72i=1@q++olPq>? zlJEC#XHq&U%>$9y3jlySdc(QcLLDRaNL*vz`lAxyk@fM6ZMtG|xzbv01VO0{Nb>zF z?B1_3TFiSObeURH8KDvm`*>`uyN`$AASZRSLO_ZY&RO0%viY30(K(naSzMiaC- z7CSwBzu#lDLy`v7Mq619 zCuTCNXxAS^0Aqn7EI*)OK||K^t5#d3F&4eLG)FHH(ljtAg`#%&bP^d*tmV4X{>%JE z{)cwy|2D*MiF<@P0Q6rO(Ln)VkiS#rWCi~ZoDk5*0fZpeO*wCNRl0Od9(4pH-DSrC zQJ^MX``$opJrJtuxfPy(Enp`t53;L0l{K2D$aa0~+Uq2Zf+MJ@K{eqP?{Za_KKV>w zwzOetr)a-`zoFV3S74?lUrW5|t7?4!kPLrx^ff6c?D`%>bcnRQM!|`Pz;L$?1|xz! zpuNT7+k{ELH07fM02zg=?;40J5N<%*LRVPTG|(Ra=zPLpt0y@7#3iIaZDNzuF@+CB zE88oMKvVZy%~<%l3IPm1c`hcv^(}S+;K3N$PM>1cOz6Aa-VYe~O16^$g&}XLx$MxeJE&== zowx3`soKDN4Wmz*Ljnpnjh}pq5J&1ecFr;H)NU%;cU@vm z69py$i4OCOS)%=~8&B)NLz#gDhk0?b{KUyKP2}E^&kZapw9ATZTSK8pcf^|sKqo@Q z0h{=fXD%My)P@tcT!&7`<|({$R_IW`G=d!s#G;7?n(2G zH0C%{-4)H@r54$LLM5LfYB=#a%_aVeZWn|1YcTQC#!SRkGHfRM@ag6hLqZ2$heOe~ zXuoizfpU@d$oRXo4%93~5klOfuKFBt!iS_4=#Tm?#gZMW+88%?`%j|;FWUO>$Iz_= zs9`5>Y$CF{z9s@AHhKlcr3+0)yDIgL$bv3`qM|NL{PhCYx~P4tlI}_$(NGXQ zasOC|bmroUV&9Y**=uJ(qK?3Cy_>T??d0k5g+3*xIB(=5Pldw(VF#f5>n0YD0fRFa zr>_eh8PW`o$_iEgNzHFl9Ltd-!TU4Wi*5ckbWezeW~E6rF+F_T?kFzq)0Sh` zfmbRsM@=xb0W^N!n&&{5u$?SnqtWgs+@utba-UC7@;u;ij3ZNSwf)`+k?*}GAuPVI zt+<9awbxN{SMmSsMP`#R?`~)^YvXC=-BOUxJ)j$C|9o#=HR=pNB^pt^BN+tH+j>M^ zg$C@Ih_9I1)xi{UM{o?!qb_X!wN~#f7(n>$eCUpzfUXfPtD6S&9C{x1lblE$5HKIr zdgYVQ*Yl|Fk?S;><3f4+h-6e0?}m$~pKR-k0Km_WI3dgJ3EKfkx)m(c%jgt8_Y8gq z=!q|Z?2?O0E)|Sb+CI)Zr!MO*domc*yyWS78b5%3^ZS_Lu1tAqNI}$KS)6UA6cIQJ z;L4;FvUj%rw$P$-sE(}(Io;wRekAZ=MU1owYJ+^-FjJ^irLNxSP=9!bV$uFp9f?96 zsYx^1ja#MH+xQ zJ}>B$?sIT}n_(oIwBd$bC`~WczsbZ3m;MCgSc2QfF1Hcp4<_Nosxcj?CI5`an7$@8a(SEbs+OBX+MnRYvTz8iw+P(-ADZh2%DDRHfh%GXWA zaNOpF=qVhNpJ~NX3^KATj=nU>H2N(Yw_^3g?F9=4n z^@2Rc$iF59XBgZ3YR;-tHaF%OI{()SSvX7k0G!5*dPY>MY-XmZfuFOn_UZVQ8Q7rL z+rlW@YW|p+%DU{p2nz!*whXEd+(&L^h=tX^=4TAIHc-8DXaDv4&FphmuVND!2WQ4M z2X{O&%U^Bu%=7mLGkG0&!^FGMamu|DUfHd6W+*_rxPn}%+&#b$yg!e;R<2K_#%Sic>P`g!^Yg$!W3(L8>*_p! zOdrrUltkH})-TILRkU}RR|XHOcmZMk_^;awbWx5pb0yLy33g{PUakF3NI%qmFJxpl zsu?}Tks{@`=M7A7@ToMvY3Bj2x$s)abPUn@#lGf8n<5kLz9XgH@Yd|8*&^xh<(@jw zzF+|LHD@K2uyYt!GcrO4FH&N^!c23plTKp~OB-8cF5mwWvr_5(yDARk;p`zh;7(*_ zs@GUG1Q=}2^yf6X|M0F!(GcL;u=+~@JrgzrdaXOdRZRQ18wYS#A8BX1TAJD|cb(_2 z$dnA8YZ_jhUkSraILD#jfEQ_E&jb@bRNf7QF%vNL-{AAxyR)BogC+sm)b2WoAY5wD zw=cM8HH}<7pRPO%+wj=Dr}%Ew&EiQVMfNh(JFtXL+X7CKd)d8#Gq3E^qaz}4w^Ki} zPCAqAIGa&(d@wH=54wx&p0ud?bqUQK!^ztV6Xt1>B;!PyFUqRD#M3jrK2pF&Abhpr zv}8xp*TM~+kpGTrp=_n64n9f;%8L3(GBOMEDvB`};i4+GCxr4yMRPMSwOJ$A+%$P$ z&wMP`2HtZiH$-Kt)oIJg!DOSP#NffqrNsN#B{qKTE$}cV$KP;n$B1HE@r3XF5iFRC z-c7(Eu#^X?zl7wMIPR00BPVKs{k(q+KHrIkYgyU2v_VCqWjI*1iWl@gy6 zC3V7O{;5(hEU(%;LiC%7kxO3JxcUqDk1371og!5&EN0^pZiNAKJM`(e=TUQSHyhrp z)l8frz+)QJ?XmXQ;A;>vYRp@bitSX)}PC z>ctCj)44way(BPYge@>Vf&~8XF8#_WcHatH-)y&C;poMk0_ znx{N6Oc@+oXAf*xJT70|RNI+kK|c;eF#`!d!FT9v$u}A8^_n&oHkGr_!l#77T!ofn zCv><;80jcX<5i%KOZt49XT!ugs9x`y%u$OQ%uYp`mM=?($~G?fp}o6X%#Lx|+>?(A zm(!shCN(TS7tfrZ8cV(Q`v)X_^u_>WP_B1A6O zp=?iu`{30|%|W>VH56H2g8$b9rvZ= zUlQxkRr0QDQxm+e9>3HtekgF>RB6*M?%UM#*PRXshAeKVI=Qvrst8{QZC$8MvHv(n^}DI*$;LTV8D%#mq3;zZJe6E zV5p_po&A=gxu^FkKULLT8#)d+03P_yS8pT~eEDLqYkRLdjp|mz`^$}Ne#Ryw8h`9AZP?OA0fKphLBM9$rUV%0TPUWz)ByWgPC?!Yn031SZ^#yQb_98s~0Rjjl6Qbu&wo1fNb_a_%J) zT5&h4+|G~(GxnvkLf~_qMTgRJ4AyM$i-C<{!s|&1fjGRwhl?yLCw?H%e`&u`>ykDPDA`cW$H4F)pj+sbSvK1kAB!3XPc(ro;*9#<@wO4 znq0f?CsSu3vAxaO^TEvvL#N~)S+g0nm5i7WcTOFP>>}^~_&J*U1#QGFO}g!B>2=YV zPRcg;6xwSiBADQx^3xTd7-hZO(fwX4AZ^SEk5y7@aS+>;!L7Pa_BWEU5 zPRu*NbIKPY-LNgBuiL*m<|Oqsc=CgLWCpYYCw(z{ZEP5#E4N{nRNk|lV<5HCU>_bCm66G)v6iyJq-#En2q@s6)W41F5(;eQ8>+Dw1F#H)n{_SauWJn4 z!#R^N`%ry>;d#C(iwizDHbbGy>uPp6weHx;&ZDOHHrFQkN`ZEuuut^-KB=%XtP7W^ z%L_%>yV4H}VVxR1AnV!w4;L*hVRktAg<)Mx>VTxu&bR)ZZ%SSjk?GGEvS14+H~vAt?c z<5A9S_o-HqMnhR2`D5{jl+DsIa}W6QhNc?6Q7^foq8D-Q(6Y-bHU0XAe@Bwx=A>sy zx-7dCOU&*I2h+tZzxMlehGxWH*YX@<8_Ev&FBp{(rLz2o2${*qJ~uE4*O?_HLkuji z1pk)qG7plrypJvJuKnc%@QhBV{XguzcRZWn`}a*1RZ3f0t*u(CHEOSzRkderLhY>x zwUwf(_TJRqio^_BZOzy_NY#iHsg)qaleXXA_jx_9`@iSU`@a3fE0J8+d0p3e9_Mi! zpZ5owcm!Q?Cfrei$6ZqerFgVDnB^Fg_cG%k(^1V1at0?%CHi$2jjCc*!EZ1duK7dw z4$e=3*hjNTqV*Yc)pp>(-uX}?SeG@d-XW`aw;+-qj?G~`2E2+`C_weGq?4RojF~8X zugRZYW>MZZ0Tkz52)O|ox(l)6fJ|9x>Bw%5O#{4%6oI^7LO(9CRiFtie-b?i7T~5p z)xJEk6)T@+GkXI{>e)Gq7O)Ef+Sz0~T4ATB@p5=|V1e?@E%^&%;C2&L}h$T~Im-_!yVgRqK2zm zkRN>dj&VlpDS2s?zL%-kTV;Ia zOB|e7M?>V(vu5!e6jnT|J~zf0D94|&PMBIu$$9@U0d_W6w8%9um;zsLSNO64;U> zlE2;VEa?4X)&hab#wyKnk`IM$#mgDTO`Qd$A41Tj?^fnNhd$H6{ZP06%8xs3WVqrI z6&9#uwbL{@H9sHxvjJp;?OG9k*72Bb3a3fQyk{4kb=Jpl3C~M63xj%Opam!ybyx~C`%#oHPcuWJ zRA%Tet#{&O;44?%#n(ppCR-pQiAGWH>hV=iaPE#&Nh8fOuOgBb0(e0&bX)}3+NYH? zn5BOkAnV%BpXRV!9F#Q$bo91--UN_2qMsksJfrmNA+Fu4wGS^#JgpDR9})Xnjg_!?xOJF#+eO{^P=zuzb70mfA$2xsq<*l7 z3ve9NqHFe)>_XZf$jMBsQKHs`K$GJH>L9F~Dv)%8m4=Te>1H&dXoTaL?}hCam4KGcc-sG4I|@9^csV$uhdOKOQ7r*;4+H1lWVe|?7SQHv z6scdYhahO%xYFuyK0zujKTK5}OifFnzDZ1!k}g(_WK)ikNJycnei>0~z8qNg;1RBg z;!3bKHd@1}oA-<=R*>)TOa0EzuemXg5$D~4Is6;`#oZ^h>NveQOgx^{s@Z%4XZJJ= zKfNScKSOWZ?L?6;2xFGr`c;(l;VSNF?@jX~`j;;K%NyfG@Mhat1Kd!zsLx&j>U0v2 zQ9}|w#ZF|{6s3I%JUxz~ zT9WHrFML{lViVB5hr5*b&DKa1V273Mq|ww^x32vHbG4G73PEYmtQqzh#r$O;Luh5Z~dkaNwQtth4kaZli=xFS6Iz1 z$srE+IK@rR$nz)U)aP?w^4V78n(O8Yt=0Uc-0wBK)M_6UE8mdjZWyfli4Ae;_Ra>C zNp$BEwtIwat=IWV1B=mQX+Jo4GJ2R`21M?>9v%Vnzt2y>7P!PJRC-Z$PfwroYX*IX zU-ZR}MSZHT^Lkc?=4(57m7MOzaIYnb8bo z7w!EZW^mpH2(1HN3e(`8!p_z5I=e@S?JXs`o8d}y6V&g*1Ex%NinM+hlQ(S?P6BcV z=PzkRe`wI~Au&{Z?xW?q{!xw+&!u9lC*Xp|`BVr>m&BLyb z!89xl;iLsR3MhJC^v6wT=7b~~F$`XRg%$a|B%5^wt92IiI;%l2h^2;2pv1v?0rBv# zEeRve11DLp&O?GPe>e?{KA6R)TuYsVfAE_|zRgBcY&Qw7lSeEF&7-c{*N&$5Sf^T4 zTOmATcUN5JkFNWW{wn%XbeLD7QD(smkRM5>&OAzZ9njr~-`nhF1-OP12N6mcKe-~b zjL^3Nctcf;(HXn8w2fD3(hmLeD?>RV4(_~LXIppm{^O|!A*7TDImHR3quYADEO19j z+;#8IDMz6{J@g^~!nSpx>ksaqziKiMYEU3E%IHw+kcs+0^kB=RcRkmVndL0@r5ZXx zYy0~Ybh!Sb6RD~a^@51D0x`H>KNZ&#HGCaK{SVj@2$BKSTCG-Ivjx;(0Q~kK5;boT9F3r z(0!5REbHByO%bZ7q*{GSE*W_ma_DWaOdz6M8EGto0eFwRre!a10V6wF{qNqwj9DATx?rrwRP{ zse?X}jy}Pqol1l9)^z*A%o8QU(WFoPO7u;FmV7Ry3(uv#1vDCxJ+Dz9J+dQI%i5y( zHY2$8OD49-+$FjfAC1lxcU|2Qkla?cTV$b${LbQ@4l)YV_8>tksJ}9`EybAZPGyY7 zIkD>|a{3c2U|x4mnL`bN_l-tBe}*VPHh~qiK#2M}89)HWHz0tRp-21%h6;yfiSj)) zANjtd&+V&EE+6_zt^gqzUz52^H}WN1|65m=zzyNw?+B1zP6FSV{7q6z9QZ~jIasTL z@pf`nFz>Fs04Otd?}jzaKqEDqQLQ1l*9fRqBi#eT(jx^sIv-xWnY)*ULaM)uSZ-$F zRN(trILj1-j6TKLGF9Xi=*!=WDOX9yHX%Y-C2&olO_yS+CJr_*rn~+K+Q_pIN~@6E z>>!&gs>#qMu`GG+=k-$204hUhLPlG-2slAN6}SHl45%671B+KINsm)3`b_Q&?P-?E z(bEDly~a^E%0xnTE%>!(Y1^-Hx!AA)J@eZF*Y0<};P2l!{u(t%dZR5T`@4<|@Q;Jk zi$&OV^+moXtuE=pS{|G&zsB{N+u2+DjQ{Rt&yVQTMfp2t3=4;$)wg#x-kLss(f;#0 zYR0o876dO#2NCRvYm{m#*Rvv?prvRW^}|& z@VT~f?&WZK;L_E=%lXXr~s z&luhB`TJ@2$z1X}znm7W-^NAXy#R2{_%?;SpL9SrUs7{Mh#d#3q4i0-yNTu>n?eC@ z_p<7~h&;^cQK6K4Y$BnLc7W&ZYQcej9P<|W>1EouQJ@G))r_Gwnz^^n9?%J~zn}KG zne51UQ`PB)&@=Lfd-jo!_8>nTjPt3zAw%Ech8v5*FUZ5`Wh4Qifb1XIMnmvK@3_*C z46fN#HiABI2WDav1Jbu}Csn=ppyJRHO#7!2m=9tZ3%{aYD87kLRU1iU?)$i$Os1V5cTW)gbG*CoRqj*Yc{Woo#)!tLZ> zc`*HuF+=UA!taLaX(82O*U$k=dt`fXKnTuN1|u*O{IU@l5u8ZqrcDgi$(1R*CijNA z7Djt>?W)+$>~a1#!c}dEoO-M76w=-4aGigV&m@*h6?>o$mk+j|@Aa5E+_L&c#ie-{ z$Lb8Fv7L-hC0XWXuh9&Ss%eb)n5)G$R@!(PL{UW3GvqfYQcgeD_{yZ<^?R)|{HyLz zy};BtzM&#B0ZGvoU(OMJ2hz2GK(j9a@4`l>4=3Q04{NxzAwE_=&%iP>`&M0EU?p95}&c;;~YNp6SM<+SQyru zZAb5VKnq+yribXG&Ysh=F7ijPX1bHJviH{e7~7EE*5bBRyxE}=7tr-gn5I8F(0Ey* zT4jzj;C}fJ*4r~4+iLee&1BWBi<}H73-x;dqD5U8Gmlv~eorj!ye%oGZ(ra{;;|HYNTi8I>NN^YbtYMMP~}w z$((=l3r<=1X>HRc@GL{J9D#khxL5QU*JJIyB>GV3l|Y(K_{l4>{?#W$JTREflM()6|odxN@T{7p2_YK*|zZOHvTZw7TA`&0d$b-{j)6H zF1X~TA@=sm0^J@5N zU{2mSPE+bB_@tZu1UxE|C6+sI##phTZ@L!No?Wn@y@8H#ftOtN{6x?`9#=AsrjKFu zBxER=&8M;p_3D8a{>}l5n)g@)M@g|EhpSf=2z!I6A`^lPP|_wHI@1h^VhFsp+{l0! z9j2fJ-7JglFT*ax9>_A6Ve-E7Ao7lUXVD7GGIocO7Hl}mn8)&C%w?~w{4s0DraZE^!1EXaHPgnI{SkPi)YIBZlxpE4R+d$>w6`I#{ONm zwLmCRySpQW-L{cX_k6aP-)>~t$Yt92`nk*z8KCNS3n=QoLu))zz5AjXSlyY|OaI07 z9sVqP=O$os{X!lbK#e9Y$0yfin1o6SgVi`e3YqDm01e%X4Bs#jbLMB!m=}W3$=d*t z;lzHDXp|en%FjAKnheG&>W9P1z0|f-f$WBS^uanSQjQInFH`Jvn4LG&PmV4cZ%BFH z85`o&;&z^WzAv3gbv+R^Gfh4)lSMy`R2_U zZK!5v8Ww1YO0e8&mv6sxgzU2K#N3=^^xVuBf8@JqMS~#Nvsg=G-(hn^&0j)cyDR-6 zJ~wOJCwB&SqphK^8Y#1Y`-ZjYkIMYCfBOog&9|4EFT@CHyxs2yl!?%Cni1=t;Eg?T zu@oG&D8$Q9;Mn2T&rcn_S(YU)$fasVYvxu=0%BP{NJ7W-7{?fo-X{)R&!`a)w(k$8 zFk4g>Mn!yX?G}sv>>~1x<)LjYK?Mt>arjW)(NRRRnFqW)$`IZmQpK)$`5{JO>|7NM zGu5LC2ESY-6m|tNN4zBtv()K>s;TuKu!#VD>Ej!mrQTsC1ff44blXF)0{1Grg?3iR zW-{>i$PX|Ay93rAgkD#PHh-fK6hZ4e*F=cTA1+g7ENXwHW~#+{Xysl!`r598=E8;b zPc!yEdLlo9#>rM4t$Z>ZC5Pgx^Uk=wkf+3es^sK`6&#wac$;zqzO;dUAY&purkkF82&|ZE7b|t-Z^z2fGLF z3-%3PtX@xn*#b#hx+}2lrhczbG#DhjWP~@0Ab@Lswi2na2dt@$h|(iaebs9O3N|uC zK#7Grwwpjj6p0besC&5g`Sr-tw8qa`)Qc6}#-*V=8b=Eg~{zOIO(g2f$ z8FX`vuM!CNr1y*Ho^Mt0ZM+^Eget{g_`a1d=b`K(M^pk~=T9dPhYMzW&@n z!gF$GYALWslE6qQTdG9^^XMCyl1a+t*ZuoJs`9(fZ6U1RB;ig7r=9tYfX>@9?3AXhsYf?HqY=_noJX_8LKI% zx>{y*PL3k91#F}B>-8Vh(?C2lAs~OKbA+QlbBB0>B_qX1nuWsju8Zv6UPb7rxu1GX zY#5yREF_`J*`j%4)+FTcgdpp!fj2sA!2P?vNofJQO%7`a{xnUFGwnVb0<3&AL#dRb z0q<7{G%5%4_$gd7LDE~AvE*v#~&eGhG`}avkb8Q+!I*-*2MAgZ0BiPNhSD z*|UVHNb@vk5Q|hF?7GLcdXDSldKDC3#_u7bknp(-*Hxc;yqWFbB6$pQ@b@w=|9}JK zUC6jyNa9lc@VRb!J!o+U%kY-^%RmlPlc3p*6lExNpyUNQ<>3Cx+2T-V0YO{*Y6E5& z^+ax#&<*g=B7Nr`L2?C3ZWh?wP}kbdD0ok9n$_C%`;nP1@I{_LmkAVdtUQie7u=-u zDzhI&; z1!IgJ^~ras|PXZOgReoB0v-!{kE{Xh2{o^P;ltjCJ#c=poXnJhY~5xRG`L5mOU_y zcGwn4k1Mj;v_iYpJO#I$Su469|MH^S#=qh$?Tq%i$R%{mz9n=5N~&MlNQsu7TBX+Y z=WhRs2*{-;Vk_8Pk#4s-W9|7O~H6;-Q z*>nF|R)~mh{{N@){qNLJUP%Q0uOvBM(TkvC%(y#)neQ-#Y5#>q|JAUK-MIdQ(7k&n zgnZ~N`8bC7axtoSBLE3+Q6s1N!_5@_!ZC>&pH^M3;`ElJg|d8tauOTLxZMyX6z_pm zDM&>nX0DHVwSU?frmRLT4nL#+G!GJu9se)Q=Adv6l~UAFx$VRsGW|cc{gDr|P^D9o zxcI=Ym>B@=Y5Onj@0U0$kIxIkN95_K)Ejq{V9kr0 z4OL$HSx*pPEqf|)+K7iUk?)3cG@~_A(&M#&VnED+tH|u90m0G#K<_CswO!hBEa0*_ zT&{?Z!)KWl{jUnU*wlC>zyXc>Zy9evALg`?Xc3a*Br*OYLn

N{JVp7wyk%=XLIZ!tey*=Z)dk5 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

>+CNIzWj=%kC&7^YYw*DJ!qVEUG zh=Eee#?Oe?jdL8#&xCw*azyNKJcYs0S6WW%BF_Cimpy`;YiRRnp>Du8-&?TDgfw4K zskEs`f^knA=5ok~JPq3&7W4`8z}e-O^m;Y*eqsan|3vLxHQ&ncb#r=C&3UiVVrF}v zetcy?Va=D~R=J{_g|GH?oje{+J&%Yj`gqQu(zD^{QF7~_!#f8PWx?#rL#9nf8bf>^KCM5%vS-Q;nqpo> zQxMj^7*g(&?fIS=bg}2i6YHut7NXx+m){R~*8#nsf^WEC_`E-qoVXU_389rBf4hu$ z*-Sp`Z|g3Q?pjmWu;e5KPGfssYxBvz&5*xnS9Bt_MGAT(k7Bfw7}W#?f7i*gb#Us4 zQ(!meuREDC&xotEx3#Q9qMVKoHpn_-tzXot3r`!=Z&b+-U%1Wpi#s^<^O16?Cd|v^ zc6rT{!wi+XlRkTocD?Y+1&aj-yB7&w;qpgU$Vacsf8>|@#y(_!kn>F#kHz1=!s58> zPSh8!K7E7ENpk)Zr|R% zL{&X5iFPH1`IFrQ(Z3^)BG(X}y-SUcN4_-U?(jDVF8dB+oCzF{zx>4m=Czl7Zk^O- zxRFuJ93>m&q_WG%h2ptb)!9(CR%3#ilx3=&v|?TT2w4q@yq9-yR@2Q+Z& zCF^bpD`}Iu6fT$21Z=vTd6rUj!S-N1Zcd?{X2XCGw(Vh-?MWf-XFgFfxZ;V$ev$3L z$-2#M8x-_Hx<{+MDBAa8TB*WH&URq&LDKl&K|@G^0%11YY77>OTkeBu-a(Dixun7c zT0dkuI6a#VspmpIp#>~nCXe`8w>Y<75w;>XgZ7$3m41X8}KqyvbMqoyr`+ueMXhBW>_WyW{>q4uu(vXg=B zi<4kQo$l7fQtzqJ z1{1q>J;+!;bIg7sw$5()Vc67=2a_uJE2%Sn@X^C?lOys1(&C7mzm_-ESwZgSV$w!0^07MI0U9@OLEeQQJBe{YhA!AgdHO82ecu&?li-+vhz zvEnvy2ujKcD76;zYFoEI4gADa^DOKO+9lxDaQmluvUa?7y%H1u->qTma6zoV4@F-p7PoOV4gZjZosw}2u9!n_o0MAi z@8%b|eZ&KDa!HxlKM`C(aiydJs4~pMbZ*3c*{o+&OKTQ@IZTFqa4T(y-7m0C6OVIg zS(*jUa)I$5*#&;6HJ$>G5ege5I4l5o_#Cq&PBSG80*D`Sr32B;;Nm6@m3%mr}bZH4Ayf--8h8}5S+`=V0+4jGZ;9cQpe{5_P1}hV4a&WRZOijc> z6nF<6(Q!u#rZ2t?q7+YKO7ZsIg%I^`H+W*Nfs?2`QcXo%vyc2)%!<-rz*c@B-j+#;x8IHWP;V1#zA9KP^Hb_51 zwLaDX^Rn1)3^VS3n&qp!mwA;HB>KA4y8q;%ABJ^DSN=qmvX6dV4=1_jZI@!_V6VCk zVIH>VCgo!&J*MVX_0bs!!y6Nh-Ak)}_LlKR`7Q@?-5k}qLbAk6g*oeBf`X4`hNI1b z+P;$5tt>;aHu17jVH>iThy6_TQr?VD{LABGTjS!0fpH^Ade&Y_X+gB&-D`-|+i&lA z7YZgghProZ=u7qOc?57*#H2Awgtn2=&gviX_k{JXFSf^z)y4xZj0N;) zAW)$nPX6K1^y%s1I{|!l(`Qrf<9GV?OGJ<8L4PL2Cvy%0AwhGvi$@B}*~4}5k=we1 zJ|RIXQOLZOJd`SOHv%D#k!?p+I0%t}^6Ojdg*1>txUV+m8FWOb$Q}WRmuja)5J=l)-&_SsQe8 zj=W+Jr=xxR)YMa)#XPPm*>uD|O62CE?MMVp!$NO+w_bW96XQu5`#Q5R>C@TI#}4W- zu?~CVL$6L)Xz78LSDr322I-JCtqC@) z+CX~IfldDsKnwPC3I{?TFhGL$khxX0L(3~oz5XE4o4>75o$@y(5gg93+6p~sXs+JP z%xu`BW3ovobizY%sm2#hp&op0i}g88d(x!%W%+^rpuaDYZD=GL;(4Utn%96uTbY|ZM2Hv1K-b9uzCz&*frzD!4S!v%qr97 zq%hQu$j`}sPC=Sk6V5(4;RB5$S_U`doq^#2wge}#Xkq&>z9y#~_M&xBVuzQJpd__O zjX90(SA~;g-Y-e%IlBeUhE^`jvskxVx)*In5DM{?W`{?UMWNp(lG!xkVB|NEv0$sHNI)@M9XBoc$BC3_#os`F#RhlC+W6?@PSp=<~W> zT^>J3gp2c*wL-3&7l<)Cj`RDnV;>rM`vlt0Y3kyZ{OfL$}MJ`oGnl1T813vqZ zr(ClWW9$gm)JI0_I|`w`d(4-X_3baZDR`?+%SV55p`CMZj@7vT?NiIl2pS%pEpsye zPV0AfW!wQZHs~6=#P0y@k#OHd^md3BwCZTXk3Hxu*V%yNuRM!^8uH+?u;B+%^K|J- zZ0P;c}C*K^)WOnUBzM&^g6CLBEqR@lV3I=>1T;u!Xrk1n13i~g+ z1@ob)CC^Q9{)*uIu>D_7SB741O3PJAy|G+&{wr@mEkGdRj zo%073Do45?Ada@i1ska)OL7{|OKWhcbAy?jU!&e^uSB&3w=GCE9@_k#%OPODjMJWO zw~bhz^W)%S-2~n6r7fYS$u)(Fzz-yVFF}iG8d{BrLt(Qfsoa{EF1~ z=HG9T$FbxgGuA?LdBf-KLP@6R{`03H(|5*Rmwpd>*cV}Cknn2ghRnWS#$Is*hizg< zvh#qZYt9tum1Jm231?l+>jXPVrDml@pOdL#pY5*5q5vk8u-?p8a8!24Y?)$DpPTP@ zlw$d+w4T|UI{M0d9@C%N5y(dHN_Vy7B4K&*&yKcPV50b?!5@BmSt&0iI{^!#Lf?F! z#9lEvJ2vc|N9*zlzfREHST^yK8X~+|pT$y)9^H8)J;odouG}s?Rh<$5&#Bx6Pij8p z>;EV|{lqi%#BI6nerj*_*Pj6EliznUc4yk^mTh-^wA5S#NUZD+>kMr2Lhh)N7z@2j z6c(%ELPOQXg-Bn#xcbCi)bj3{L6)MEQROi?Ex4iAUIQZ53M+z9I_^sV`Sn;!@AWd! z7PI11KD1cs{FoVbMkL00PON1(Lsa(^1Q$7rQ+V@GJW{Etk?Q-585>a=-Bp-4m00`p5vI@V3WCDL8`oaYxZTs8w5#pqz~)(;0hO>5Mt_)q?M-L7MFovI$vU$zpO0dmG<{B)_g|Jc$j`=>})#R`Zn;`ws6 zcizWTtqq$TddGJkDT1DG>~uWlH`xBc$|>&&-W_+Mo2MFlOSpvBuo*P6-L!9|H*tNw zQ=hN=S<6}!_ePkv)S)LIFdoRxt{JL7&Wk4WG^bK;bP90T2madn&(J_Je^LLd`ilsh!p(KS(XLDvEOzijK;$dulqOyqLG63? zJAitntgrL^DfZfqBr(CG5S z&W8U)4{B68)n6tay&mN0bsF4$#6E)x$j$~j1g8|)1+}#ghx#6TH9MU%RnJGg>zJ=U`p~q5I1e zE<8a&^VQ~4AC^mWLi>?{IR)l%942fznaxk(M5z-Bwk(h7s*Eftb*f!ve8h&ZMQ!c- ztg6cXp>6v^pXSdu<&A63elcfERhmz^2R?~Q|DrUEs#lM#Q^iD_8S7G_ z;l00)2XHGy94(mQ^&V@y`Fq^(g-_7UZ zvkH1u=q&hPqODUtV2;PC<20;ZdyjagnCZiGb=KmRR>+#%$NGVb4-IV1h+hu zv&$Q`LJawl8Hb1)V2&G*Q{Aq0+?JoNBSaoXE5`(I(7867o4O(5MDixJs(0RrXc7#}U1F8(kxWzVw>;1mpCo@7HrsWsS4d8p)V{t?G zn?YXF@F^OdmXM_P{Bq3+U$0R@T5Yjc0cxPd&!ve|K|gQFrj*>Gi2F{+?%0)9(;m1e zO^j@8j`qA^t*wTD%|JFQV#V2qC zS%%jucZt7;tMz0LTpZTPqZ_W}bv;?}Qq#WJmQ$!3L6v8Km;9y@N^q`x_XO@4{8r<0 z{W>L7W@r=Nn$))!5+>dz=Tq73zn^vvoHIZ7OBEQ z(X?)}J$+R+l6LHfXWcV`e^wL&E-%dr*@znYyL!VD+H>ctrV8T&)+>+F>%+4hhIY0k z4-LL*&a;u%9F&UsYfZbP?_p}Kd}M(iGS-~hur!eoo|rekNGIku$cMnIH$i*OE7bD# zfK1)K)NI{8s`D}AwhcW6gZX68p*-w^mR8DVoy-#H91Iu45FYvUWnJ7i8B9=$Fn1EDdgiG(Nw0YG>8=8}y;}5EI^6dpDPE0+>i?!0GY_9t)vo5O-PzGOfN8exTx?g7jiSanf9|oTpOX%Uqw%Ef(gB~YqV^3h&N<=nrhuB0Vhj5#LMgM1&KdFYrBCxv zlStscWZ3nhJjW4zKrQ<4|tKAf6X=`5N|a{S_BRfLg{c z`*qK8Z&7c%=ZG&ZI+b-x_sPILJmR#rG06_CryXK>o}WAhRi#W9#P1ibo5>iFlio|2 zXKHh*rgktWiD1j2$qG*ixkqC?)$&@8XC*~yUbyN|aXHVKi~;!2^gmlx)I(e>QSawz zKS{=owm>WQfTi+u4ubj70d)8xz3Mm#R%|-Ea5TA&BV|9zF zKgscMh3N<8joM>j7(_cQ`uTYA^_ z@_q>A4V~N$9{SMKt_Lk_ zzBRF(W1QKiyYxO_c&J98!(^Yebe|8S{7%L@+d@o2nGaaa2a(_9*Xa42DhSuG(R(6e zuw;4*IQot5!r=v~2gQ#~#)!+*ud>$&AIy2Z@A*T6?(NdwT29aQn!!UW0o{tgf+9Ji zrH9YlnEMUxipXVS!#KB#T7o*6$#N2tpCnWJ1)~!9^AJ0hr@WU^zq}a16%3|8&P|at zoAV;qXvu-Q)Yp93g>bLeLWvSh<$#BFNMpw zKTMmGTRu#Hey0rB7+&M#ZX%I8oh|_?W5hKYukG`#U(Y>jm+A~&c`^5}swVMysAg_> zO>Hxu_NZcP-3c3E|E6`8Fnp&rc`!=H?@60oVU4^s=9w=F=2`wtN92-mh1hjRpF%{A z9hEt-wUs__p&(;S_I4=hvd6tUcVr(_<@p3%s_G8pa-t8$Y;E-_Y;($r=Y3#B92d04L|jA~}8cFU~fQ8FTJFhi`6 zCUfeB?iCYO-u_75JTvFE(*x##(;rr95mPe&g^t1zZjjd~X{I?c)mo)2O~90-l&%(rZn1mUEIl~~%^OO{Lt4Ud_MWzi!?sC6C8W5^D&gw7k}jSv z8hPZZ(gx_etwxwkeFV`Ga2=LayqJnX+qvW{I`_?UrW@z=o~B-f+DwYHaTvS+a%MFJ zoc>v)=BK~KCCfhWo#?FJp81XoAWQe${L9tUK&oD0ZLIzt?*L|F9~6~*Dwa{aHWr zH}BJu_;2G_wqQD=oOA~Ln;Gxi%({!3D+|vfom)jRvP)t;t?!>$ZtH_lzj685r5;mmp9uvO%$fWm85Oj- zs;cw)hW3>=XfHg`jNW?I$3HpqDRPAjmXIi@+{zH*Jq(`fL)YFl_&z?cLo1odXS5P- z`U*ToXGNYZV9DTn%Xv%U0WU9e8>8~NVEx7dS>3ErY2~oAhJFebpkTwBhty<>zbutv zaFMWZ{g>s@sXtJndxZXzXeFIeqJMnU_oD>Hgu@F6&V;xAx({Z!->v!S{iYVc{$T-t zItJdYiRqqG$pn8s8j;yNu3x`ss=pwZdPG+p{EMn=-D^Ox{eodvESBPM(}=87{y5p= zd1~d4`u6?^mt*)GF~BZnRM#3xv8vUM+_fNNe!&>ILTHnQ8^1$6YUq zEL@)z2FfNKP@G-_o&mY_0mp8TVxBqBoZuqZ&h z&H&BDKJbx6Q9;s^nGfKI{akOs8~s~R+vvkth*zy6qb9sF6mfBLxP7W|27hP3hK z!ZXuCrScL7-7AW8cH-*GB9Qjz-2k1T`#}|p^FJ{wPi#ejEl0-i(2)A73`L9fzyr~` zKs?RN=^UeVlTY-V_W{IdX>M{{;S>iIg){9eXl(dHRZbKboJ(~KVfZ03dg%j_4 zcK&SNJt3KFJ>nKVl(X#7KGlvyM6YJ$w~sWKUTA)ykrRI^CUnoDyfw6P>Vf%Uamj3D zTSG$oOUldKwjYrJ%HzfAJD3WE4@XqSb!I)1hNp7{`vjZYuub!YA^p!YQu&&#L?7_W zn}c;Ln=A^~ZV6;O(_v{OR!;hwmx3g|DRoJoPaaJY(Uy;17CBGDGI*ImqNM}=oxjx+ zX-AhIC$Khw9|7iku@SwP?eS8FYvz`ZOa^6K8l`wDVj9}w%cTb|PJc2lUlX@|4!I@nj8-K*f(;y?QZN%*yC9rf!2w9-P* z`^|l4a!k{^%Dh#XX#qo{#ib48VdaJoJXhu;7iS}VW^}nA`4tv5XHCVDL|^eZGy zuF$Y|dqnw;8<*An`ZND3y~7PD$)AYHx`uWMZ>)1K#Oe1J&bsZU5-sh5?O;;%SE_n( zD{wYt=#-qrV~|=aO}BTy>&z70HZ&&N8uI-|_(F@Jz$CThNt&(%QO{ySqsckUhwh=T zL$t6DcIDWH{pH}g?i_$OL%&eRFr)v?YLkgY&YRht zlx^)7cPCup+pR%H2@m~-@bXLB($+ZcWdD-b?{*guMMr^`?N^UMr9^$jyadoN?dIgE zO@!>#>%NuqYkK~fw5Iq4^Lt1>Z%*%V!)1l%%DFk`8a#2rH%EmP_itw&TmXQD z;cl^(q;Zo^eZP?c-^zo(#3kF^{`}?qizb^VM#k4U#81%F%`S_Sv!-Q4(JSsKnzH%f z@_u~j1{+pAX0Aa`0{T-^xa3nk^1NHAU)-!rIhG5r>~3V=qLeKn9R6s8s&Mj8@}g39 z-%9xRNGDGo*FOfJ5!0Z8n1|&=BQ2#X60L3#S@C*XSAWwxv$HmYuCMhj0sY-w+Yj+uc$+fNN;yacc+1 z=phL=tXqHax^Su(rk$a0Sc7--7h0|KbM$IFQhIWA_X-3m(^~;E@1%tjb&+!RR{2xV z-(izZjn>Csa5I|ryn${fbFlgmPMhiZlca;m6*3W1V}cY79t$z-%Nd!2H6mq|KebN4 zdSM(d+ci(IMVS}#|10h8{b3g3ic(mID*lD)u~*T4qDm~=rQ9B`_LZD7+JC_oX@?z>{y>T$e?FJ)^JFN8v{TOUS* zks%vj4_lg)b=q#Q+0nNVEyiHGQ^LnKS7ABhbe_l}bnf?1`v%cZHDtQ@mg%E+%c8!& z5SSXlu5GD-oP~YypCZ5ypdNh@1m`X?+;Lsf!%ZX+v>C;bj{it8Z!6@7B-C!*@T>=bk-Z!)lv%dTyFYLiABK-JrRA_FQA6X2;(3^Me4E63^82rg$^mUU z@_BweF-_s-5D8`L-X^BdMNHb4{b}D7dvCiUWpve%?ApFDdF3N+P-&6E9rCDO^(1rj zf_S+Vi@^b?A&-?<)0O3@5-pvvAZ1nDgXe1tFx%;at0Ms-D+rSk2ekF;97ky>ZemNW&Xa%7ofI>DB`cJuX%}Rr?)t!{vpuZo2uF|*{|ly2~M#wOLtn=ml4RD$B?E zfnsT4zH|?-T7fj}^^zg|@Oi(qu7L@*2!md%*HXSXGKY1I(*OA~pQ<$?Fx+ zmOtEv2Ey)cDP}yfopJ_B{<8<}x`nBzRz+|KQiB;Rk1X zmvo^;L;GnNErU7IXSmAk$0VjB`Q;p`gKgpFHsxR>yfedhb}gwUIh+H;qg+=}`__862swpNQ zr~bs^{_-hDc07_k$Md&Uqg~Pwdp(7WC}Us#i-9rpvTic z+V<-~nZ2`&Zjl#O33L9mdn3_Mn(TKqj7zNt_f2Iu?RmdZ+$-NKxZTqj>pCzsZ#p-6 zA~zYmd;39s!;t0794zrZg=>-homggSJ`VxB9+x;3%0`HeYnZohqZ)x(Lz@?+O5(Fa z;-EU!)pYR^fXS^N#FVi+GDz)8r*BN$<}UDeso12YUBuhrPsIOG5tNIga0N>vZk_(c zia)ZXNT2_OX8wN@4*yTp`Tr{-uDMadKXkJ4R0@i5@GqD8oZt2Tfz(lmk6Q*{hrELc zfK5?Qrx1G((RCMYaKqDHD0$>nN>^m*z~z89R`pZT{X;8R;(zaO-e~0qNJyx6>Geh3 zqs_Uy1H?*wzhmEf25B$p3wRQg;ZnvjUfg}uy-|O_Jf@09|GS>rcM73fx7l; z|F3$(xeRmn1Q)b&qolXDMu1@0l3`hssc0o9r`Z%k!S48s1ojINda zr}gmW{}5;BXOtwpN=VcsJ%~-ERvi3G8a!8asiE(Gh>-tpzgle4FOik)b@$4azg;x* z7rI|LB-=+Jg*N!@Zaq(CFVUS93U8=^5SG1UI{nOPm#k3d*TB6W{T&rY2Qxv}Jz{X#nX@GkdCQRTmKvu2pA)aOFm9*4OU2#MS z#PmpioP%pJwAj2{dp4;YyZkR>^^yV)H?|2I!gw>dHrviYrLcg*)<3fKXfkFg9+!S^ z6KXH61;mPSx4DOz#hnJcry6^RyB}`XVjCB>csGbV7%VRtUda(dZ%6n!a~vFWR2e+K zk;DYylu%8vMybeGG}#+BK`%z?!JgewtEnk_5vkYd>7EigKq!ts$nDS4uLGXk_O@s| zv=v@-t_VNM6d3wv`M!B>pNVcBMX-b^L%E5L`yjq%DTQ~$KTT`{+ROEmv-}t+mC=ii zbIYCwuSgt0nu#Cg@sr~Cm;7W^d#iY})e=RZgRH3N-ehKPSVh^h9{a&r>w8f4v zEEM5VvfsnOHPg`CJ}S_3IOXX24`%z##@d^Zz(1N_)Jle@wzZCyk{1UdNvi}O->QzZ zJ+OF68w=~DJtM`ite-RlY( zc9IQ0qk`5__Sg2pOX+}_@-jt1sh#b zx;JusdubK0J;^fZji95!UqMU_3M=*cjgRW$HRjV>*_8S@NB;E4^hf7)9_o z^<@Yct9_bgwl(H;aUZyOEl?o%p3U^v=fs+e_s^P~lug?41|IRMDzEx5x!dtueS==^ zx)cx0uU-z7Sl-Y@yND#?*FNX#euG5a3YP?|DJAi57JVc;cKw1L9<=TpAC+bzzm`w;zp98 z!Gk>Yke!p5rQW(K;yFhxif%6Dnpcmg&`SNH$D8qDO1Axnc7KxIwQb>COEc|~@DwC# zs?8zA%C5TF22zt2V6ZjL0uC3|0>aFsI21I3343op-4_&ex}f)f_g!7;Z*7aqf(QZ! zZw7*;V&I>h@Tf&dov%ebrf&iHdna=KIs}}XH4m3RNV>D^tHgP8G^5U+nA=|d)fn&dIzoA@ z<0ECu$InDqJ=8yXtfQZEkDn`^L4|*Mn9&{~;QL1V_PsnkpTVk}dz*k`Z-nc+M;U)> z^r*+qO(QGbenHSR6jmSo`cd346w&g66K92@wrLy z5crZ!e5Owd6%p_%`QMIXHYclGC0JW!(LU{wjy3NkNg0pSLRGMdN{D+~NJ>F$P6G*_ z;((cs5RSW_*NVNtz9z2RU2YIQ zK@zvGOq1{1WAtDv|J;A=)hBn3_68nPaDGnd&R?;CN3?QNe);*18fZF6k5ne{ut(UY zHcrv0tEt9FOQ#7`>Lqzt6#&~v?ZiwkEPwsFV;vNX_@(}i`ejvdb;N|^{lJ)PvGZu+ z;UCWNheNtORjTJ|C95#^ex8O3 z6ThGL_4_K5OGJ_l-&tTjU1HsjWJxry_`ViIW@MQACy1|bCLN20ibplrrpomer8Fzg zLa;O)pct2M;a|aWJ)?G@E7$d+cub2axt7rj@(*F>jabo2l2a{jfZwy9riPoo5lR^t z>Txe=(+rg1$*YW=OrP?d&+DE^0M};2@?V`7^_)sBQp9YfbogAsA>YrQJmg$*MKgQR z>A@|6RjcFZaXvf8#(oz!wYc?e2ps)ySq?eFP@Px&YrwKP^;nn2d<%njpKSlYn3xN( z6XwoKmj0UZ^}cC~fP;34&r{Q+zR{kcr~=(jyAV|^3q|5NI9}HLCrwwCVPA3W#DhJL z(9h8!kF-lZ{b%8{O65|K2m0(ty26%c-$Zxl8-g@8waO#8ko!fVn zOS2tRoPEdbbQj0UF@<+~Sp|o-oIOl+M%+A2SEVmWn$!GM{Tii1m?V^MrOD*VtX{pb z`ijhKMk-o+)7Dl{BDz)T^^VGK0ui?Lwl*5QJ3Zo=pc;m=Xp^*0-~$VmFl;@bV=|-Y z0$us5D3Z^@;Wk^Lu&s$Xd-Uohpk(fT-f_#vsg!{NiUDV-!uAkFznjg$O>rRE$G&hc zbb&{|!bA_E1NAzy!IE?6;Ro*w_zAK8R2d2s9nya``l`FWEk6E^2L%WxK@gbd?Y%$X znWU<00SkUxo*mfNw$&#|trRC(2?^JrA@ZLJL5?Qz>oDilA8I~)B; zDSJBqQ{7A*DRw~bAbmYF>Efh{+bNEh=}jmi3fDR^{4IvxXqhDll0pjhLIbbMqLV4y`#;Z!I54FSw&{lwudklSWY@rx=6$bCWr|<}w9)H*$?t0TFs%I@nAR z{B=}Dio(Ee_Yg})QM4IVv87Cj0Gx^z_ACtX#(4jfV$(vgBKj`O{^It}*kpBtO^rFqr0#!z^@$_J^-=s0K}ySCtFA8N~m4j*?ivs(4bT0c6m zoB19~&&DPFReX6wMm3nLwE7#oGUsc#Gro;M>x`ISoMz98LiSIn&R3^+aS9h;(oBf{ zW>DLuhPyhm)7{%mol-j{2TKZjf`4t%(kvACu24_x=TfZvVA=! zND@>#4qJM=?ji8vc$&mz7VE|byDD)N!EBS${%^v$gBjvWJ%EA*t}cGj_jM#el+V9w zNjo~Z7#AYr@kSdXs)bb5QaScYl{y9NlDITDo%T0lDYSutB0SF$7o{yFEMabe>I8q zq65XOQramagrEh<91N_DpBhdK7@0Vq7PVdM@rfg$kP_PWT$=-s*SIFU8D6g(bkiIx zHJeDSxrS}4SDdclhnQb|5`Ztb$HaIgG0AdEgfhQ!O+u!}zyDsDu$x{88)Dt&{aLsP zOc9s{x!2poOLgj8gcrN?Gd~;W?W^LA+zLLmpFL+7@y(7|M#l5%v;M|D9TjVilg+On zU0dp_J@@|RgJ*J+{%M~n3%8MkH55+U49!BFJ08L1(x7E-25|<|%VYw)rmo z_{gIPjdyr48m6|PXY)S*)4mbElUoq=hTxSq1 z(Qb|y5LXZ$hNN|FN zAi*t2Hy$K-2Web`1=q$UfdqmDcN!9`@y1<)d+^{cjRtL?k?H$R{%<`~_0-HeZ%x%Z zHRlr_XwE*H(`&E2_PVYgS@m7KLD>Mi>1G0R_~SMNTi6C34}!>;_a1ZZ))|v#2m$9! zf)+Y6`xrpr~Y*UH_D z^MO}@aV~)L$H%p2vN;GcKJUyLbobdeZcDTO{7CVl9$X54iDc&mpY5K>Tt zvFbS?yT}E*FEVb?^;dn!ts1TvQ5+jnyF=v-<(O~KWX?3rTYLP(b}Ch_{?hlP>nC1% zOl??7211t^$SY)F93%?kdh4g$di-|o-PU7Wo)W2=>FS=-QCda7RO*sl{C+Jc30q`> z+_j}{d{m6+_g6xw)Ni5=-SuHzD5Wlw6?YnU$Gq{LTd=Qk5J6eGPuCc9q^oH+@U}R~ zvAA*JdP}~4|B3g|uUCR=UP+dQuz^{zuDO}|mg1^AGA0k|Qc8AEfvx;Ri?x5H>{a^r z`}i&U)}C{Dzdc`}B#pBtJTLb(ME$K}OW`S*InCnTQCp>scQOMpI|h#)F47G+KSm9I zwiIZ_w(&l=71|YhJ5mXs!LiX_`aY!w1@%qWPq_XHIH-XUMRkxMb&*X~#v(sF*Wy2W z%d09m5w!Oa0C|8a0-<-rM6{^ z>#PVBJGk@36!&S#JH_p}5jV+=V3~GKmM__xcf5DkFE&$ZM)%Ejynj1nZItz%x;Kf^ z?4jtho*%t#uWci3Svbu3-ZJ(sXt*!w!AzsL_f^4?Ci#;F5T;{NIMC?FqKx*3+5t!o zx@xG228Sq9>iIAXHGe;7bq(i$gDx~DIY6VQd<)wGhnB{AKLq%mrh3g((08A8|aQNuz*Z4OnDlOd< z*BpZ4@2$*NzqHR|Gcd^OH5`t<|J?j;lb_vmSF0)gK=|^k!csFRg|^zObjD_a18o)pE&E!&d!PAx z2%b9F&|DsEF}ZWBT|6#Pk_r9U~QxGp3(1u08=n9p>NvJ zQ>jW++A$U+?v!x)-dpFEBd^@5^#;@*qL%Bsib?)7@*^%HRx^{wUiEY9lmx|xP>*8k zqU+09^+lrmB!oJmp!RI3(7w0@_UIhp74U5n%2Bt@_BiV^uA#cx9I`5QPDh;xJLTd1 zcd|sB_oec_PUxb2Eep9|{4|jjjv%~+RD|WT;1-3=LR)mX)FwF#3v9#2>(=60?qoJ)qGu0C)L}hH4`@RoiG%Zq2?g z1+~4+gxs-nt-9PncW7a_v4EP~;zj;mz!HJ+H*iM4GMTRH0fTNVb6d{YHhY|-Z8X2O zK(BOUNuCwUPdty^mM`ejwjV(LN77b0O*UA5J4uD6K$8If8abLY5%aslL1emgg>ml5 zn@2pTjRYvh;TrQk64QCiyJf;dvX3bsNgJBfSFl3hyO{#RrpRi!N^w} zO6wLMLsL=`C?5NKkF8Z|X5hrx{&OfV6fkFA0g)@|WDBm})jc{|H|GLdnl%FDns==- zuW$s?XG3BpP2BP(T1$a#>&6mdaGDB9dub$+%b>XueLf0b1BhtX-wO*gb+fARfC7i- zpU;IH3KO_H$QkS_4LCMbf@54t+1pJ%h+AD#dbob=?MH;d^p7~U9Cea7-mhm=g1+L> zl7Hm#IMhaDivU@Kv&P?69%$m)vQ9QO{5Y$6k-y=QIOoARIkyR@Hq=%=0rT(kwA)s} z$ESS-I>W3Jm)xc;irBix+XJ&3cF<*5!0M}CVs9633QH{^+MDW1eFc|IP5MKQ%}sYV zfa4y=LFdF3Ls);(frAS_a_yE^3R3-iOvB$LQFAIiqtI~Ci|AbZ^zJZ)3z zQustpAmRXUbl4;}q-6c->I3nq$Uimdy1jpD(l!!+IhjM)7^d>TDygHTDB-fhuTC5a-@IKmB;L6oCVf8_h`*PmPAt;rOb~PK)nYgN*m|4 zu>NT|)p+aa;Uu4c%?jEs~$#I?(Drn5h!BZ^Er>y&WW{RIS_)rd#j$KtQIJT#} zLWWw~^qNv{rEq&Ek9RR%F9Y`s(x848iel?i+8(zbtmu1N(7a`o8YvYUCD^ng-GJnv!Lg2EOfD>y5WCC}6?z=^4F zbUTiVl0AzGaULjYdAIGJkp68+XtNi!G(Fip;m@~Lg)im@(>T$yZD?-DiMwpxWJ9Fz z@sNNOVLgB&sfPDSiX%j`o{HS>07`aN4|`zfQVRg@K>$PlknawQ#OFstsd8;9KLnGO zh47;DvC=g9JCZ24b{H_V9nhkfimCWyMGd`Pl_y<4LseOxt|lnUw<(s_;YYjC`_0Rf@e zT3)wHNdxWdn|d;oSLTWKHQh@^zvy14)L)Y{saO@UN6DH~VQ zCKCD8U^yIE`-`~LfLAW#2~*b_>&ED6T#vtf#YhNe?RsS!De*p=k6^gkx>{88t2)DQ z4ca|#_b8YDW!Fb$SbTWxh;L7IEseBN**afzd#uM(&>S)LXS*H`olsr4xtcuB_fKYJ zUL7tlENwfS2C>czl)_hwTG#V5?l|MOJDg9H4U7WhwS<{eQXk$&w%V#s2LUO6>z;_c z%$bNQaZPHpbvb~Up*uWxC?*i3H_aDKPEkJ18N(2s)n|^4a-{AX4~^<_Q%(WV`6No( z^%*t%R#33s0PA;J^u{rGA^(0H4e9#|(O-D(&P*vy2g0nQ6Rv&LGyJcmo7=|30sD_= zevLYYjz2PAVrr(FzUe1%O06g^!%`jsABQ^P@?Tr(7DxK*YEPv_g&MNaDXBsFtSJ_z zUe@WIn}fei9PirLx^@qQ8b$Y9tMgR{R0xb^ko!^@j4(ZQtYiN+wfp9y5Lu$GIL1ti z_m0WCQRgi-guR!r1K3D`nI*e~{|Phy+vv7qzTAU2_ATb*O*yL}$zO$`7XpPcl@52$ zGw+2pUtTr*!YWsd@B*<*6FnCkg6~cT(ne1QhQ{)?41S0^BIwhcLCZ9+J{A5Km1bz^ z&XmtQL4BTMQSr=m;Io1Eeo`4%&PB?%ir>VTwl18BZHGoUlj;NREUY95DESQ!Jg=iE zd$%TlDQ-v4z20kxV2u*-<4GJ^!)D2`?`g!fyJ99XYe4g4J`23GIS(LeXG{MK+9}%D z`^YedBzMqfdGSP@^!=|$^ikI3tz3pkCKZV*zsO<@=Y!PsQsPa#20S2%wxf!XtaF<# ztCE}N^g~Dl3HHQD<_gEsxjq%2rKX?=c-<|Hb96dL@>?I^Fbp2ha8mlQ-NZsCX~gY~ zsC^XvLx7oeb-9fS%Wp>+ngCu@VUT?Yt2JfCt8~#kmqd zdb9Ni-mOL7=oi}FeMPZk6UM47jE2@JaV>^F*bi(c1R;x8n?psOGd}riM^!LRrg9hX zhT%()zvZivzLJVNx=YxEKz)0GXS6U*}T&9gWms>-DX` z%dSr!9zNttNh=tBFG3lTPY{@P`BGpU`ZYs)r9y{)|GA-OPUQ!58SBfbf{c`A;4enY zSo3Y=1jYdCr$WRMT5{E{%!(}j=@5md7)qOe^_ImEUu+?bJ@k}$+y+qs{j{}Fy^C_X zEW{R_tK%wrYzKsrwFVt>z=!K*zZ-IEgU`s{D7;@!gtsB~FMKrPXk?zk?Q z2MxJ=>1%B7L>fa+iS8Hg=Vx;DSGiPjzgYN3d>T522Vr7<{X$WcqMV5syoDq5TJiW& zB;or5hdC2Opdr!|)obppJShQ{vTL;kJ+Dnof5&-ds(2o+m&;_8?rLvn#Le76HHByk z#KT0G)qKkdM>Hurgkc08G?+sQ8T_Dw^T$tBjwc=`%$z4&R8-hYaK9v(_pialYAN+Z zc~MRd@hws^dpZiViXgLQzBAR#+a{1>SVxDufzAM#0C%NlQ4N(+oF1kk_G(gF{gxx~ zJ?@F9dLQmHT$RE}$eVqSW(laP9<;*i8cEZnDJ*M^4w-vpe9S=0>!hLsy|tE+qj$JhbbTizY4h;=6>1|vuh2t zxqW;C$AWT+k)yOakH=9$0gD7NMh(thCy#!zp%EEA-mn$`-qt6Od{bJ5Dv7pwo=Bp$ zo>Hq?mx~#)5V%gP&-UGv$i#?w#H&&>D_AnSXaJI-1#po!mr-$JWgfA*dPL+UK}T=n zFw0)z2hQ6d8P9IRuh?wU(QUM=@wH!fqU3eSGPvtt;w#ZcN6p_6)V$JOSLwN2!y(Ts z0!)E*ekrl|s`Q=l-SX!Xvnp=DfBY}Xn8&R;bs&$g6uFYS4V1hq_B4w^lkolJ+#Eg# zUjbHUC6O2sCVMQ+>^yrO2!ubBKSXo}Dq}}V`=FaBYU~Q%T zq;y>)V_SQXH<|Yj(zYjB2(cv7QDu5Pq~ltBGr%$}WAgmhyExD}Kf{5S3Qt6w$;nJ! zA-w|dru+tM%s*4YHKOKnl=WlJLogHk(1ffpyuU(FMG1l=H4UoucKu0bc+u3MK*z6b z+j$D)ke#)n=|(cqml2g;S*5o7x_-kd9zMAT>8F(*O;^C$b*MPkuEj4(rumV^=nSQY zK{UYkD>w-mE|^3{*15&-dhShZXj80e;W(3n@^T;Eht7m21@(nx`?)WtB!e?T5EG&c zM3NhL2Ew~!)kAItFd^l$hODzaZo0;nx>s>V!xT~j(Fo}E;-PB?oLIFpi?RESM zL|feKxft|YCig|W3Eg@TS0csrsFaWufXLkl56JIr)e9z1cd;+5y_e;a|0PyAn>k;` zvoNA2%2mTX{G?m3%w{M$c~J48sgSw8RSDOYShea&RmHY~hcYuaOGAT!_T>D04p;9A zxHL}%p5%Ya?g;1Z{W7`}Fc6bPABPHl6+aCNP8<$@ok#&H{ze*t!P*K zhgcu>L76woIE`Y$QfWUTzEp}bQG+ZJ@Ocnxjh`YCSBu~LPThbQO{M~AWC+BExDRHl z%{A2u__)8VnHBPt>S)b6(-nushxJvF*%4RXP#Zy{w~TW5GtMLIrC6!As437Ttq7+B z+RgdQCO?|u*SlH;VSYh6*hiQR4&Q*D5h;a6rc82yhV6c6%i_MOq4h^`?5vi-1V$dv z(jTSJ@=5x}v9pOorE!bd%g?zvxW478R|RI5y^VPxkqR(0&K;+2x;6QgQJ!Sl{_{ZX z&uS-Qkq3a1s3ESWr-SAZ#BYyrIp@Er_ar@WR-8|6izCMHYKmZzDgH&_N|bFJ@pif+WtWTA15h^%f(T8cK6`oTH^Ev z@h$ingwEio3MWh8dC#u9X<3G^=q&8GSY&s^6sl>}hXq`_ z#7xGX<{6jRYarA2ZvXz3s@Zs=+INL-auWMlA9@WO^&P@55~tMQ>!%Kq4a0nt*ROaF z63~z>C0Ah0Egz@Gj&goC45++G_c2|*;ITK0RlsmW>O z4+^KpPdM(S-+?);iULpp(=+Xf$GEfeYdUn(Moz3{QF0Lp_ki0o8OTM&w;BiEuw!@W z)D@MJPF;fh44=Or&+fSIwgICm;XW9Q(%SJj!TVj5AKWUPX_Q9btm6dhz+^Hq*{o!4 zPhKv_YE=CUI(d;fwmU3p{T1JmwAiCGHAee}M|PSOFXR~jl*BPR|I+7cz29q^Irc`u zaLq_Mt{@fef-u|Of+DA)R?vME*NuO+W?*zvY8)IrI>H@>PN=Cg=$E3 zrE2AHZHb5YGL_dJjP+h}Y^86*PG&L@y|+;!k@Rtc&!eA|^ekmrrPw#hh>*aOG4l@< zNvmb)(={K`4~PtsV)59S%n1h@!G+2P`mD1drqj*=eW~(5`79;x{D^1`aGf6Wh}zP9 zrcdbvakGN|Iy=bbx-=8NbM$8<;3L!H3t#n3JCR>7YlE6%HxlTV}I_RW??8XYMUcXY4!n)y|2&obwWkp-YFSx8Wa2RbKzo%ANGgAs%4xz zvs(4jS}667byMC=tYd+&E9tw z@gc>EQq{EJ3`^&(IUo)C+V^TBqpqk^R>X3)1Il1rlF0@RN$mIA%~s;4nQ2m_1x{#} zrbHVL``-kIH;wBVoRyG-5cZwyEcK|P#q+NZ*h^~<-xe&TR7z)P3iZb|aDFYbDN)VK zRV7>0r54_%*u- zDW|HtgaUHK<_l#SOcC=(xkXu_T$HfZx|BR$Nczr?^Uqm|?%ljnfgFUdf>msz)%b0d zmj`aOxFnEu_(kqEW_*z?^x1Ky$OMi`@FB6Sq;}*Q{;PUIxgQ6t2hBN7hBg*W#F}Xb zI1H+9d%7_qU?ztTD%!PD}wcMb|s#Zuo%?D-H_Nv*Ro=0Aju?X&1LNWMAVUiB4oxznZ=2!^Wr zydDN$pVJCy?2rMt30&$yxy`WI_D-{&g8xfFUQ4aTc>yIOxRJ^tU{(8Jh^@b&5Q7o> zec;-2XWTL^kRtTnk;Iv%vFlc>*N>9n$T}jNgWaJQvo>P`IrlZsP8QZ`I*2Qn*AC&a zS;NgC>FQWrlyWe|pN|)AHJdpm?$zj1g$4Gh2KVcQWxwWAtiMTK1-_5Te-uLmm}Xys z)Rvh?H4HD9&N_`wzhc1{6Ca34d91mh<7ltb_yuslP{i>0D8cCqhX9o>Pzg5@HgG$A zvSo6DW2jgzY_gs)-IYrY{g!&W9B<&}4N+TRN}=8=+D&Lk@^*YO4~ZIXnkytuwcSo; zuJ2A!y3msSiAmC3MKpfha&Y(>4a;0e7b?w8Wu^=iO14oSklk}*%hq@HREpZ z^f=mT6gh^KDOM8;so`?+#oa#fo@&Ya5o=#R7F+lN0~_OQgLX7)m1fiqgVISdR#HC} zD!fYsX=Q z%$S|ZIgAqImFu{;{DFZwC6nLaE=J6_WA&gOU?Fzpi%pS2rm;i!AUjxSue%IU_2T4{ zFkR={0f>(bieEK>zP8=9wqg0Pu9MG7bz9$Ch@uEv-nzy-AY(3Slrmfuee|pPTisZx zBai{uv7WG_c-lRr2s?PB`j*pzRYN18*9h3(93pGjGw&*H%&AzLkiR6D#Glm;KtfT` z9wQp4_a8NEU>8zhC`=5C5bd$z>|_(wnZn3!*TSKF*YW!YVhiVJdnpEk>oooSVFL+e z#PbC?4TH7`EgFf+l7nk#@Iv?)(}D9kPU~p}VmHEP|0gmuaQDm^B344+;KaRm@o+8S zWu*|wK{`?mA>vAd)^|^wom)Z-);Hk++Qb6I+X9F9vk41xkq}B^bQFzns5; zR4kd8Oi@mCV9$O{bnkybI`%T|6OGW-Q_v%J$zV3|E++cd zMAb$JahhVMVeW(&bvzZ;ey2L{N?4SdtN;E_(Av$(Ps)l(2eWJ@OR@z&^8Cc7-}Al4 z(%3q(Gdn}TJ~1uBMY9X)UmPG(TMA78ZfPp{;p)sytAf&Re45tlb3e-jJPl2+K`lc^ zYux**1}}&Wlokl0^^6Tk9g6xXq7V#lf1!KdSI-kqFP9gnUJnCK1P5>6!8*G>xEArl^bb)-Ypwl``81|`7zLP$i0iyPEUiAZoACxPPcNKj7nL4b-CuL4JnxI-(VD2)q;-fA66013B`&o;xi( z8_I*P7!Mas*EU;tdjR0KW%j=7?qSIPVIMgy&L{TpSFOF5&e!kiz@^(cFOLvW@#5~UJ3iUhG}VxKwLI#J6{i8_1H^n%_}?E zhf;9WWzM^v{cC2+;ubJl%K!YNpMQ?U;U+?6di~RQze2VR@lUw>g$Q z&y$9_wPCTm`_o*Nez6?V2lIGtx0hsl(sO{#LHNZLrPtw4j-E{WmP>!NEv=I;skt#iH!Woyr5_-^>HQu+K0 zFTJOH%aW&qtjV8*RwI;8_I6NuY~QlaiBT-EBeBn7ie>UvBi8a|M^1y*My*$ct?4Y} z;ei>*8K-1>)}dk5>|6TuGt?DU5|i&--5UAzfkei`DUsIU#pWu{hD~a=*_OP3JwU=% zsq_VeeiBl~xY%NRcuNQ%Yqqyv=*Hf%tk`w%wgkAI@EV5M8_rhi6`bx`vxJHG<9p6Y z42g%ELIc{X1-wN7Yq$Y~&4L&hK>hzlqEtHZ=>H^9GNQZ9%VX$y+}99Lm_!N(DiT=0v!9#!MC653cGXXz+|7xDJJ^rQ9olE~|QUAYtl9cKd$3L?`|L9Lk z9R|jKOYnQ~r|}WvzvznoJ5Zj;cNN}Dks(Jy8o|HdxajV!s|*Km2-pAQpJ&VZ&xqXY zi@~vQWv^jpnUY^pI%4|jJ8ts zRiXd&Ih(<=54$wT88`ljG(wxD9^wI9Y>W{?=F#b5-?W1LO8c*M0=p;q5W_vtsHFKT zjTG>%uW}9q`FKXxkmbcNj~I1H#qMZsMYAsFxPpL7-(V;o{p2c5ER6OSeXDxr)qenZ zb30-JaIlTh)k!_yc=AF*KAV6O&d7;Pu0A(ag{8F@Jq(v zjtSJhO;XH;o+%vvoG|fyHXEw2LK?wr(Ucid>jXn8!QNZskoG>B0EZ0N>^tQ}W2ice z0IQLxVKT3a#-hn%&ZH0{`xqf3U#W}$uB5 z7*#Yv%%w%tcgc;?k`-g3$uuLP2@-Od*!i!u{i&`Hh{H<|tfRYJ9NSpjar)-pXZTs77R$Qb%{s9iPR6zUUgPrevCWGA+esTS#v*-Gq_tzeyIKw#}<~7D2GJD_AyN#kKTqnvYFDUO61C;ie=Sm4s}KnM^8-Cy~N85Bk60_tGU7sY>tKlt8wfz63224DrI(v_<0=qE&a-;Y4AF~a7u_4DGJVGBbmQD^ zG~5ohabLOQPzO`lRFAOF%)=-VpXaQgQI@veEd5kGEAM;W_zt`M#PzP6u9tnY@`Xae zd=mmz;k2V!?~y`fVzW>$<1mWm(^=FTK-O>o`Q0TzB%iMLn#|>_O65ZATXm)vav<;> zVP70~OQBEQ;?nb7t?dV6Iw?G36L%4JZmYIUT%ks^N7J+j2nY-}6--O?w>Mif4<7`v=Z)zBvnE3(>WGwsAFX z98FrgM2{5P5||g$I`BI;x=eli>|f)S8X1Rr*Py-8k0mVve9KVg+LhlLAp>Vit+IK3 zxpLkpCE04)*qacva(L@_piqgAlV*`2YQHpAshf}pwhDdhw9#$*UFBa10mj=Lbwxg~ z%pdKn1)4=6YZxS2TP&v)&)<8Ry)g##s3|^DlskLI7-yxD@YH6!=?rbnf?Ow?ffrQ* zS||I@?#{m{`&$(l0JhX-9K9RuUp-2C3RyEh-te>70=XyGcF@Fb1^oV`AzQYzUEmVx zFmE7IYg8(+g`MJenayW%6y)Lxb@&waH{*DTX3xQzr1HEGW-U0?v^McQ{uP>J@Y6*S zkFbckb0b}sGbh9vw>3%G7A`TgCe}NuRhIVhK$CKQ4O>^#x<4O*fOvl%(CRFM7mHX zS(<4;^^DQR-Z~a4k`WEDrAxRw#rCC!P4zCfhz%uuz{59R8`MLdq+OLb3h<%bf@Q^B zd;}!C!j&%$o>M{~%?7*NU;G=> zF1gU=uT{2N1I1T*2oLq}y?|!$SGyM3(xz5k3FRR>UDV;)`ekdY^1%t%0*%K~jr2)5 zy}T6Fz0Nt%V40Q>HVh^u7wg}3EsdafKP&GN59mGJ#7WsN5)`^v^}d{Fx4GOT-0FL9 zXXhFjfZCD(CrXGIil5kopWbH8(yHzLNe{l-Vx_n&#=%+yv^K>{rDf5KC0V{p5V9ZL zK$N~?M?MKkvQGLM_f!BTzw1b~QC>Z;(eeh;G2;MkI66eXaQI|>4b2SWiTlxWyM^W> zge?8>Z;B@C&RjNfLizSwfe*(SZSy7uXc{MbcD(ETj$|mmSvel1xP}a1+-%liw$P6x zImARFjW}-R>2fZoMa)6rw{Bqs7eB~zjJa`&x(Z321CA9;(J` z7&*op;zoUG8fTpIpdFr%~>mr|P&T)E_k zrr>ES9MZm7UsmGoJrTilbRKWdPr+Z`1Q1)45&yJK2!hi_7rNrs+w+q)T`fI`r+!FI zR(FK%LVZR-7|%0{M&i0Cl3k+6aZ(;TB(o4ZET}!FT?XuhDU^v>a?r@Pl?smj3K&$XYVOnDFHouL zoC1T((WOzu#bZ~BnOW+}Pg4a4fGp8D5k(0ntA(Y_wX(E)_wxMtVFRyf;hIo>=|s3= zv@Y6_z8arJQ9^B3q}Q+}Ja0JBwgmu|L*V?RX=s?|KVId=`@=;4(EnD=G0FC(izwxH zpm|`%)(eeNWJ|y3cdtKxMMF)W z+N89)_sLK?t2!bUq~AdQSu&cp<5*WtSJ88K5_&8_uAD?#2(Ml_#9U#@{&y9UM9M+{ zMM(2ISGb~WtE+|Nl7`Gz>ew5&VE-_U$U5t!n4=Lg({;xw1+pfZ0#UGUA<@V|=3Le? zfNz7V6JDT`hN4YzHq=>C_+bM1AuW3|)Yun|zKeNbbA2D)Kb({iv%gE11PdI{kV$HJ z#vXU~-H5B8DB<3u!#C@@C^YBFHK})K>oB1!=s&&=V^7W5erN1?yCv8;IwS}^GmgG- zq>U9by_aq@$!CXdpxWFC8{UQq(I(^a5HwhB_l(?>md?4|{Zbo_#DgfApz1V_tjxM$391oZD^3_;+8%R}fFH zVNunWv()dd7$Atb5@v$t}gW#A9BP-re(w|wEkkSB?l#`30U7()~hDS ze^jLL&m!bp&B6A7$J)>0xHfNVkufPd$S`RzY2&V1R&bG5>#D$FbP~n9G9D(vp(BMDG1rct5PY+0aa~^^-bCYn0NnMJcwXuJA1vx410oPL84C zkAuzrWnWL<972dMe^CnXeS@cJZx=uA(;&2qHdd%kzv*(da8ijp-E~#0pr7VlNE|1w zxB)@u$uxU zWlcz*NaX~UV6hS%VCKphk*|k+R&-F4_rh*MV3#%@vxU=t#A1~6l&Aj`{fTj_6*(y0 z=QWtlzZHYKg3`53b=@3H;jgqBnYb}KTw;Dm5u_~h_afoJN%`{kdTBzy_w?_j)<$8@ z@b}94z}x$u-

(79IMZ4`6oF6aVJ}*b!39|M|fGzi)uu(cbmt@RVXvB!5xk<~e-- zlcs^1<9!GdBsQNt+*!Vv<IKPE-d(l;+ck=E;CH$VcSK6O4^X-|N?QLc(Hzek3aLy4|BFw>(ExMZw7wU)sA^Ktn0ADC@Nw` z^~3lI19dAxO4lNWXGTo?dwqF}7jn!vXqXxnn&|C4$*ot0Q|>AJVa1}okUeBkTl#KK zZ1FMIRLDW|8XpM{H|c=(eUL=ja#hC1zpoWv2fc>msnK)!Xfd!%km&Os*r#F8$kIOb zCl>;pzUM0E9|ET|*zQ-NfLN3}vji5ao=aZr_w9R%+qzTm-jilcO+%tU<`b^S|`ch(GYX*AhR7MUlP z5k3-V>FJKN_J($Oz*!o_Xl+Q%;jrHuv)LWEbJuvZSPK1Ib<;xPg8bN8805?6hAiyP zQ?uzHtpm8Tx4nfwyN^HI0WNY7hu8Wi&h_dv7}Ixb4bp&BRwIw$zI3OO1~Uu5O)at%F;}J5~*K5RAf}>(QYQ-S`f^5%m!pimA_2U!a zBXKHRWIArJ_-B?E)g_#)fQx(nx0TL1E)^CVhozo3tn_B(!rcnL7~K)_BAMFaZ3tYW zADEYOO0euLrt+xJT_;6*je=`YK^3pZ*-4o_YjNbZs9O_XYE^E!5b;X)4$n4YNL`qQ zUa3GxTY5+rhotTTBv&1kRF$F2PHVvK|HdFlv|N?>4bsWZJ)u3{$2nN~Z;T6&$`i1a zP=lwZlpvKh>|Ah~fwY-lBh98vKYeCgq79M6R(xdaa}3qAOHcU%^Eqpa^UHV>E4*1g zI#*^A_mK8GR!CxND3~d`+`){m`!U&EsC`IN17?69%RShgAE$dS-s+FJZ)rM9l|cjr z)$MC80WP7AY>P`W2fW`jP=ZrFyb09pu_^3MS9e1lOM;yF*9$OWnAw7=S`9B{^382c zp-D85&R%#iYm_4E=GK*>aeL&#oF}?Su(Gkj;-2Lp;$u#0X$MCNx#9up((Bj7%KNI> z28!K%n6XCFS@iLk2NP)XU+=eT9?|@u zAb2%&{M*gPPbij$uvyu4e7mo6AuoA4m>=6pcnqou@ibFVYIM7ZZG&9~BMPws&e1k4^~$Xsnx2 zhzQ>M)$+)=;4z?{a<2386fJjN2w8(X1L{%3vhD1aqVI{`+16$FUl8MY;%qs;9M6G8 znYA#CcLC_vX1v~ewXUrZoKVad0@AXL>I*X(-T@6%U9sjY4w!uo**P8K2KGX4hvVh{ ze9O>I5&9E5P%Z+S&s{p-93bU`m&_W4e=gf^A%JWSy-TJ>CKSWLAFu_&f;cECf8euRf5NEM6M&i1o@ z)60RCzb)-QaD21&ND%3>4-FEmD^cL@eWLE*Nfl&&nyXLc_#K+J4ZRTkF#>OkMBj zO`3!L?9$h_z-mHU{t(Dc!k3y0f;$A~_IMTUmFRuyyC}^)ZuQ-!eyP%d=bwng=YnMmMuWO>cT5ow1VMUDj;Fl)Ikawid%_t38>T>78 zTfAhm3HY1t<{IIo1n%+@fG*pfrM(=m8G*1xtHTqHhs`9?qJ@jkyRD@4kU6}8;sbXQx&@tyZtsp0_ z`KVPgYLL_}^@tjXgnsf!^vk;|y%=H|ATyg~4+XbUE#9vbr;V)f*<6`faeOzab#rl^ z$3@n|`>crPS!UBX=+K@??3Re^6mNRis`H2DUIJ<%E)2?!x7ywQJ0O3V$q*I30F;O3qNo-JQ7SV zjVvsB9Bz8!4g!|a1QAGj?LcJzMjEmp75Oe!dka#|ySVqoQN3e6lfq1t z)4>u5>EBvloUn*b*>e++i`^{aZ2Qfgy|^HU_8Q#62a(fxhiKd`zWGs@XMc>k-4=oA)c@mnx3r( z-9VNAag68!y1;Jw9)fq^^_n3Lj(0O@cw`UC%!g&h_RViJy9|38Y?t~rA*q)QFfnMK zCl#Xmpu|9?6!P^*ZfRO#?x^_kQm16;&s{VtcNDLKrSeRE7d+*11x9vT zCoO-Xwt4lg+S@E8-Ez_I7ty6Owh0d*ii4?Hu;uF_rn2Sq437@!X#*c&aw8cbO!&04 zU#Y9E<)lp8hyNK>BvC*A-;JXtjJMYf-Y*h}+&uWf|MihyA)RKM+(`KPGoIu7yAS^a zXx+B|vYjk0?Q~4ONc;c9Rx^>rq+?$BlfSP*b1V6Rk41Ft8RKh~^v+<>>cE}PyT;Jh z*F`MRzEv_MN%;xVdrZCT1ED>kCxVRHOng(6Rlqp|8{hwRG6ZV;ty>Jxb?biX1 ze&>sE;`bt~_yuQYEp8%K|AdpQM%*A}WYy~&W{a%-5U-b7w&|J%QpXd@1ec=5CG>@~ z(;gPjPbcm6jsyUz>jzu z95LGAj2N7y+f@pZ;Pl&1N?~lWWQ643+a^WYO?QbZL?Ksu|qq^`?%mN#x?E(m$;M_=@&E|BrsfN#jZ zmU2U64seg;PZ2qeD{WRV9`l>#DXMDk1I~YACI3G|Ql|!L1&7Pst@@Xc^jWd*ND_W> zK_{ZGX9*c%egR}kTs6N`of3Uh(jX|Dp&$+$AvL>1*7%eqb&Ku%dgR~J9CN<~^wqQBhE=qX-jShvyx;QPPT+W_5Et}Qf zK3gP%Yt*9Kn@8j7b`*l7C1P*b`gs+ZM-vaXGBgx?Xks4*WQJ^nQwO}DDu6lI>I2xs z6T)+Hh!f_zKqIe@NA<5lyy_{KrU-R>`pQ^(&LYy}Uke+_e^IxkzMKmG;ZJ>Z>?=ym z9aj4MY>h)ypkT){&fTyG*wW-m!8KL8z%Wor0V=owuuySJFMi}t=BwR7rVs0DeBE6F zCaKJ^vhdul8JIsiGq2P5AeNc&BbxQxzRTG!fiQ^wr!;n> zkjH&f3p)#x)Li+69<*N9kGf3KR>FscC+$@%)K}+v=Ti-JEu&h@BxtwJjw&n4+w-}8 zZ5X!)XSeOOl>B^MGWO*p!9rAW|Bc9IwO5_dck$_8hbg;tw^7s)V>P5b?t@BVd@99u zxek>1b)olF&$bxze0RKy0~_G`7RC0p9l}c~Td48jmy`idb_PGY&Q@mcA9kL9MTSp$ zAMW0)zvwXEpzYUMx)qh{+r1eQ*hdq+X~x8B@>a?CJS@zv3CbPMZr)gBzTTN3+Pi$) zBJufEw(sw)mX0Uo`xl0vZ9bbcaG%vv8fS`FBFX-VEouVqqWj1{%gSGMfT?X3NR)bH z*1|tVeyGfP+IS)Aq8U_ScK3eIHy5w_%d}sE04aO}_5L)}AyDSB0hE7{bIREr3FI>CCqu82i+e)!F#Gbm8DoqI$j`)2bTSMz!Z_DO&Eql; z9Oy+;Vz1hyai1B^wwSJ*UyN}G=51QPKOa>eu845-X&XHi*&+32DA3PAsFR;%uO>uU zue%0{C*8(uO~jV{!V_k8cpE(dlf0f!M12O>yg4f^~=}CqeJ~TwK)WiV$N_`mW$Ub!ILE3Bodx ziK0`aT3da7Uo*@ve7;!Q9noF+eKEQ8g)n-dH)=7F8l~EBCQp*Xead)P`w$s~6COGM zhlrUNKX=4s72*ykXCRU5PD5$&-Hd+xgI$1V7Jl=Ot)#$ac&Iy`oMl1yXYQU9JQ_|fAOcjKSsXKr-2`^J{U zP5V@q!zQQ0XBC@;e}?_VAWn-qX{nCGx4cr{Tc>h*XK6P^!0ur#g=5wW9=^U0va!q$ zELm5d?kwyW8bw$rT{yN$X%j%jK1ZaAE@YB{l7d3I_LqUcaRywIh18Lf52>8wBG zxn3829#3eD-NZ{!IB65V5i3OWAl=$|+ZD z96#=7PVi~C_Q6j_jqbP;1keqd9%<~GnY}J)SL?_M5nph!P3WurdDr9KXj5#xKezzc z`!#G|Vr|hp#&DiSA9%M%dz7W;*9Vbi;!LX6i#A%Z+-l`Yj#68QUZE<+DZ@e@7R8I$ zcwW-4D#dc+uz@~pcQV+8SG3V~%OvZlz17?|!$yYefav;Hz|hlyFF)MPj~Lf}%N)qj2>{8b_qjy3&v&R7MD#!wRT`U&Wn-!l_@#%xM9B7Q#E}O zZJp`Nj&O}?N3y?!E(HLl@GX10t&@DXR8Ho8E_>x3?ENKO!huqy%vi8=mEk1^`_%#E z{EC;Dg~%P>6mD2^pm6aVtum~{iWj^m3VUB&_imto6N?=gR$eOqW5{XC53Qzt>oxx# z_z!cD#tXH3U%Ac_;gs_+Q;$*_`UIXOW*} z-qwTLyB*|bmJl)wCz(jTA{1|1M%oD^FBBkhF%Enq5zn>$D$io=I6x= zY0vrA3s}0(+oElJib2x#dU{o_J5j3iCHtYYRh|%KQzEZq16i_(;bg?0WFl)h9WU`u zzDSc>w8U2|OL4Pl9EbFC(=LP&mvZM!cPlVzEs#P;=4ZQ#D$?^qXE@lL<;YTP~G3UAaC(hKXpdrKD+E$_OE z%rDdN{d|MtSJ8ohkUWF`NtYAw=G+(k%3G50p<-0oJPK6DmbW+Mta66ZY$zJZN zg(3+CTAVu~%bn1d)NV(DpxFI#gXgKDX_a=cZ~ji2U z@e(~><-hBjPPrx|6O$$h5gSik?_U`NRocy81pj=8;+u5snv*=f{rpgCG!^48XK5MI z`*0n@7G;&oKi6x2+cR?yFU(4$y@iuNGqQtNXO!yYp@JFIHR2C~GKzQ*Z!hIa zXY=dl>q0`~`zGfW@m`i~-`C7w!&TV^3I z?&Nx0d|ll?=~$JT%06|8p_7%wboHbPKXK*K_W4~reQ@y{dn3j+$K)!2jfj0?5birV zAL_i)ppdpLDuHZe z!oA=yvDK!gOmk7^^PYXUEnX>yMdm4&mi0F3Iy9pOgP7&LrIldTFKdiS#uz8wTrt6$ z7E={rBh$EOWvdkAeU5sJ-S6#*n%@|JIJ8QLokHp&U+hW2-;RkF-mO(oNjCOEKRSr> z3?y4&hZ)`ZQcJ;~O&DR>X;YA7E57IEhpGvkBv)Xfl6Tz+jMuqNVa}OEayA>>aK=;v z+c^l@h6hjV?N5%`w;lJ3D^HrXLX*}eJdcGuHIMbYAD?;(ixWTq@b=TkAP%=q`TTZ1 zgh-E1+VbSOzWR(1V$Z|XCLinDua3Fs{(kzAe0w{`{y`FMGPewx>nR91**P75CIzMp zsLd=t_eSVk9}78}Sa_*_jApGFHHb<6t0CC3`D8jaA!=#s(8?siPsKq90kf5HW@b+8 zCY?~lhKuU(!VJ^WRTGX>H4Rbjief*G5#lPdN^-G|tIA8xt_$T4HzPX@- z(6KUfgm9JeU+H>Ekyi~_Q&$;IwQXsDo@dQX!M<+`K6wthvn?mKEF5>*K$s3dr=F&X z?ZO;!yWC?Q5Xz4vFaWn0A@zn2?wQX_gv|nQJ-+nM;ox-WS)8DQvj!Z|h$=K(7=mQ* zAghgvn$baoZ_xeTKMc^S+AMl*BP5v1+lMQA-H%hgv?0&l2A5=Tw23gN!;| zAt8h#pYegjXnxUaF5uT{4rqQ-O{E;+`g?{I)=Zw6?#wT&f!m1abe(8q!$xkx1o1CN zLLkJjq;N(u^+`tk-#MKe;+&h8D*#!&Qs)IXU?_Diu#t9uA`BP2S zFx&Ur!`HsH^XP#l>viEyJLO9!)*LZ%##i2ya2dpj!VVK$H*f0x308eVOKPp&1I2kB z7H%ZyJTM_I)Ef@TqSRUGzxxKAY&adzEb-txPrR2>DD<;=_(%VY0bVZX)d-mEt86Op z4p|Tt^$W?ZzCFD+eOVWpvcQSj=w=n&*78vy84_zxGDx>N9wBC(Yn+vciE;s^ND%3I zGX@^7(eRb&wQ(=MM%tdWE_btaN3kH}D}uM+M^uVE_+jz26)(8v`LHnXB5Oq9=hQVZ z_CWp2NUe!^&;G`h5YOz`3;O#sW<0~ghPE*pwhvu#6SyX2*imQ%FgrfF{vbTh#rkWW zA4}ToDBsByA2mBbh||w;AxJqn?p9YkmWpT|ej3sZ zSPllV*unJNfhx689lFTA?r(8t%hQOz4vqAcsIz{~bsBbO^5lLz5Jh`>wN8j1-Y$IS z;bO$0_o@$FjXLn$FgmJ$T}iNW_57Huz6=>)1b# z*2o60oP1Z4BLyqr!+~LIzVo}Lc@!Ty#)t!#wkgggTZBH2j{b7;0w$QA1!upzXR2;^ zPcIM~afHVa_cle3I4M2k&nfw)~@Bf;KJtA ztxsZwKz@fGK#z{6<%e%})TeqUhp)D2O%(7k9or5up)Z5p#^PK?+#G@=4F2ly7yDmq z0(v!3N}M>4P%Y~I+1m7YElJ6uu82LNU3=fD)yf8YxTQaZd?^~s{c zmF(9sl4AjwXf5*BdfmCbZRohJC)Pq1 zB}unrPgK`lR^m4}{ZcdRppfN&wVx5kni0%2- zo3j`^!mjeH(Bdj*DJkal)+L$OFzQO>r{}v6jpDQ*;zRUkc*c!> zliH}&(6|kHW4@OO-8$!3k0YKMXHNNsIG(yxr&9I(Hg7!nRM1ZP7o;uW2x& ze&d)mc8{+|`P(BjToBaUbF1mwgz}@Tv>^@}hxgPjq?4i*dT0~P5Ny2i@tsE>Fl!tA zi9Lgz(@qyH{U|P9#$9zM?vGRavk$kRU8N&4L>$?4&m+@oL}Yt$;q9zh#gmvwlg4rS z%$u3~k@Mn-Yuo-X?uW0{*n>``?g5wlUWPVXFt=XS3Ogh-)#taBh5MXkL`7~&1RAD) zHrQp_aO8fWOU~Mc%1x+*8|t|WA#-;czCYg(!8es0doGeQzVV?gtLnb}$rE})aky=b zvVUW&J5)e1Vz}&c>%+>mI!ZQa(y;yj5P%I>sGIwqyEmAuvAi5Sr`_x3$0*t{2RLzv zaz-w(Zii4!hZE$bjBxcqqIy$>2#_DY5++RD-PbTtCl7DjkLHSqbmyYPWEiZs2_Ld3 zU+W#xW%q`EXvX!EhwP;K6Ljy-?N|<`Y_gz=Qtc^0s_@56O!3;M3l+1Yg+dI!n-T=N z_^K3q!^cE-tzV>h_2cuYRLqf);(E81OR$yidr$5bCu*d8238)aQZcp zsUCHTZB+8_&m$W<9jPfm(o^{YFfQYaF4(os`fvIDLh#_Q!&&nX3wD9>qil1qu<(k( z%x{Be+4x~c4_oZ)TXu9!NdXpIF~!i?AI_<(y!gd>5v6NljC1w_weAp$6qf0a_2s!<#~6ujp9sFU zV!T9wO<=VPm(vC&mvQ7T<%F#VvdH1^8L(s_WQVIlIRKWS_OBf4Y%PBDDb?ovop~E6 zQAoj%px!>K_w5KsZ#hL!SFKBUanP{z%cUewvxUHCVur1ZO6~@*rl7vXaXjS0 zbe3EkSdXR{b!HCv<@M@vf0jT?k7wcg2HQ923NrVdFtKPKm@*0@V`Z_*g~xk-_G0De zgVx{*pAU6wq>D^~Emv2rJR>%F&t|KmoVE3dBw<1rBadz@cYIO(EF%Azw-1>|A$NOmvJ$XIa)#=J+HT> z^($~}12ei4D^HT{@JS0*Zo%c}>*V=XiIvp*j20ZILEv=i8|1m*ey9Rrv~P>$qZnhM z)3SRpCA@_Io}zOw-tMwW3Vuo+g<1ZPQACfjm2I<*`S;BCAMrq@)qoLi8t zn1^1;!Gk5FxeEs_Pa+C9&zK^WA8AM#_3o7$X2x5wvEUI;!r@)k8*5wk zk7H2xuLf^{kh1M7P7}te){v1Q|DS-;q3*09jL49YN=dg5gF&GSgpBI$TO5cib9jGr zfNQoF({+=O&S6vnqUb_p;@;f(V>Bs|Yf*+B&e~q-*rNDjK9DrH*d~!t(_#^(*Gl0n zv|TW1yuE%{3*TLp)(okWtUFvrX3-oCF(Ia})rck@FHrj?(~azn56AV`VqYFTbNtwF zfnU?66)5wZ0$i16!9RU`S4cfa3y($3UNEXhtQ$;LQ2;mz*mf5ZM`R^_p4-Ix0^u;% zVKe+!gm}m(9}unu@~Sfhj}q*ueIs{j1ZwA3j1v6DhN0;GMXH>Izyj;O@olQ%j4l@B zkZHD|{+fXcQ!U{M&8~Tlsg@*#SZsap`?gyEY?{uIaC9@Z082A9!z@uC%exa6M6?m# zK<1F`%7{OmF|L1vl7qT08>G_~T9;aE&}0pkrwbFe(((9H*GK#kMd%Hv#1wA3F~i7E zNeO)Uz&w;|lZ}!J81#UQ1waY{jsH+5V?J1@ zAUM+Xnb4dtI<^;a)pJugX|4@-tEf9R6aH=BrA;QBYaO{7d=Zg?`@v0WGik4bUpB9T zESvxgFsTu%bf@-Wq8APV?8UIui!5CbA_82}?7?5*c4nnnk&27R%Q^wZ)aD>%rY9rL zOi8FB@FjR8O;>tG1Ps~!!W7}(tb?#^+@zt_!Td=*jgXgqjMTBY@9k1I5#t`iQ0tUC zuRb-yUCWV=)&Mj0Kf2U8g59XrR|Ks~2Q)F4$p%g7_!n$lz;mrJ$pve!!H-9Qij(6} z#hUl@Z^1j0CBxq*7`;(gO7&b0voK~J)d4{JpEJt8hqYhz3+pXIJa-GXvl>kXgohD;dUn&SYR(=h(?JETe{<*@4ow5GAbmu$WXpl z>({@X)HyPD{oJCmxN*`1Q|QEoo>%@eBII{a;cw|&zBJyMVZ&DnRyl0rBB95UC9tlM zegk?T)^vkA^8O4O?eHJ0<#fX~n9n)>eqBY~xGW+C=-FX(CN;w)3z3XAWdZ>>thMvO zr1(S6@1UF3v*y)twUyIlJJi9$NCm%;UrNBV0c8NRom_8q|DifM(*kl^ zx^Q-Ulow}mjCgq;G2pqpDid0tvV6XQfqW7E*bpY!aQG<`K6PUQ1FRgtClO-=n z_#vhp^7dj?S#p;XAa(>)sx|rcP|NLoN{?+wd?{EGrtHHeAGMI(Fn zt`BV2i2D10-j_%7vC;m{hQ9Pvj5Sb(jliT1UbwFOo9z5irDyEW2_a!Lg-b8<7v5UD zLa~j6oF)B{-i;c3lMB?di;#t{1c5RgM*mrPVqGwi^>$rLl5a{MOd0X7r!nN~L*Dnl z2V}ug9#jc$Z+u{gyEC${UxV!uE?A=HL|2(3H2IK4F>LRD<4m)`g%lM0I%hmoCm~X7 zJ=nq&3+6!!BZrDBf1+9jep3dcp^w;9l&zw#EiV&eC|N(3!Bz)ALXb! z`uvWg0xqpiv_%FRq@=kATw~&YoA#6R-0i#V+>QE6pbXb?{SV%il^ULc)cqiHM45GNz*LSl3tWr_6)qVr1Jd8--{KmxCWq}{xH z`EjY}1cImCaq=DNitDKT{-ba&8g{P~39y*N0uahkc>$U^96;^}@JC2O1G#bsBVjc2 zW)+7KCChCegI>}tVzKY=G|D7F)MLYG^&V@L zCclme%v{0yLaS2eysIPW8ZW`NeZX%eeFzPO=aXH4gFE^4@&lTriHHN%K33sX@Kzd{ zM|CM7CevqxH*R7(bq3>S;%nt`)L7PvA!1A|7G&v z32Ls{fnWBL%QmW=f(6g{ij``XKl51I9I0g=A^pa#?5R7p&8c_vhS(utu;D$R*|x7- z#KoSTi+CtOKQ*GabPxnwEQ_@z9xD&d5b@WkQ}1xQH0@8KxeH$CU6bD#d5Mzfw&fM0rVKk|0nm91+>7nxSBB*pHy=ldI- zqT=!=#WA#NuQBH9WsQRoRzA2q-r;efgZ{Dch#{c%ZtEI$PAmMpq*#yAwWzJZuUj5| z`l6ddU=-g!;aY+~%grkc5w#R+PVibNoLP33&RIbAlI6>UqN+X3CGl5cmxIWfyaY7B zw2d1V9%9C^S2ltC);&Oiop5JoSgie8tZX-1##M0a#$?*FvcL}LOAj%ri)~*??6IHM zk}u-c)0ffYZc11Fn+*Sb4KCFqdZn^Adb+QRCec{Yu2r#5S6V0ex;}=0kmP#V7+yQk z|H3ZLze_iKr%K|5-dIG7qOwRj!6#bgGH+I8T}32Mn@@Fx6-A!VC6v-_vD(S>>syNl z;Vwuz-@J9@I|F1|dm`jf25BV&)(R|E`|g_cpgC#p?Hv8Tv;Wl9v6|HAJK#hz#c-Y= zux?>GoyfwM5n&9wO&&`x4O538*E9F0K}i-*HJyzh*qZRj&tP*43B$Kw2h|uRn1rDx1W#&{wL5u56j&X4Y$n z&}STcW>$ineo4aYteOh!h9$=C(bHmaFsrF-yk&DyhA__N(A7O=jFwiKfJ}mWK!4Y1 ziL);zqF;`8W#%#7dg01pEt}&0ii~$!8S<8g+SV2Ku2u=B4ZA}_Y>KY=E{oLjG5@R# zTr#wHaLLRof0pXfT))9bPZ%VNHDG1fteE>gwvw5ER_zmR56J2_@0-mB2d;sS*NieD zWogtjH|+HCke>+w3i3BUW>DE35n-j}$~eMD@qXxWACMnHb7Dscy%W!79X3Qu=Ms52 z;gcQa`Dh{qN1@dlJHCg^5mkcSj9tP4=I88>5T5)%fNh0Q!4hI(9lQzr%#Q|{A8vp<1LTL z*F!h0_JM6jP-Qm>=cPel##g5!jUBd5k6`p@`kEt*%So@OY!b1R7!A!99p&|6&l(j_eecJEX9W5kxR{TS37BW@q z_Q5=J#pOL!BsV-2TG_Nxlpu_#Yyu#)M&`LJBw0$(xmNxL&V>FK6}?EkGtZ>=n2bn= z+3I3K&#_L-Kt18=l2X=ds!|yIbhc34uxagYyY9-+MA~sT+Prd1e4e|}Kk@cVy2{**t|^7qDe*<1eMqb_%Q|TdH5|t&SyJGIF3ILRdchAMvD4PuE*i@k zKe_y0HWCI=drs$>U2E39C8RrrpQ|~ref2+2#F#jeKsRF$XBJJ&ufAk-TxljxOflt$ zf*>yH1i*H{rYo2QW31^OV#%wSUZfj9%LbJQLqMVC$7!9tn(kazyH_RLeS1c zH!u(%AN=S=e=>>BGlm%adq_{(sd=rz4aQNJ9UaMQ(?)F5V2V@?{7n?H9Ii!w$qC!s z&aQDXrE8(!WvvmL74_k|&TS`m>pS3}Kjcy6V^yK1UHMn9A0UgH)u_==XV(2GtW`}i>}3mb%bhd$LB6m@RfXY=4MOrbQ~`% z>)kX9fd2p1Bhn4k{&a9COQf8FuIt5{oc`{@1Gh?jTNpmjl=Z_Ls$x@Nx;YGDV;wYd zP1@x?@TCCJn`D9`lNjIo`Zu*&1Z-D28GR!PO=qR|Z`bMR_2rZqC;88%Tb?^VXI0Xx zP@N?6CFy*Vs%wf@-j>;QkYhv=pG)9 ze7;7uv(LeSY9Ox3hv2{nw2gz$P}&Aa&EmNKG=M5VhNV9H;6K!g)BB_=nf3AT!iZ1_ z{70O9JX2|Xm$+NvAD_Nfo+h)*;6>X)dFqBttDErt*M@HBbOHa{_ z-m6#dy)_c-q08`<1HBN^)kj)cR+Pxu#Yw>>Wyby2>Az!df-m#=OFk|P_1=ixg&u!f zps3vXNmJf!#??+}lj%>e<;%Eg$}gOuw$av1Pc$dak1#(Plh5mJCmuBMz#YuuIS%Z* zv_6x;^y0O5>h0a=CMCG1STH=kr%1hS))IFwEnobSM`AWmEj)h|Q|hW}5^Etc&wDH_ zDMHsU-df%q---=f*Mg7yyxv*;b6XRMm+v0}&iaWuPzJa@{BHUDj)4hl`+gken~UC` zR7Lj~31pL4WGmYDeu^1Es7C?0CBmb!sMsYX>co`hXi*RtBfdx~4^KMoIixlbz}lHW ztUi_SX#}oK%TROc$ z_MvJ`0;Dbe^^f2!z4t^{k)UikEXx($!=&Z`nNw#x<|MA=RZsa6#y}T$H@lnE$rXVt zG7I(BaRP`EDEJ&GkMfeX5!`g=4+fa=31Z~MIU2^ti8WZwuNR>s zVGtcp1l`Ys`F*iy&&iG?L#=aKH88#%Eo#1|bjaeEd$tM=)`uNvFe+op?Ue?mhxL5( zp2d?_4cz@&TrW_@(X2kk(_9Ui4b9|2qeBfA_qd#Aw!()$Nm8}NYU1Oacb!1WsF_Cv zT%EajFUwMoQe_DYw6!Gve+LWi{)b?pNN1o7pruL){06Enp4qO^AsoMfo(R%Gt?{+=(7(T~V1p6_jL7t2SyVuv=4Onr5&cJJYdUtM6+|8yeG+tOm! zB#ht*4&Vk><)(WHtIkpDzX^r_j{Rb%;(!Y#p(Qs>DT8FdLzwDsE`IQef3gAU1ob+! zr_^NUAs0nKe^m-3erKJ>v8;rYsF^MK2Y8?NxhgT=0*{z&cRtKy^0jF1Z7$_J~ON3byL7(vw|A{bh1h+*T8iJloNrmxb7@{Sv38{VG3 zI-Y}b1PQBMHCOGO_YA9r?~Y8@QRLgMWQO^&$mR#~DgpA)*&>L3^MRZjt~}2+cZ6AF zT(VRKlbA9jdp0guOTz0xp`|OR^1Twwm#Q2R$%wU}%34%|4_`fpSz-bbCi9-YtqU`l zbQx@zqa3l|MtOHI0_x~&y#azz3H9{K5rDztuu&ygfZFC0ML(+8uyK2 zLdGs}A9qrw-dw_4L4BTvU%c5Uy*)dT#LYxZX`ZSncNk#n-$0?k9onI>B$k zkLq-G^8xJLmV7XO-fK4+B>g3dgTo0oQwEn2f9FDf&J-OS%AG#*_9^GR5UE&ZwMDP? z7~f773X%gx-GbCv^nk|TcNG*Q7ey+VGO`1Aoy-`dWoQ{;*F3tSS>rn{!=bVMcbBtE zz_7@z8Xyq5&7^Wh^c99s@uZZEJ!_P{2#IjP0W%M!=*dlfn~vA~=0l-%b(0FWXX`q` ztVn$AnDfSMi=*#uC=B7an^JxLo9q_12Vs?my>aX(Qb0Ar$H8pU{O*j{Kr}GPl%6(O z0viu(9wCexZF3&mVnenPUh3LH9-97w*(;2JhjDE@3m!9A_Hj(47w$WKB(;*<{Gpm2 zyXrQ01lhii2Dv5p<{lT z6>C0fQ?^529*Z!pp1zE2{kx2W+hNeh%fK~r^xU!!v;^?-LVwfZx`kxK_E2NRBbcq_ z0(!>vBVSXz=3UNubkqf~^c}C%oR@=U2~1LVQMJZpk;*g&#ZvnCiE*V>J%YLEH5##bko80*O`rhb3wlupKfZixv>NSjKhB6iS4e4_ zBe(vp{9(vuwcM}SZpU{iIV%K^<$mN@dXs^dD?;B6+Shc?53;;OrTq2eVC#ze8?42| z^9D#;Xmn4)`!J8WecT|rhu%B-YVMrkoScvrimI(Fb0jC0B>leUh6w0^y>^7dbb=nE z#<-kL=kQGTGdXM3)UPN;;h*!l99K%IM4(%E9YQxSAn zh%nGfb&0aJoWH*4iV4co8$OyDG}0Wj_Op(d>I3_~tA7n?c4N;>ywYG#{-^lxXh^J%y3D$#k!xLRb^&kgaXC9^nhMm#M7Et&MFB-xEVEIQsVSuc%PN7~v-k7Fz= zlc%~i0+N}kcWqwmo%RHC(#Pd(oHsfRc}4;`dDYbowo|@-<+h+B3Y!>|=b#fy$BHBn zMG|P4T`qBtd$`fy((mYDomu?_xZu8IS2A|Y7~w;p$8o}4Vtpi%n0923f6>0yEqame zRn8RO+P}@Q!dT9>`?#n^Sdi2QB;@tkcxkQhvx8_cx4ryPc81p3QqHW`tUX!;RhsPC zX%8LPXfIh_qs39?BZmQmRVqb@=$1ZZ%O9Qq|A=)D*BrQ(0*6AE0G%r1ROXYcP{V^o zPBS7g4T*~r$56%Gi>pm*`HqC}C{~Pfmug~OETLFDwU`HX#^YX0V!^r7$P|AS5jR8!MQMH>u_VsSpb z>~7j;V5>Zz&V+7;8Rq#};``Vr993zS|?1#dIpN0BXq1wv{go+IVqU|OtL+vv2h z4ItUX68A^kqw$`3I~~x;7ex{+R$duVyY72GcltRpE5{#bKh{&k+b}GbnUJh*@hsgS zfRS#<;v6DMNzH+A+*+~caacU|eeZVpRH2nn3`c|b)1OR;3fnLO=TLa<{$>tvIGgl# z&84a2lvq#XTZysZ)6+kRKiYxzHoBACh-fp2#-DG?>#vZ zoECs4KI5r@3TD~_dh~c>{D_vtDiz7Sa^3w%Z!%=~-l<)%HCFJ)$h{m(q>ZkjbgCA18Jidzu;fex6Qh2u zIg8$F-huewG^%dW$_a16%Y(uIcK6O4fQrAIoG9j$Q?7H9_-Asqt=G_OQhL^FkSTWV ztUNPx%-pZssl@-%O5_*Xf5?AA8L`p%2NBp*6FHoTI|Gv*FQWb`V%u1g+jr~bh;XS4 z0o2!w%`|O?-ocJ*t2Y9G%3B%=ZSYfqpX!5`w{QN6+d0gxVdw4fl_vOg+L?p_Sn?>K z{ag87-wRc4!b6RsY&krr)5AMT*@<;?c&R#IoNw}zmLK?|$YTefbjC|1T@_g?A z!Z^h#T-Du}UOHlje2Tun{95wh&|8(My!MD_xNE_Q^6!)8`_HwJCdgda_SyhdSpw?$ zx=a`>&x})Dbzsvo0jh)7$Wey1HiQ&vBTs5o&azzQ!CbJ(OrC zb7s?B3j)lGV)|5&Sm7<+upasQP=U7S-_09o8}t_Fc0Qchlh67%xY;p{kL|$^fPs(X zmcDODkA#cAqT6ccnGM#XTC~*paX`pl!$j3pc&P@uE(NfwjN7pD|MNY{*r2%mNAtLh z|01OMW0ycX6)MZ4#>p@;ZnTp>kQ|*(r}AWrPc3O(LpH_KmDDYO_G(co50ga=H-x$G z?C0SI-=w>#wS#J-sj^XndY6?&+_!V6!3GUdG&wJ2qCh2G&WG7bUV^`ErviAVXM__D*Wf(iQK zV0|veWd-_$Pd6YIEihUk2q7L!-Lj|SG)3!3*k87A(Ud%LaO-1g*{m~{FMDTy_y?!X zYzp$1tzs`4=Y&^soi&x`N^1rBe&ke3j6RN>-4`>@)>n9{QR<*zpkt7xHyRwN^fbOsXtIdhUP2sqF(`bc^-EEFvb( za@N1`%X;Nbuy&olNc26EH;k7P?z9pLc~m=UOp3$3r80!5fdh)ph@Y5QE_jn)K4G;~ z0dvBm4d%)azoVSSWS3#67E|Aot?qjd+Z%!JO$gQPU5U=Gm=zmyp765eH-Oa9Gx_oA z0$H&JhN$etz!{t@|``2%6%8D5? z_Dr~AWHDwtP9ip+_W1Vy>3)cGt1<=3bYJ5J7kmGX4ICn6HcZ42V@v`v%$^kv6BFFW zk}XC2sC#|N*(>2Ae?&IzPE3lwM28M?44vq;w}eWD!=iX%#4b`fkFzpDb0#!Gm>@n; zPfknscdC~M_Z3L z{oUO9DA)So(Y|Cc8k(SkwJ^SiZhWBM_&8vol!EP!UlD6ozTO(MhNebT> zE~&##dK+2eYo8r(;i8W>S4TkSl8d*1Hy@Pt!cNwE*E5js(#f}(orX4Q?Lis1>vta- zt95f|HE$`uK<0*4J89@pd?-{ycuC75((ei(O8fqj>35 z%V==gR^tXBVDRuJGGT>r{1v+T@4z_6)0T8-tf@fq6T7&yb?~0cxaX4f#GrH6?UU~p z2$8d5byvU6X7Sm}10rg1z72vj=#y1NBxQ>u_nbY?%U|=d;ICVtXe@`Q41;H7P%`PZ z?uY&m+yq1^bbM#VG>fj9(uaKb6RD%C|GH?ns>5XD>b14ZkNX@}Ka8h+oN7ra)!Z|Y z57)%TAE?``ys+J@&BRE+H_$26#QWiII! z2|8_lD^sYWC}p}?K91z^QmB=4B)7nk4{|`Q1O47mj4xEQRtJ6PG9ZR%N&#$jCfZ?B zM-THHe?u)$Jc*gz8HnW^_jN(2%?ZK}h~_*0F#i&`>|ve0z@@9+OtOEKvWHHLOnLINE>);A(ffh>b7 z0Q5WzIV0h0Ex~SeN30QZ6LS7fI2~BdwhIH&66vvFo7xDoUcc|vi&0+=-+v@wP_*_2 zbxa%L$%pJV%_CA{`QNdLJzZ*4_`EJ(d{8_#SaiH&L=0jY1Vpt=|E*=LeT@|UP z6;-fzcD33hUmjKUL)Jwb6{n+*I<}DhSU+(Bu99PzEU+~s)VV6ByU^;FIqe@2#+>v2 z26dzV19iu0;Q$6Q|7TP;TREVrZHN!;Sy)E<>Rp{#lW3%tDhJ5e8GzRcu?gqjv`UId z4LBdXR~DB!GO82w!JNS+@jH9x)^R1=V;)-CdPP_v*l;cLH*qNY^nU@}?z7tB3sQ03 zjrqurM}Az$#W-Xq@Np8yg!%Jav?5x7_mhR6;N~2>N^W&NC;Lqhqc;?^R<(tAZP_^- z2bUy}r7kulX$ihAWu53wSMi!q`4jT<(|?i90Lykhu#?mn%4|HKmaB1{PmhEhe$sP? zpA1()Wn>VQR%oYh-UZAR`QM3pTy+#LWOnG5L(hymSO zduX@ItvTtfh{+RIQjZ}$Nj$IkaET3>)LlHSI@4~}KDQ*R+&u8o>+jqWEJ^UWYOf3{ zo|o!;q|7Q=W%LDL$H%Ns3yhBR(bTTflY##`$nALq+8O;HliX_z{~shbcBw4k+NZ8; zd3nP@%!kIU=8oZzZoK{WtPtw_=Rq*CLMIk&wEbYd&Q3`T+o4CWy!uKgsI;ZH=8=SB z4$ci(GE6i}vQa-!lKQ-#G3m0;5qMjvXnpAb6nYuV8gg~#Bla8}8E;7{%%;&@MalQx z;mdz2;$*+{67n4pHUf>@`xr3oO-gRz|G~u%jalapw{1;Mhx>2wwgBpO?r`vtPIi0$ z4G3p(p&8h0cS$l;azseeuBSUntzaF=I;==r$$yj!1!s08@*$h+Iby(P9v(}|+|BMU ztF0kGE^zDic?cQbsXfz#?5R=8n;xBTS;T3sao!LGhu+9nbe6HZsC?ri3AZiI?lv57 zx+u>Mb9xH#Kps=uD_I-ZA|!h5>`Jr$cd)c!LFG9#^g`1lRa**2MH<{x`1*)8Z!;PC zl_Mr7#M!jCAu;{q>gfiN9&5$g%I8`gF=9FUR1%5R58uP(@eLqM*VjBD9IkfF>+JzQ zZmPB&GN_jAj|tatvpSf%&-z*x9lG;gCwRg=;jHy$4@x{L+TBR8%0$&}_HxyWMN=@{ znYLd$IVsTN&tGshlD+Yp9dE!3P72-Db-^A=Lmp82h@aBg_I-2X4b!ubz>R=gt>IXa z^uE14s@VSt@@{~;`Seql0>3s6vVrk%u>Q)^6S6@oE~mx*OnFB&pZMJn5^>Ky0thDE zo0R3f=fQicm?4F=P;0p9i8x5p1H+eLx#G+66K&i(EkyAEZVH!f&v5q_S7f>;Y){Pc z%(Mq-4%4@K1wlTppj7=Y3scSd4FF-tF-;ADFQlVqVitJz5Ld^m^}BDk5BGW8RZ(oNTYE{%8yWDs*6wE;iZSt9WIyHo z>={`&kC-=s*;dh2hc9=J<>p&>^=t%L>g!_TG5Iw@zI%OC9y=Gdylm9)mSS8$ACIEH z_ET$fHpG7`K%jM(9>~GUfGycJtL-HUcB!jU8iUt%)AD`az#Oe?w(axncB8(Jr!dgn zfmz$;rSfDZ;?RfkiD%h-Z)BDmG!MHHxe+??oN7IyUXEOuypr8`!lX|3Wy`COaf9t* zf>7K2oTt1)8LYbl=Cwq)8?)2~)N17^n#RT#uOswrrTTfT&OgcH*fv40=GoC<3p&SM zffSo83;EJT-y}B*p@DAHHGMT3ZIMM?&!t-!R~q$!O(XIXbq#2yUoND*KH)asW}T=T zW#oi!yKqw-Ji0f=@TZ(>a-n!Q4s@ zFJqE7+y->h0t9~3jd$r<>wP)6i2dkrd*^mAu4wIt!*OzPKFzow+t2cB3{tf5o*Q6x8bI^G;r|;q-uOjr_}f3+IH%}; z=f)TQ;l}SdqJ`~xTcH9$BaacLZ69ogw*O9!4@mr<$#HQjZJPYYY>P;d)$Y6*tEAF5 zKTd#w?eG~!O9q$xC|r0=vEd3bBzDXzsz>u4l>`pA{=k$T*JCaPWM15$Fu4U)i`frh zK;2=M*h@|)jG-W;vw;-9oeN!fs~26b#x8^^*H=+f&K4Nw1g4ALU8akxPf=6UUdtQ}*c$w#C~@MasrNTcbG7^uRuuP{X;|XQ<>YddhE* z<_ab)vQM0^r@yU8sT8P~jS3}}Wv8naP-S>!n=W|N`rmOC4q>tt=d_SOoc^)zpFgGL)VQg+#eu}>}FuwU6ii*L& zq>AUn_`lk__i(2BHUQxDR8w-Qb5d zl%ht+A+tFjGD3!ImB%vY!xl4V?^N&MdH#C;eXr~N=XZVo{r#@%dtdkW{(V39Jvr-T z0Y{;dMT3e~#ki&CJTT3AE*08nLdB{!w4E4c>~2}@FH>X9)(%0iD%t=eio>ma4pc}W z*SE6}9>`3f+N#O`>m$r(n-9uxSWcKZ>GY>e~P+jkKN0s4T8m%85 z*dP?Dgpr;}#QCaKHIZlNag5l(MW1D?BiLi?;QG`%v}{kWX8SWYTyAk+hNw;K%dt_r zxXHqXdLviZP6Wh&bUkl2qabA;*jf$CQ_E@1{6=Hd*%r zrI@rKL`xy4jjdqr-T}M2sK%?#iaj!0B7)4Mzr~4u%GNn@=s^$E^@huivb(h~T_@RkSj{VI)Tk0r5)Caf3g5-+7Ta;75M5CEqb1 z5%XeK-df2HsO-gX6_(PjX4Ol>vlJf^)G{JQ;rmgNB4i#AuA+`^kPlyge{U_3{OU~SnIO6j@4y5+|Xg^c3)IM<#l=u;kYU_ z%ri_%LsjMXnWqYS_$^O5Yh*M?5+E;4PqI*B_9IIV0CNo9-}mLZl`@NejUE()dBhvX zcN4oa+^;uSzPs8~e2F5hBCqUl`AtD|79}8Km>-@Be+juZ*F`IkT%q<3%HI;}jXdzo zH*4WBOdH|AUsNuR`>*+N}@ z7$r#?{Q`Z+M0ajP9;7-V;xaS=-bEUG`_C{a^hb-snecU8U@LKr&~dO%t4LvCO38ke`Sz7x@6s%EU*XpftNRD_c57n@i9ng3+~QOCZ>Lb>n@!C-1yDhhb`Q=kWBZPajqV}y8?Etye2Mw zEZs{t(pY6(fjs_Y+p9lS*3)LRJIL;%IhVN`50K6R?`&e?`z05&3Kf}9L0h_B%{pz3 zmKQ4jWOk{+Qik4J{QS(Hf~{Xo`vw`7fV7;T1xy`#!k6IQUoy6NCIHl;v&eN{K!4XZ z8qbC#Hgu4uT$-4ih!rMy?lurJeZewtBR`M%1JdkV5w zl$I-!na^^1@?{4hp@ejCT|w825_mG_e2Vq3qK0HxSr_N+Xpr&bkqIY9E``lBP9TTH zby|I|m4sgP_#@w0x9{7Bzu;q#iTI6MIN<9jn(Wgxkhnb5WL8pgqNf?RRC*qSAuMJs z8comH%Df(v`ao3StiMjbq<)MPm7YF(z}`PMh!8)hxD~*=lqY2U?Fx9J*GdF&Ip_rD zoz_u=uXrOzjFIf<>nJCwX2%7WL^D>6#ZUrkuMw~L^nn1% ziy(eV(nk(T-%=wqOV}hY4AkfsM|25z$VO?CLw9<{VoabY-v%b|aUCb66UBZ$?bUI( zy4ZZpfvk@>a%a5Vp#RaG!@QoOB8%~U!R0sW4{0%I;O)kE{ifZbH1LG@b8fj|;TzI` z4D`8#h6}!LF<7YyhUU<3SS42g9f!9qt}X5~3N4h_rBnLa#dXk_Ol^>#ePna9wV`{I zy~0^()ebQtu0oBAf!y4}{WAyXd+v>JXGtJu9BH$wj_p-Z9 z@+X!x+#`f-h2=bmjH8v+1X42%-IXRDmTO^V+a4GpG-qOfnGr-Y!wm^wXwWsgkPUGJ zf+v#B|He!@r{WZDkhY5XnNPD9v#GsAS+|TXk)8(xkGAEgWQH5yBl>XDn`U6PIINR|#mNQxxUD0Zi5gYroxekKixgE(T2e%+Xq62rrgp5k~V0}^xS z-c@4pyeYDQ&|fw!sQkqB`d%9a=;3V($NuJk_fMfd{-V|HAODylzjaXR659Y-=2z?X z-2r2Te>mV_EC0Vc-~;=AIAC?LQ}!)-8#_6yv~n4*H1j6HT=1UmY1rZwXIrae&6aGa zqxXG>WY%JH#HoPzR-oqs(34})DKV^|*2UjIDKEhEnx)Z7jsE>koL`2gt6=j{TaM## zAZL325DQ@${re3T6^vjE_WybhkFCFLPPtNz!_p*r25ebZU-F8An*H}lAL4N<)RbaY#tJH>)ni-;K9{$ topKFrequent(int[] nums, int k) { + //定义一个整型列表的数组bucket,长度是数组nums长度+1 + //下面会解释为什么bucket的长度要在nums.length的基础上加1 + List[] bucket = new List[nums.length + 1]; + //定义一个map用于存储数组中元素出现的频率 + Map frequencyMap = new HashMap<>(); + // 遍历数组nums + for (int n : nums) { + //将每个数字出现的频率存入map + //frequencyMap.getOrDefault(n, 0)表示通过当前整数n,从frequencyMap中value,如果value为空就使用默认值0 + //frequencyMap.getOrDefault(n, 0)+1表示当前元素n每出现一次,在现有频率的基础上加1 + frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); + } + + //遍历frequencyMap的所有键值 + //这个键值包括了nums中的所有元素,其中重复的元素都合并为一个值 + for (int key : frequencyMap.keySet()) { + //获取当前键值key对应的频率frequency + int frequency = frequencyMap.get(key); + //获取bucket中frequency对应位置的分桶 + if (bucket[frequency] == null) { + //如果当前位置的分桶为空,新建一个ArrayList对象 + bucket[frequency] = new ArrayList<>(); + } + // 向当前分桶添加Map中的key值 + // key对应nums中的元素,且经过map过滤,key是去重的 + // frequency对应key在nums中出现的频率 + // 如key=2,frequency=3,即nums中的元素2,总共出现了3次 + // 在bucket[frequency]这个分桶中,保存了所有频率为frequency的key值 + bucket[frequency].add(key); + } + + //新建一个整型列表res用于存储返回结果 + List res = new ArrayList<>(); + + //从大往小遍历bucket + //res.size() < k限制了出现频率前k高的元素 + for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { + //从bucket的当前位置pos取出分桶 + if (bucket[pos] != null) { + //bucket[pos]得到一个由nums中所有频率为pos的元素组成的列表 + //res.addAll将列表中的所有元素加入res中 + res.addAll(bucket[pos]); + } + } + //返回最终结果 + return res; + } +``` + +**复杂度分析** + +时间复杂度:O(n), +方法内的三个循环都在n的复杂度内 + +空间复杂度:O(n), +建立了一个桶,占用空间为n+1 + +**参考资料** + +* 网友高效答案: +[https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort](https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort) diff --git a/leetcode/347-TopKFrequentElements/bigablecat.md b/leetcode/347-TopKFrequentElements/bigablecat.md new file mode 100644 index 0000000..85b087e --- /dev/null +++ b/leetcode/347-TopKFrequentElements/bigablecat.md @@ -0,0 +1,19 @@ +**前K个高频元素** +--- +[https://leetcode-cn.com/problems/top-k-frequent-elements/](https://leetcode-cn.com/problems/top-k-frequent-elements/) + +给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 + +**示例 1:** + +``` +输入: nums = [1,1,1,2,2,3], k = 2 +输出: [1,2] +``` + +**示例 2:** + +``` +输入: nums = [1], k = 1 +输出: [1] +``` diff --git a/leetcode/455-AssignCookies/README.md b/leetcode/455-AssignCookies/README.md new file mode 100644 index 0000000..d7e4e77 --- /dev/null +++ b/leetcode/455-AssignCookies/README.md @@ -0,0 +1,36 @@ +**455. 分发饼干** +--- +[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) + +假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 + +**注意:** + +你可以假设胃口值为正。 +一个小朋友最多只能拥有一块饼干。 + +**示例 1:** + +``` +输入: [1,2,3], [1,1] + +输出: 1 + +解释: +你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 +虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 +所以你应该输出1。 +``` + +**示例 2:** + +``` +输入: [1,2], [1,2,3] + +输出: 2 + +解释: +你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 +你拥有的饼干数量和尺寸都足以让所有孩子满足。 +所以你应该输出2. +``` From 79ebe6092dbf3550b78bd5da3bde936c14a60fb8 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 24 Mar 2019 21:51:30 +0800 Subject: [PATCH 18/66] remove unnecessary directory --- _site/README.md | 2156 ----------------- _site/contribute.md | 105 - _site/leetcode/001-twoSum/hatrick.md | 39 - _site/leetcode/001-twoSum/official.md | 4 - _site/leetcode/001-twoSum/woody.md | 53 - _site/leetcode/002-addTwoNumber/monkey.md | 47 - .../monkey.md | 43 - .../hatrick.md | 60 - .../official.md | 3 - _site/leetcode/015-threeSum/hatrick.md | 52 - _site/leetcode/015-threeSum/official.md | 4 - .../leetcode/020-validParentheses/official.md | 4 - .../leetcode/024-swapNodesInPairs/official.md | 4 - .../025-reverseNodesInKGroup/bigablecat.md | 75 - .../025-reverseNodesInKGroup/official.md | 4 - .../032-LongestValidParentheses/official.md | 3 - _site/leetcode/036-ValidSudoku/SpecialYang.md | 113 - _site/leetcode/036-ValidSudoku/official.md | 4 - .../leetcode/037-SudokuSolver/SpecialYang.md | 97 - _site/leetcode/037-SudokuSolver/official.md | 4 - _site/leetcode/050-powxN/bigablecat.md | 57 - _site/leetcode/051-NQueens/melody-l.md | 94 - _site/leetcode/051-NQueens/official.md | 4 - _site/leetcode/052-N-QueensII/hatrick.md | 61 - _site/leetcode/052-N-QueensII/official.md | 4 - .../leetcode/053-maximumSubarray/BambooYH.md | 59 - .../leetcode/053-maximumSubarray/official.md | 3 - _site/leetcode/062-UniquePaths/BambooYH.md | 64 - _site/leetcode/062-UniquePaths/official.md | 3 - .../leetcode/063-UniquePathsII/SpecialYang.md | 115 - _site/leetcode/063-UniquePathsII/official.md | 3 - _site/leetcode/064-minimumPathSum/melody-l.md | 54 - _site/leetcode/064-minimumPathSum/official.md | 3 - _site/leetcode/069-SqrtX/official.md | 4 - _site/leetcode/070-ClimbingStairs/melody-l.md | 113 - _site/leetcode/070-ClimbingStairs/official.md | 3 - _site/leetcode/072-EditDistance/official.md | 3 - _site/leetcode/075-SortColors/bigablecat.md | 67 - _site/leetcode/075-SortColors/official.md | 3 - .../leetcode/085-MaximalRectangle/passself.md | 189 -- _site/leetcode/087-ScrambleString/official.md | 3 - _site/leetcode/091-DecodeWays/melody-l.md | 73 - _site/leetcode/091-DecodeWays/official.md | 3 - .../095-UniqueBinarySearchTreesII/melody-l.md | 82 - .../095-UniqueBinarySearchTreesII/official.md | 3 - .../096-uniqueBinarySearchTrees/official.md | 3 - .../097-InterleavingString/official.md | 3 - .../098-validateBinarySearchTree/BambooYH.md | 47 - .../SpecialYang.md | 121 - .../hatrick.md | 42 - .../official.md | 4 - .../zengdiqing1994.md | 42 - .../104-MaximumDepthOfBinaryTree/melody-l.md | 100 - .../104-MaximumDepthOfBinaryTree/official.md | 4 - .../115-DistinctSubsequences/official.md | 4 - _site/leetcode/120-Triangle/melody-l.md | 59 - _site/leetcode/120-Triangle/official.md | 4 - .../bigablecat.md | 101 - .../121-bestTimeToBuyAndSellStock/official.md | 4 - .../SpecialYang.md | 52 - .../bigablecat.md | 141 -- .../SpecialYang.md | 106 - .../official.md | 4 - .../131-PalindromePartitioning/official.md | 3 - .../132-PalindromePartitioningII/official.md | 3 - _site/leetcode/139-WordBreak/official.md | 3 - _site/leetcode/140-WordBreakII/official.md | 3 - .../leetcode/141-linkedListCycle/official.md | 62 - .../142-linkedListCycleII/bigablecat.md | 3 - .../142-linkedListCycleII/official.md | 3 - _site/leetcode/146-lruCache/hatrick.md | 98 - _site/leetcode/146-lruCache/official.md | 3 - .../152-MaximumProductSubarray/SpecialYang.md | 43 - .../152-MaximumProductSubarray/official.md | 4 - _site/leetcode/167-TwoSumII/bigablecat.md | 75 - _site/leetcode/167-TwoSumII/official.md | 4 - _site/leetcode/169-majorityElement/README.md | 21 - .../169-majorityElement/SpecialYang.md | 109 - .../169-majorityElement/bigablecat.md | 153 -- _site/leetcode/174-DungeonGame/passself.md | 81 - .../BambooYH.md | 44 - .../official.md | 4 - .../leetcode/191-NumberOf1Bits/bigablecat.md | 102 - _site/leetcode/198-houseRobber/hatrick.md | 49 - _site/leetcode/198-houseRobber/official.md | 3 - .../leetcode/200-numberOfIslands/BambooYH.md | 105 - .../leetcode/200-numberOfIslands/official.md | 3 - .../206-reverseLinkedList/official.md | 4 - .../208-implementTriePrefixTree/official.md | 4 - _site/leetcode/212-wordSearchII/official.md | 4 - .../leetcode/213-HouseRobberII/SpecialYang.md | 59 - _site/leetcode/213-HouseRobberII/official.md | 3 - .../BambooYH.md | 147 -- .../bigablecat.md | 142 -- _site/leetcode/221-MaximalSquare/official.md | 3 - .../225-implementStackUsingQueues/hatrick.md | 66 - .../225-implementStackUsingQueues/official.md | 4 - _site/leetcode/231-PowerOfTwo/hatrick.md | 44 - _site/leetcode/231-PowerOfTwo/official.md | 4 - .../232-implementQueueUsingStacks/hatrick.md | 80 - .../232-implementQueueUsingStacks/official.md | 4 - .../BambooYH.md | 91 - .../239-slidingWindowMaximum/official.md | 4 - _site/leetcode/242-ValidAnagram/bigablecat.md | 92 - _site/leetcode/260-SingleNumberIII/README.md | 17 - _site/leetcode/264-UglyNumberII/bigablecat.md | 86 - _site/leetcode/264-UglyNumberII/official.md | 3 - _site/leetcode/279-PerfectSquares/official.md | 3 - .../279-PerfectSquares/zengdiqing1994.md | 59 - .../295-FindMedianFromDataStream/BambooYH.md | 71 - .../melody-l.md | 87 - .../official.md | 3 - .../303-rangeSumQueryImmutable/BambooYH.md | 35 - .../303-rangeSumQueryImmutable/official.md | 3 - .../304-RangeSumQuery2DImmutable/official.md | 3 - .../304-RangeSumQuery2DImmutable/woody.md | 92 - .../bigablecat.md | 85 - _site/leetcode/312-BurstBalloons/melody-l.md | 57 - _site/leetcode/312-BurstBalloons/official.md | 3 - .../321-CreateMaximumNumber/README.md | 48 - _site/leetcode/322-CoinChange/official.md | 3 - _site/leetcode/338-CountingBits/bigablecat.md | 104 - _site/leetcode/343-IntegerBreak/hatrick.md | 38 - _site/leetcode/343-IntegerBreak/official.md | 3 - .../354-RussianDollEnvelopes/official.md | 3 - .../official.md | 3 - .../official.md | 4 - .../367-ValidPerfectSquare/official.md | 4 - .../368-LargestDivisibleSubset/passself.md | 99 - .../374-GuessNumberHigherOrLower/official.md | 3 - .../official.md | 3 - .../376-WiggleSubsequence/melody-l.md | 61 - .../376-WiggleSubsequence/official.md | 3 - .../leetcode/377-CombinationSumIV/official.md | 3 - .../README.md | 22 - _site/leetcode/392-IsSubsequence/official.md | 3 - .../392-IsSubsequence/zengdiqing1994.md | 90 - _site/leetcode/403-FrogJump/README.md | 47 - _site/leetcode/403-FrogJump/official.md | 47 - .../leetcode/409-LongestPalindrome/README.md | 23 - .../410-SplitArrayLargestSum/hatrick.md | 55 - .../410-SplitArrayLargestSum/official.md | 3 - .../leetcode/413-arithmeticSlices/official.md | 3 - .../416-PartitionEqualSubsetSum/bigablecat.md | 104 - .../416-PartitionEqualSubsetSum/official.md | 3 - .../official.md | 3 - .../leetcode/455-AssignCookies/SpecialYang.md | 34 - .../leetcode/455-AssignCookies/bigablecat.md | 56 - .../README.md | 20 - _site/leetcode/464-CanIWin/official.md | 3 - .../passself.md | 85 - .../472-ConcatenatedWords/official.md | 3 - _site/leetcode/474-OnesAndZeroes/hatrick.md | 47 - _site/leetcode/474-OnesAndZeroes/official.md | 3 - .../leetcode/486-PredictTheWinner/official.md | 3 - _site/leetcode/494-TargetSum/official.md | 3 - _site/leetcode/504-Base7/README.md | 21 - _site/leetcode/514-FreedomTrail/hatrick.md | 49 - _site/leetcode/514-FreedomTrail/official.md | 3 - .../passself.md | 42 - .../517-SuperWashingMachines/official.md | 3 - .../523-ContinuousSubarraySum/hatrick.md | 90 - .../523-ContinuousSubarraySum/official.md | 3 - _site/leetcode/546-RemoveBoxes/passself.md | 120 - .../leetcode/547-friendCircles/bigablecat.md | 126 - .../551-StudentAttendanceRecordI/official.md | 3 - .../552-StudentAttendanceRecordII/official.md | 3 - .../576-OutOfBoundaryPaths/official.md | 3 - .../576-OutOfBoundaryPaths/zengdiqing1994.md | 66 - .../629-KInversePairsArray/official.md | 3 - .../629-KInversePairsArray/zengdiqing1994.md | 117 - .../leetcode/638-ShoppingOffers/bigablecat.md | 134 - .../SpecialYang.md | 75 - .../646-MaximumLengthOfPairChain/official.md | 3 - .../647-PalindromicSubstrings/bigablecat.md | 198 -- .../647-PalindromicSubstrings/official.md | 3 - _site/leetcode/650-2KeysKeyboard/mahone.md | 34 - _site/leetcode/650-2KeysKeyboard/official.md | 3 - _site/leetcode/664-StrangePrinter/official.md | 3 - .../bigablecat.md | 95 - .../official.md | 3 - .../passself.md | 70 - .../bigablecat.md | 130 - .../official.md | 3 - .../691-StickersToSpellWord/official.md | 3 - .../692-TopKFrequentWords/bigablecat.md | 66 - .../hatrick.md | 54 - .../official.md | 3 - .../BambooYH.md | 47 - .../BambooYH.md | 43 - .../official.md | 3 - .../hatrick.md | 57 - .../official.md | 3 - .../mahone.md | 35 - .../official.md | 3 - .../official.md | 3 - _site/leetcode/740-DeleteAndEarn/melody-l.md | 68 - _site/leetcode/740-DeleteAndEarn/official.md | 3 - .../746-minCostClimbingStairs/bigablecat.md | 61 - .../746-minCostClimbingStairs/official.md | 3 - .../764-LargestPlusSign/SpecialYang.md | 145 -- .../leetcode/764-LargestPlusSign/official.md | 3 - .../official.md | 3 - .../zengdiqing1994.md | 84 - .../790-DominoAndTrominoTiling/mahone.md | 44 - .../790-DominoAndTrominoTiling/official.md | 3 - .../official.md | 3 - _site/leetcode/808-SoupServings/official.md | 3 - .../813-LargestSumOfAverages/melody-l.md | 59 - .../813-LargestSumOfAverages/official.md | 3 - _site/leetcode/837-New21Game/official.md | 3 - _site/leetcode/838-PushDominoes/official.md | 3 - .../844-BackspaceStringCompare/BambooYH.md | 89 - .../844-BackspaceStringCompare/bigablecat.md | 64 - .../bigablecat.md | 88 - .../official.md | 3 - _site/leetcode/860-lemonadeChange/BambooYH.md | 46 - .../860-lemonadeChange/SpecialYang.md | 79 - _site/leetcode/860-lemonadeChange/official.md | 4 - .../official.md | 3 - .../874-walkingRobotSimulation/SpecialYang.md | 111 - .../874-walkingRobotSimulation/hatrick.md | 57 - .../874-walkingRobotSimulation/official.md | 4 - .../leetcode/875-KokoEatingBananas/sandao.md | 45 - _site/leetcode/877-stoneGame/melody-l.md | 72 - _site/leetcode/877-stoneGame/official.md | 3 - .../898-BitwiseORsOfSubarrays/official.md | 3 - .../official.md | 3 - .../zengdiqing1994.md | 57 - .../920-NumberOfMusicPlaylists/passself.md | 48 - .../931-MinimumFallingPathSum/hatrick.md | 53 - .../931-MinimumFallingPathSum/official.md | 3 - _site/leetcode/935-KnightDialer/official.md | 3 - .../940-DistinctSubsequencesII/official.md | 4 - .../official.md | 3 - .../954-ArrayOfDoubledPairs/bigablecat.md | 258 -- .../leetcode/956-TallestBillboard/official.md | 3 - .../official.md | 3 - .../bigablecat.md | 89 - .../official.md | 3 - .../968-BinaryTreeCameras/official.md | 3 - .../968-BinaryTreeCameras/zengdiqing1994.md | 55 - _site/leetcode/975-OddEvenJump/official.md | 3 - .../official.md | 3 - _site/leetcode/sample/concise.md | 40 - _site/leetcode/sample/concise.png | Bin 85605 -> 0 bytes _site/leetcode/sample/full.md | 72 - _site/leetcode/sample/full.png | Bin 166160 -> 0 bytes .../\345\211\221\346\214\207Offer/README.md" | 8 - 249 files changed, 11772 deletions(-) delete mode 100644 _site/README.md delete mode 100644 _site/contribute.md delete mode 100644 _site/leetcode/001-twoSum/hatrick.md delete mode 100644 _site/leetcode/001-twoSum/official.md delete mode 100644 _site/leetcode/001-twoSum/woody.md delete mode 100644 _site/leetcode/002-addTwoNumber/monkey.md delete mode 100644 _site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md delete mode 100644 _site/leetcode/005-LongestPalindromicSubstring/hatrick.md delete mode 100644 _site/leetcode/005-LongestPalindromicSubstring/official.md delete mode 100644 _site/leetcode/015-threeSum/hatrick.md delete mode 100644 _site/leetcode/015-threeSum/official.md delete mode 100644 _site/leetcode/020-validParentheses/official.md delete mode 100644 _site/leetcode/024-swapNodesInPairs/official.md delete mode 100644 _site/leetcode/025-reverseNodesInKGroup/bigablecat.md delete mode 100644 _site/leetcode/025-reverseNodesInKGroup/official.md delete mode 100644 _site/leetcode/032-LongestValidParentheses/official.md delete mode 100644 _site/leetcode/036-ValidSudoku/SpecialYang.md delete mode 100644 _site/leetcode/036-ValidSudoku/official.md delete mode 100644 _site/leetcode/037-SudokuSolver/SpecialYang.md delete mode 100644 _site/leetcode/037-SudokuSolver/official.md delete mode 100644 _site/leetcode/050-powxN/bigablecat.md delete mode 100644 _site/leetcode/051-NQueens/melody-l.md delete mode 100644 _site/leetcode/051-NQueens/official.md delete mode 100644 _site/leetcode/052-N-QueensII/hatrick.md delete mode 100644 _site/leetcode/052-N-QueensII/official.md delete mode 100644 _site/leetcode/053-maximumSubarray/BambooYH.md delete mode 100644 _site/leetcode/053-maximumSubarray/official.md delete mode 100644 _site/leetcode/062-UniquePaths/BambooYH.md delete mode 100644 _site/leetcode/062-UniquePaths/official.md delete mode 100644 _site/leetcode/063-UniquePathsII/SpecialYang.md delete mode 100644 _site/leetcode/063-UniquePathsII/official.md delete mode 100644 _site/leetcode/064-minimumPathSum/melody-l.md delete mode 100644 _site/leetcode/064-minimumPathSum/official.md delete mode 100644 _site/leetcode/069-SqrtX/official.md delete mode 100644 _site/leetcode/070-ClimbingStairs/melody-l.md delete mode 100644 _site/leetcode/070-ClimbingStairs/official.md delete mode 100644 _site/leetcode/072-EditDistance/official.md delete mode 100644 _site/leetcode/075-SortColors/bigablecat.md delete mode 100644 _site/leetcode/075-SortColors/official.md delete mode 100644 _site/leetcode/085-MaximalRectangle/passself.md delete mode 100644 _site/leetcode/087-ScrambleString/official.md delete mode 100644 _site/leetcode/091-DecodeWays/melody-l.md delete mode 100644 _site/leetcode/091-DecodeWays/official.md delete mode 100644 _site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md delete mode 100644 _site/leetcode/095-UniqueBinarySearchTreesII/official.md delete mode 100644 _site/leetcode/096-uniqueBinarySearchTrees/official.md delete mode 100644 _site/leetcode/097-InterleavingString/official.md delete mode 100644 _site/leetcode/098-validateBinarySearchTree/BambooYH.md delete mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md delete mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md delete mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md delete mode 100644 _site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md delete mode 100644 _site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md delete mode 100644 _site/leetcode/104-MaximumDepthOfBinaryTree/official.md delete mode 100644 _site/leetcode/115-DistinctSubsequences/official.md delete mode 100644 _site/leetcode/120-Triangle/melody-l.md delete mode 100644 _site/leetcode/120-Triangle/official.md delete mode 100644 _site/leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md delete mode 100644 _site/leetcode/121-bestTimeToBuyAndSellStock/official.md delete mode 100644 _site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md delete mode 100644 _site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md delete mode 100644 _site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md delete mode 100644 _site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md delete mode 100644 _site/leetcode/131-PalindromePartitioning/official.md delete mode 100644 _site/leetcode/132-PalindromePartitioningII/official.md delete mode 100644 _site/leetcode/139-WordBreak/official.md delete mode 100644 _site/leetcode/140-WordBreakII/official.md delete mode 100644 _site/leetcode/141-linkedListCycle/official.md delete mode 100644 _site/leetcode/142-linkedListCycleII/bigablecat.md delete mode 100644 _site/leetcode/142-linkedListCycleII/official.md delete mode 100644 _site/leetcode/146-lruCache/hatrick.md delete mode 100644 _site/leetcode/146-lruCache/official.md delete mode 100644 _site/leetcode/152-MaximumProductSubarray/SpecialYang.md delete mode 100644 _site/leetcode/152-MaximumProductSubarray/official.md delete mode 100644 _site/leetcode/167-TwoSumII/bigablecat.md delete mode 100644 _site/leetcode/167-TwoSumII/official.md delete mode 100644 _site/leetcode/169-majorityElement/README.md delete mode 100644 _site/leetcode/169-majorityElement/SpecialYang.md delete mode 100644 _site/leetcode/169-majorityElement/bigablecat.md delete mode 100644 _site/leetcode/174-DungeonGame/passself.md delete mode 100644 _site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md delete mode 100644 _site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md delete mode 100644 _site/leetcode/191-NumberOf1Bits/bigablecat.md delete mode 100644 _site/leetcode/198-houseRobber/hatrick.md delete mode 100644 _site/leetcode/198-houseRobber/official.md delete mode 100644 _site/leetcode/200-numberOfIslands/BambooYH.md delete mode 100644 _site/leetcode/200-numberOfIslands/official.md delete mode 100644 _site/leetcode/206-reverseLinkedList/official.md delete mode 100644 _site/leetcode/208-implementTriePrefixTree/official.md delete mode 100644 _site/leetcode/212-wordSearchII/official.md delete mode 100644 _site/leetcode/213-HouseRobberII/SpecialYang.md delete mode 100644 _site/leetcode/213-HouseRobberII/official.md delete mode 100644 _site/leetcode/215-KthLargestElementInAnArray/BambooYH.md delete mode 100644 _site/leetcode/215-KthLargestElementInAnArray/bigablecat.md delete mode 100644 _site/leetcode/221-MaximalSquare/official.md delete mode 100644 _site/leetcode/225-implementStackUsingQueues/hatrick.md delete mode 100644 _site/leetcode/225-implementStackUsingQueues/official.md delete mode 100644 _site/leetcode/231-PowerOfTwo/hatrick.md delete mode 100644 _site/leetcode/231-PowerOfTwo/official.md delete mode 100644 _site/leetcode/232-implementQueueUsingStacks/hatrick.md delete mode 100644 _site/leetcode/232-implementQueueUsingStacks/official.md delete mode 100644 _site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md delete mode 100644 _site/leetcode/239-slidingWindowMaximum/official.md delete mode 100644 _site/leetcode/242-ValidAnagram/bigablecat.md delete mode 100644 _site/leetcode/260-SingleNumberIII/README.md delete mode 100644 _site/leetcode/264-UglyNumberII/bigablecat.md delete mode 100644 _site/leetcode/264-UglyNumberII/official.md delete mode 100644 _site/leetcode/279-PerfectSquares/official.md delete mode 100644 _site/leetcode/279-PerfectSquares/zengdiqing1994.md delete mode 100644 _site/leetcode/295-FindMedianFromDataStream/BambooYH.md delete mode 100644 _site/leetcode/300-LongestIncreasingSubsequence/melody-l.md delete mode 100644 _site/leetcode/300-LongestIncreasingSubsequence/official.md delete mode 100644 _site/leetcode/303-rangeSumQueryImmutable/BambooYH.md delete mode 100644 _site/leetcode/303-rangeSumQueryImmutable/official.md delete mode 100644 _site/leetcode/304-RangeSumQuery2DImmutable/official.md delete mode 100644 _site/leetcode/304-RangeSumQuery2DImmutable/woody.md delete mode 100644 _site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md delete mode 100644 _site/leetcode/312-BurstBalloons/melody-l.md delete mode 100644 _site/leetcode/312-BurstBalloons/official.md delete mode 100644 _site/leetcode/321-CreateMaximumNumber/README.md delete mode 100644 _site/leetcode/322-CoinChange/official.md delete mode 100644 _site/leetcode/338-CountingBits/bigablecat.md delete mode 100644 _site/leetcode/343-IntegerBreak/hatrick.md delete mode 100644 _site/leetcode/343-IntegerBreak/official.md delete mode 100644 _site/leetcode/354-RussianDollEnvelopes/official.md delete mode 100644 _site/leetcode/357-CountNumbersWithUniqueDigits/official.md delete mode 100644 _site/leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md delete mode 100644 _site/leetcode/367-ValidPerfectSquare/official.md delete mode 100644 _site/leetcode/368-LargestDivisibleSubset/passself.md delete mode 100644 _site/leetcode/374-GuessNumberHigherOrLower/official.md delete mode 100644 _site/leetcode/375-GuessNumberHigherOrLowerII/official.md delete mode 100644 _site/leetcode/376-WiggleSubsequence/melody-l.md delete mode 100644 _site/leetcode/376-WiggleSubsequence/official.md delete mode 100644 _site/leetcode/377-CombinationSumIV/official.md delete mode 100644 _site/leetcode/378-KthSmallestElementInASortedMatrix/README.md delete mode 100644 _site/leetcode/392-IsSubsequence/official.md delete mode 100644 _site/leetcode/392-IsSubsequence/zengdiqing1994.md delete mode 100644 _site/leetcode/403-FrogJump/README.md delete mode 100644 _site/leetcode/403-FrogJump/official.md delete mode 100644 _site/leetcode/409-LongestPalindrome/README.md delete mode 100644 _site/leetcode/410-SplitArrayLargestSum/hatrick.md delete mode 100644 _site/leetcode/410-SplitArrayLargestSum/official.md delete mode 100644 _site/leetcode/413-arithmeticSlices/official.md delete mode 100644 _site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md delete mode 100644 _site/leetcode/416-PartitionEqualSubsetSum/official.md delete mode 100644 _site/leetcode/446-ArithmeticSlicesIISubsequence/official.md delete mode 100644 _site/leetcode/455-AssignCookies/SpecialYang.md delete mode 100644 _site/leetcode/455-AssignCookies/bigablecat.md delete mode 100644 _site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md delete mode 100644 _site/leetcode/464-CanIWin/official.md delete mode 100644 _site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md delete mode 100644 _site/leetcode/472-ConcatenatedWords/official.md delete mode 100644 _site/leetcode/474-OnesAndZeroes/hatrick.md delete mode 100644 _site/leetcode/474-OnesAndZeroes/official.md delete mode 100644 _site/leetcode/486-PredictTheWinner/official.md delete mode 100644 _site/leetcode/494-TargetSum/official.md delete mode 100644 _site/leetcode/504-Base7/README.md delete mode 100644 _site/leetcode/514-FreedomTrail/hatrick.md delete mode 100644 _site/leetcode/514-FreedomTrail/official.md delete mode 100644 _site/leetcode/516-LongestPalindromicSubsequence/passself.md delete mode 100644 _site/leetcode/517-SuperWashingMachines/official.md delete mode 100644 _site/leetcode/523-ContinuousSubarraySum/hatrick.md delete mode 100644 _site/leetcode/523-ContinuousSubarraySum/official.md delete mode 100644 _site/leetcode/546-RemoveBoxes/passself.md delete mode 100644 _site/leetcode/547-friendCircles/bigablecat.md delete mode 100644 _site/leetcode/551-StudentAttendanceRecordI/official.md delete mode 100644 _site/leetcode/552-StudentAttendanceRecordII/official.md delete mode 100644 _site/leetcode/576-OutOfBoundaryPaths/official.md delete mode 100644 _site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md delete mode 100644 _site/leetcode/629-KInversePairsArray/official.md delete mode 100644 _site/leetcode/629-KInversePairsArray/zengdiqing1994.md delete mode 100644 _site/leetcode/638-ShoppingOffers/bigablecat.md delete mode 100644 _site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md delete mode 100644 _site/leetcode/646-MaximumLengthOfPairChain/official.md delete mode 100644 _site/leetcode/647-PalindromicSubstrings/bigablecat.md delete mode 100644 _site/leetcode/647-PalindromicSubstrings/official.md delete mode 100644 _site/leetcode/650-2KeysKeyboard/mahone.md delete mode 100644 _site/leetcode/650-2KeysKeyboard/official.md delete mode 100644 _site/leetcode/664-StrangePrinter/official.md delete mode 100644 _site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md delete mode 100644 _site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md delete mode 100644 _site/leetcode/688-KnightProbabilityInChessboard/passself.md delete mode 100644 _site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md delete mode 100644 _site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md delete mode 100644 _site/leetcode/691-StickersToSpellWord/official.md delete mode 100644 _site/leetcode/692-TopKFrequentWords/bigablecat.md delete mode 100644 _site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md delete mode 100644 _site/leetcode/698-PartitionToKEqualSumSubsets/official.md delete mode 100644 _site/leetcode/703-KthLargestElementInAStream/BambooYH.md delete mode 100644 _site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md delete mode 100644 _site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md delete mode 100644 _site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md delete mode 100644 _site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md delete mode 100644 _site/leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md delete mode 100644 _site/leetcode/718-MaximumLengthOfRepeatedSubarray/official.md delete mode 100644 _site/leetcode/730-CountDifferentPalindromicSubsequences/official.md delete mode 100644 _site/leetcode/740-DeleteAndEarn/melody-l.md delete mode 100644 _site/leetcode/740-DeleteAndEarn/official.md delete mode 100644 _site/leetcode/746-minCostClimbingStairs/bigablecat.md delete mode 100644 _site/leetcode/746-minCostClimbingStairs/official.md delete mode 100644 _site/leetcode/764-LargestPlusSign/SpecialYang.md delete mode 100644 _site/leetcode/764-LargestPlusSign/official.md delete mode 100644 _site/leetcode/787-CheapestFlightsWithinKStops/official.md delete mode 100644 _site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md delete mode 100644 _site/leetcode/790-DominoAndTrominoTiling/mahone.md delete mode 100644 _site/leetcode/790-DominoAndTrominoTiling/official.md delete mode 100644 _site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md delete mode 100644 _site/leetcode/808-SoupServings/official.md delete mode 100644 _site/leetcode/813-LargestSumOfAverages/melody-l.md delete mode 100644 _site/leetcode/813-LargestSumOfAverages/official.md delete mode 100644 _site/leetcode/837-New21Game/official.md delete mode 100644 _site/leetcode/838-PushDominoes/official.md delete mode 100644 _site/leetcode/844-BackspaceStringCompare/BambooYH.md delete mode 100644 _site/leetcode/844-BackspaceStringCompare/bigablecat.md delete mode 100644 _site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md delete mode 100644 _site/leetcode/847-ShortestPathVisitingAllNodes/official.md delete mode 100644 _site/leetcode/860-lemonadeChange/BambooYH.md delete mode 100644 _site/leetcode/860-lemonadeChange/SpecialYang.md delete mode 100644 _site/leetcode/860-lemonadeChange/official.md delete mode 100644 _site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md delete mode 100644 _site/leetcode/874-walkingRobotSimulation/SpecialYang.md delete mode 100644 _site/leetcode/874-walkingRobotSimulation/hatrick.md delete mode 100644 _site/leetcode/874-walkingRobotSimulation/official.md delete mode 100644 _site/leetcode/875-KokoEatingBananas/sandao.md delete mode 100644 _site/leetcode/877-stoneGame/melody-l.md delete mode 100644 _site/leetcode/877-stoneGame/official.md delete mode 100644 _site/leetcode/898-BitwiseORsOfSubarrays/official.md delete mode 100644 _site/leetcode/903-ValidPermutationsForDISequence/official.md delete mode 100644 _site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md delete mode 100644 _site/leetcode/920-NumberOfMusicPlaylists/passself.md delete mode 100644 _site/leetcode/931-MinimumFallingPathSum/hatrick.md delete mode 100644 _site/leetcode/931-MinimumFallingPathSum/official.md delete mode 100644 _site/leetcode/935-KnightDialer/official.md delete mode 100644 _site/leetcode/940-DistinctSubsequencesII/official.md delete mode 100644 _site/leetcode/943-FindTheShortestSuperstring/official.md delete mode 100644 _site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md delete mode 100644 _site/leetcode/956-TallestBillboard/official.md delete mode 100644 _site/leetcode/964-LeastOperatorsToExpressNumber/official.md delete mode 100644 _site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md delete mode 100644 _site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md delete mode 100644 _site/leetcode/968-BinaryTreeCameras/official.md delete mode 100644 _site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md delete mode 100644 _site/leetcode/975-OddEvenJump/official.md delete mode 100644 _site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md delete mode 100644 _site/leetcode/sample/concise.md delete mode 100644 _site/leetcode/sample/concise.png delete mode 100644 _site/leetcode/sample/full.md delete mode 100644 _site/leetcode/sample/full.png delete mode 100644 "_site/\345\211\221\346\214\207Offer/README.md" diff --git a/_site/README.md b/_site/README.md deleted file mode 100644 index c47855b..0000000 --- a/_site/README.md +++ /dev/null @@ -1,2156 +0,0 @@ - -### 算法每日一练 - -* 这个专栏是Hollis知识星球的朋友们练习算法的地方,同时也欢迎广大网友参与 -* 所有题目来源是[leetCode](https://leetcode-cn.com/problemset/all/)官方公开题库 - -### 初学者友好的算法题目解答 - -* 算法解答部分的代码注释细致到每一行 -* 希望能为初学者提供最大的便利去理解每道题目和解法 -* 欢迎网友为本项目做贡献,提交你的解题方法和详细解释 - ---- - -### 专题列表 -* 2018年11月27日~2019年01月16日 ->[《算法面试通关40讲》专题](https://time.geekbang.org/course/intro/130) ->[《算法面试通关40讲》官方课件](https://github.com/geektime-geekbang/algorithm-1) - -* 2018年11月16日 ->LeetCode动态规划专题 - ---- - -专题(Begin):《算法面试40讲》 ---- - -2018年11月27日 - -[206. 反转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/206-reverseLinkedList) - -[https://leetcode-cn.com/problems/reverse-linked-list/](https://leetcode-cn.com/problems/reverse-linked-list/) - -英文官方题解: - -[https://leetcode.com/articles/reverse-linked-list/](https://leetcode.com/articles/reverse-linked-list/) - -知识点:数组、链表 - -难度:简单 - ---- - -2018年11月28日 - -[24. 两两交换链表中的节点](https://github.com/hollischuang/algorithm/tree/master/leetcode/024-swapNodesInPairs) - -[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) - -无官方题解,网友最高票Java答案: - -[https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.](https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.) - -知识点:数组、链表 - -难度:中等 - ---- - -2018年11月29日 - -[141. 环形链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/141-linkedListCycle) - -[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) - -官方题解: - -[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) - -知识点:数组、链表 - -难度:简单 - ---- - -2018年11月30日 - -[142. 环形链表 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/142-linkedListCycleII) - -[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) - -知识点:数组、链表 - -难度:中等 - ---- - -2018年12月01日 - -[25. k个一组翻转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/025-reverseNodesInKGroup) - -[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments](https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments) - -知识点:数组、链表 - -难度:困难 - ---- - -2018年12月02日 - -[20. 有效的括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/020-validParentheses) - -[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) - -官方题解: - -[https://leetcode-cn.com/articles/valid-parentheses/](https://leetcode-cn.com/articles/valid-parentheses/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月03日 - -[232. 用栈实现队列](https://github.com/hollischuang/algorithm/tree/master/leetcode/232-implementQueueUsingStacks) - -[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) - -英文官方题解: - -[https://leetcode.com/articles/implement-queue-using-stacks/](https://leetcode.com/articles/implement-queue-using-stacks/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月04日 - -[225. 用队列实现栈](https://github.com/hollischuang/algorithm/tree/master/leetcode/225-implementStackUsingQueues) - -[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) - -英文官方题解: - -[https://leetcode.com/articles/implement-stack-using-queues/](https://leetcode.com/articles/implement-stack-using-queues/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月05日 - -[844. 比较含退格的字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/844-BackspaceStringCompare) - -[https://leetcode-cn.com/problems/backspace-string-compare/](https://leetcode-cn.com/problems/backspace-string-compare/) - -英文官方题解: - -[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月06日 - -[703. 数据流中的第K大元素](https://github.com/hollischuang/algorithm/tree/master/leetcode/703-KthLargestElementInAStream) - -[https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) - -知识点:优先队列 - -难度:简单 - ---- - -2018年12月07日 - -[692. 前K个高频单词](https://github.com/hollischuang/algorithm/tree/master/leetcode/692-TopKFrequentWords) - -[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) - -英文官方题解: - -[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) - -知识点:优先队列 - -难度:中等 - ---- - -2018年12月08日 - -[239. 滑动窗口最大值](https://github.com/hollischuang/algorithm/tree/master/leetcode/239-slidingWindowMaximum) - -[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/sliding-window-maximum/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation](https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation) - -知识点:优先队列 - -难度:困难 - ---- - -2018年12月09日 - -[242. 有效的字母异位词](https://github.com/hollischuang/algorithm/tree/master/leetcode/242-ValidAnagram) - -[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) - -英文官方题解: - -[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) - -知识点:哈希表和集合 - -难度:简单 - ---- - -2018年12月10日 - -[1. 两数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/001-twoSum) - -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - -官方题解: - -[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) - -知识点:哈希表和集合 - -难度:简单 - ---- - -2018年12月11日 - -[15. 三数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/015-threeSum) - -[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution](https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution) - -知识点:哈希表和集合 - -难度:中等 - ---- - -2018年12月12日 - -[98. 验证二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/098-validateBinarySearchTree) - -[https://leetcode-cn.com/problems/validate-binary-search-tree/](https://leetcode-cn.com/problems/validate-binary-search-tree/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)](https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines](https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines) - -知识点:树、二叉树、二叉搜索树 - -难度:中等 - ---- - -2018年12月13日 - -[236. 二叉树的最近公共祖先](https://github.com/hollischuang/algorithm/tree/master/leetcode/236-lowestCommonAncestorOfABinaryTree) - -[https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) - -英文官方题解: - -[https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/) - -知识点:树、二叉树、二叉搜索树 - -难度:中等 - ---- - -2018年12月14日 - -[50. Pow(x, n)](https://github.com/hollischuang/algorithm/tree/master/leetcode/050-powxN) - -[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers](https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers) - -知识点:递归、分治 - -难度:中等 - ---- - -2018年12月15日 - -[169. 求众数](https://github.com/hollischuang/algorithm/tree/master/leetcode/169-majorityElement) - -[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) - -英文官方题解: - -[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) - -知识点:递归、分治 - -难度:简单 - ---- - -2018年12月16日 - -[53. 最大子序和](https://github.com/hollischuang/algorithm/tree/master/leetcode/053-maximumSubarray) - -[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts](https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java](https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java) - -知识点:递归、分治、动态规划 - -难度:简单 - ---- - -2018年12月17日 - -[860. 柠檬水找零](https://github.com/hollischuang/algorithm/tree/master/leetcode/860-lemonadeChange) - -[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) - -官方题解: - -[https://leetcode-cn.com/articles/lemonade-change/](https://leetcode-cn.com/articles/lemonade-change/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月18日 - -[122. 买卖股票的最佳时机 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/122-bestTimeToBuyAndSellStockII) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) - -官方题解: - -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月19日 - -[455. 分发饼干](https://github.com/hollischuang/algorithm/tree/master/leetcode/455-AssignCookies) - -[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)](https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月20日 - -[874. 模拟行走机器人](https://github.com/hollischuang/algorithm/tree/master/leetcode/874-walkingRobotSimulation) - -[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) - -英文官方题解: - -[https://leetcode.com/problems/walking-robot-simulation/solution/](https://leetcode.com/problems/walking-robot-simulation/solution/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月21日 - -[102. 二叉树的层次遍历](https://github.com/hollischuang/algorithm/tree/master/leetcode/102-BinaryTreeLevelOrderTraversal) - -[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS) - -知识点:广度优先搜索 - -难度:中等 - ---- - -2018年12月22日 - -[104. 二叉树的最大深度](https://github.com/hollischuang/algorithm/tree/master/leetcode/104-MaximumDepthOfBinaryTree) - -[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) - -官方题解: - -[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) - -知识点:深度优先搜索 - -难度:简单 - ---- - -2018年12月23日 - -[51. N-皇后](https://github.com/hollischuang/algorithm/tree/master/leetcode/051-NQueens) - -[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.](https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.) - -知识点:剪枝 - -难度:困难 - ---- - -2018年12月24日 - -[36. 有效的数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/036-ValidSudoku) - -[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings](https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code](https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code) - -知识点:剪枝 - -难度:中等 - ---- - -2018年12月25日 - -[37. 解数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/037-SudokuSolver) - -[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking](https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking) - -知识点:剪枝 - -难度:困难 - ---- - -2018年12月26日 - -[69. x 的平方根](https://github.com/hollischuang/algorithm/tree/master/leetcode/069-SqrtX) - -[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) - -知识点:二分查找 - -难度:简单 - ---- - -2018年12月27日 - -[367. 有效的完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) - -[https://leetcode-cn.com/problems/valid-perfect-square/](https://leetcode-cn.com/problems/valid-perfect-square/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code](https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code) - -知识点:二分查找 - -难度:简单 - ---- - -2018年12月28日 - -[208. 实现 Trie (前缀树)](https://github.com/hollischuang/algorithm/tree/master/leetcode/208-implementTriePrefixTree) - -[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) - -英文官方题解: - -[https://leetcode.com/articles/implement-trie-prefix-tree/](https://leetcode.com/articles/implement-trie-prefix-tree/) - -知识点:字典树 - -难度:中等 - ---- - -2018年12月29日 - -[212. 单词搜索 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/212-wordSearchII) - -[https://leetcode-cn.com/problems/word-search-ii/](https://leetcode-cn.com/problems/word-search-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)](https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)) - -知识点:字典树 - -难度:困难 - ---- - -2018年12月30日 - -[191. 位1的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/191-NumberOf1Bits) - -[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) - -英文官方题解: - -[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) - -知识点:位运算 - -难度:简单 - ---- - -2018年12月31日 - -[338. 比特位计数](https://github.com/hollischuang/algorithm/tree/master/leetcode/338-CountingBits) - -[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) - -知识点:位运算 - -难度:中等 - ---- - -2019年01月01日 - -[231. 2的幂](https://github.com/hollischuang/algorithm/tree/master/leetcode/231-PowerOfTwo) - -[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount](https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount) - -知识点:位运算 - -难度:简单 - ---- - -2019年01月02日 - -[52. N皇后 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/052-N-QueensII) - -[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution](https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)) - -知识点:位运算 - -难度:困难 - ---- - -2019年01月03日 - -[70. 爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/070-ClimbingStairs) - -[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) - -英文官方题解: - -[https://leetcode.com/articles/climbing-stairs/](https://leetcode.com/articles/climbing-stairs/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月04日 - -[120. 三角形最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/120-Triangle) - -[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle](https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution](https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月05日 - -[152. 乘积最大子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/152-MaximumProductSubarray) - -[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity](https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time](https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月06日 - -[123. 买卖股票的最佳时机 III](https://github.com/hollischuang/algorithm/tree/master/leetcode/123-BestTimeToBuyAndSellStockIII) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月07日 - -[121. 买卖股票的最佳时机](https://github.com/hollischuang/algorithm/tree/master/leetcode/121-bestTimeToBuyAndSellStock) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) - -官方题解: - -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月08日 - -[188. 买卖股票的最佳时机 IV](https://github.com/hollischuang/algorithm/tree/master/leetcode/188-bestTimeToBuyAndSellStockIV) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月09日 - -[309. 最佳买卖股票时机含冷冻期](https://github.com/hollischuang/algorithm/tree/master/leetcode/309-BestTimeToBuyAndSellStockWithCooldown) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月10日 - -[714. 买卖股票的最佳时机含手续费](https://github.com/hollischuang/algorithm/tree/master/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) - -英文官方题解: - -[https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月11日 - -[300. 最长上升子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/300-LongestIncreasingSubsequence) - -[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/longest-increasing-subsequence/](https://leetcode.com/articles/longest-increasing-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月12日 - -[322. 零钱兑换](https://github.com/hollischuang/algorithm/tree/master/leetcode/322-CoinChange) - -[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) - -英文官方题解: - -[https://leetcode.com/articles/coin-change/](https://leetcode.com/articles/coin-change/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月13日 - -[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) - -[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) - -英文官方题解: - -[https://leetcode.com/articles/edit-distance/](https://leetcode.com/articles/edit-distance/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月14日 - -[200. 岛屿的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/200-numberOfIslands) - -[https://leetcode-cn.com/problems/number-of-islands/](https://leetcode-cn.com/problems/number-of-islands/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution](https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution) - -知识点:并查集 - -难度:中等 - ---- - -2019年01月15日 - -[547. 朋友圈](https://github.com/hollischuang/algorithm/tree/master/leetcode/547-friendCircles) - -[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) - -无官方题解,网友高票Java答案1(DFS): - -[https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution](https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution) - -无官方题解,网友高票Java答案2(Union Find): - -[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) - -知识点:并查集 - -难度:中等 - ---- - -2019年01月16日 - -[146. LRU缓存机制](https://github.com/hollischuang/algorithm/tree/master/leetcode/146-lruCache) - -[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)](https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)) - -知识点:LRU - -难度:困难 - ---- - -专题(End):《算法面试40讲》 ---- - -
- -专题(Begin):动态规划 ---- - -2019年01月17日 - -[303. 区域和检索 - 数组不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/303-rangeSumQueryImmutable) - -[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) - -英文官方题解: - -[https://leetcode.com/articles/range-sum-query-immutable/](https://leetcode.com/articles/range-sum-query-immutable/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月18日 - -[746. 使用最小花费爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/746-minCostClimbingStairs) - -[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) - -英文官方题解: - -[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月19日 - -[198. 打家劫舍](https://github.com/hollischuang/algorithm/tree/master/leetcode/198-houseRobber) - -[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月20日 - -[877. 石子游戏](https://github.com/hollischuang/algorithm/tree/master/leetcode/877-stoneGame) - -[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) - -官方题解: - -[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月21日 - -[64. 最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/064-minimumPathSum) - -[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月22日 - -[96. 不同的二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/096-uniqueBinarySearchTrees) - -[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) - -英文官方题解: - -[https://leetcode.com/articles/unique-binary-search-trees/](https://leetcode.com/articles/unique-binary-search-trees/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月23日 - -[413. 等差数列划分](https://github.com/hollischuang/algorithm/tree/master/leetcode/413-arithmeticSlices) - -[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) - -英文官方题解: - -[https://leetcode.com/articles/arithmetic-slices/](https://leetcode.com/articles/arithmetic-slices/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月24日 - -[712. 两个字符串的最小ASCII删除和](https://github.com/hollischuang/algorithm/tree/master/leetcode/712-MinimumASCIIDeleteSumforTwoStrings) - -[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月25日 - -[62. 不同路径](https://github.com/hollischuang/algorithm/tree/master/leetcode/062-UniquePaths) - -[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space](https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)](https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月26日 - -[638. 大礼包](https://github.com/hollischuang/algorithm/tree/master/leetcode/638-ShoppingOffers) - -[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) - -英文官方题解: - -[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月27日 - -[647. 回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/647-PalindromicSubstrings) - -[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) - -英文官方题解: - -[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月28日 - -[931. 下降路径最小和](https://github.com/hollischuang/algorithm/tree/master/leetcode/931-MinimumFallingPathSum) - -[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-path-falling-sum/](https://leetcode.com/articles/minimum-path-falling-sum/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月29日 - -[343. 整数拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/343-IntegerBreak) - -[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution](https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月30日 - -[95. 不同的二叉搜索树 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/095-UniqueBinarySearchTreesII) - -[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) - -英文官方题解: - -[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月31日 - -[740. 删除与获得点数](https://github.com/hollischuang/algorithm/tree/master/leetcode/740-DeleteAndEarn) - -[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) - -英文官方题解: - -[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月01日 - -[646. 最长数对链](https://github.com/hollischuang/algorithm/tree/master/leetcode/646-MaximumLengthOfPairChain) - -[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) - -英文官方题解: - -[https://leetcode.com/articles/maximum-length-of-pair-chain/](https://leetcode.com/articles/maximum-length-of-pair-chain/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月02日 - -[764. 最大加号标志](https://github.com/hollischuang/algorithm/tree/master/leetcode/764-LargestPlusSign) - -[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) - -英文官方题解: - -[https://leetcode.com/articles/largest-plus-sign/](https://leetcode.com/articles/largest-plus-sign/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月03日 - -[279. 完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/279-PerfectSquares) - -[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月04日 - -[392. 判断子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/392-IsSubsequence) - -[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments](https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月05日 - -[377. 组合总和 Ⅳ](https://github.com/hollischuang/algorithm/tree/master/leetcode/377-CombinationSumIV) - -[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation](https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月06日 - -[486. 预测赢家](https://github.com/hollischuang/algorithm/tree/master/leetcode/486-PredictTheWinner) - -[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) - -英文官方题解: - -[https://leetcode.com/articles/predict-the-winner/](https://leetcode.com/articles/predict-the-winner/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月07日 - -[357. 计算各个位数不同的数字个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/357-CountNumbersWithUniqueDigits) - -[https://leetcode-cn.com/problems/count-numbers-with-unique-digits/](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月08日 - -[494. 目标和](https://github.com/hollischuang/algorithm/tree/master/leetcode/494-TargetSum) - -[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) - -英文官方题解: - -[https://leetcode.com/articles/target-sum/](https://leetcode.com/articles/target-sum/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月09日 - -[516. 最长回文子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/516-LongestPalindromicSubsequence) - -[https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution](https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月10日 - -[688. “马”在棋盘上的概率](https://github.com/hollischuang/algorithm/tree/master/leetcode/688-KnightProbabilityInChessboard) - -[https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) - -英文官方题解: - -[https://leetcode.com/articles/knight-probability-in-chessboard/](https://leetcode.com/articles/knight-probability-in-chessboard/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月11日 - -[718. 最长重复子数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/718-MaximumLengthOfRepeatedSubarray) - -[https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/) - -英文官方题解: - -[https://leetcode.com/articles/maximum-length-of-repeated-subarray/](https://leetcode.com/articles/maximum-length-of-repeated-subarray/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月12日 - -[650. 只有两个键的键盘](https://github.com/hollischuang/algorithm/tree/master/leetcode/650-2KeysKeyboard) - -[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) - -英文官方题解: - -[https://leetcode.com/articles/2-keys-keyboard/](https://leetcode.com/articles/2-keys-keyboard/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月13日 - -[873. 最长的斐波那契子序列的长度](https://github.com/hollischuang/algorithm/tree/master/leetcode/873-LengthOfLongestFibonacciSubsequence) - -[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) - -官方题解: - -[https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月14日 - -[139. 单词拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/139-WordBreak) - -[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways](https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月15日 - -[264. 丑数 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/264-UglyNumberII) - -[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月16日 - -[416. 分割等和子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/416-PartitionEqualSubsetSum) - -[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月17日 - -[304. 二维区域和检索 - 矩阵不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/304-RangeSumQuery2DImmutable) - -[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) - -英文无官方题解: - -[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月18日 - -[221. 最大正方形](https://github.com/hollischuang/algorithm/tree/master/leetcode/221-MaximalSquare) - -[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) - -英文官方题解: - -[https://leetcode.com/articles/maximal-square/](https://leetcode.com/articles/maximal-square/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月19日 - -[698. 划分为k个相等的子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/698-PartitionToKEqualSumSubsets) - -[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) - -英文官方题解: - -[https://leetcode.com/articles/partition-to-k-equal-sum-subsets/](https://leetcode.com/articles/partition-to-k-equal-sum-subsets/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月20日 - -[474. 一和零](https://github.com/hollischuang/algorithm/tree/master/leetcode/474-OnesAndZeroes) - -[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.](https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space](https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月21日 - -[838. 推多米诺](https://github.com/hollischuang/algorithm/tree/master/leetcode/838-PushDominoes) - -[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/articles/push-dominoes/](https://leetcode.com/articles/push-dominoes/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月22日 - -[790. 多米诺和托米诺平铺](https://github.com/hollischuang/algorithm/tree/master/leetcode/790-DominoAndTrominoTiling) - -[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月23日 - -[813. 最大平均值和的分组](https://github.com/hollischuang/algorithm/tree/master/leetcode/813-LargestSumOfAverages) - -[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) - -英文官方题解: - -[https://leetcode.com/articles/largest-sum-of-averages/](https://leetcode.com/articles/largest-sum-of-averages/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月24日 - -[376. 摆动序列变](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) - -[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月25日 - -[801. 使序列递增的最小交换次数](https://github.com/hollischuang/algorithm/tree/master/leetcode/801-MinimumSwapsToMakeSequencesIncreasing) - -[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/](https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月26日 - -[808. 分汤](https://github.com/hollischuang/algorithm/tree/master/leetcode/808-SoupServings) - -[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) - -英文官方题解: - -[https://leetcode.com/articles/soup-servings/](https://leetcode.com/articles/soup-servings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月27日 - -[63. 不同路径 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/063-UniquePathsII) - -[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) - -英文官方题解: - -[https://leetcode.com/articles/unique-paths-ii/](https://leetcode.com/articles/unique-paths-ii/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月28日 - -[213. 打家劫舍 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/213-HouseRobberII) - -[https://leetcode-cn.com/problems/house-robber-ii/](https://leetcode-cn.com/problems/house-robber-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation](https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月01日 - -[368. 最大整除子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/368-LargestDivisibleSubset) - -[https://leetcode-cn.com/problems/largest-divisible-subset/](https://leetcode-cn.com/problems/largest-divisible-subset/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)](https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月02日 - -[467. 环绕字符串中唯一的子字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/467-UniqueSubstringsInWraparoundString) - -[https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月03日 - -[464. 我能赢吗](https://github.com/hollischuang/algorithm/tree/master/leetcode/464-CanIWin) - -[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation](https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation](https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月04日 - -[935. 骑士拨号器](https://github.com/hollischuang/algorithm/tree/master/leetcode/935-KnightDialer) - -[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) - -英文官方题解: - -[https://leetcode.com/articles/knight-dialer/](https://leetcode.com/articles/knight-dialer/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月05日 - -[787. K 站中转内最便宜的航班](https://github.com/hollischuang/algorithm/tree/master/leetcode/787-CheapestFlightsWithinKStops) - -[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月06日 - -[576. 出界的路径数](https://github.com/hollischuang/algorithm/tree/master/leetcode/576-OutOfBoundaryPaths) - -[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) - -英文官方题解: - -[https://leetcode.com/articles/out-of-boundary-paths/](https://leetcode.com/articles/out-of-boundary-paths/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月07日 - -[374. 猜数字大小](https://github.com/hollischuang/algorithm/tree/master/leetcode/374-GuessNumberHigherOrLower) - -[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) - -英文官方题解: - -[https://leetcode.com/articles/guess-number-higher-or-lower/](https://leetcode.com/articles/guess-number-higher-or-lower/) - -知识点:二分查找 - -难度:简单 - ---- - -2019年03月08日 - -[375. 猜数字大小 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/375-GuessNumberHigherOrLowerII) - -[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~](https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月09日 - -[967. 连续差相同的数字](https://github.com/hollischuang/algorithm/tree/master/leetcode/967-NumbersWithSameConsecutiveDifferences) - -[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) - -英文官方题解: - -[https://leetcode.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/numbers-with-same-consecutive-differences/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月10日 - -[673. 最长递增子序列的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/673-NumberOfLongestIncreasingSubsequence) - -[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月11日 - -[131. 分割回文串](https://github.com/hollischuang/algorithm/tree/master/leetcode/131-PalindromePartitioning) - -[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.](https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.) - -知识点:回溯算法 - -难度:中等 - ---- - -2019年03月12日 - -[132. 分割回文串II](https://github.com/hollischuang/algorithm/tree/master/leetcode/132-PalindromePartitioningII) - -[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.](https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月13日 - -[5. 最长回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/005-LongestPalindromicSubstring) - -[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) - -英文官方题解: - -[https://leetcode.com/articles/longest-palindromic-substring/](https://leetcode.com/articles/longest-palindromic-substring/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月14日 - -[523. 连续的子数组和](https://github.com/hollischuang/algorithm/tree/master/leetcode/523-ContinuousSubarraySum) - -[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space](https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月15日 - -[837. 新21点](https://github.com/hollischuang/algorithm/tree/master/leetcode/837-New21Game) - -[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) - -英文官方题解: - -[https://leetcode.com/articles/new-21-game/](https://leetcode.com/articles/new-21-game/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月16日 - -[898. 子数组按位或操作](https://github.com/hollischuang/algorithm/tree/master/leetcode/898-BitwiseORsOfSubarrays) - -[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) - -英文官方题解: - -[https://leetcode.com/articles/bitwise-ors-of-subarrays/](https://leetcode.com/articles/bitwise-ors-of-subarrays/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月17日 - -[91. 解码方法](https://github.com/hollischuang/algorithm/tree/master/leetcode/091-DecodeWays) - -[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) - -无官方题解,网友高票Java答案1: - -[https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference](https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference) - -无官方题解,网友高票Java答案2: - -[https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation](https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月18日 - -[312. 戳气球](https://github.com/hollischuang/algorithm/tree/master/leetcode/312-BurstBalloons) - -[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations](https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月19日 - -[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) - -[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)](https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月20日 - -[975. 奇偶跳](https://github.com/hollischuang/algorithm/tree/master/leetcode/975-OddEvenJump) - -[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) - -官方题解: - -[https://leetcode-cn.com/articles/odd-even-jump/](https://leetcode-cn.com/articles/odd-even-jump/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月21日 - -[115. 不同的子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/115-DistinctSubsequences) - -[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java](https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月22日 - -[940. 不同的子序列 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/940-DistinctSubsequencesII) - -[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) - -英文官方题解: - -[https://leetcode.com/articles/distinct-subsequences-ii/](https://leetcode.com/articles/distinct-subsequences-ii/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月23日 - -[691. 贴纸拼词](https://github.com/hollischuang/algorithm/tree/master/leetcode/691-StickersToSpellWord) - -[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) - -英文官方题解: - -[https://leetcode.com/articles/stickers-to-spell-word/](https://leetcode.com/articles/stickers-to-spell-word/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月24日 - -[982. 按位与为零的三元组](https://github.com/hollischuang/algorithm/tree/master/leetcode/982-TriplesWithBitwiseANDEqualToZero) - -[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月25日 - -[546. 移除盒子](https://github.com/hollischuang/algorithm/tree/master/leetcode/546-RemoveBoxes) - -[https://leetcode-cn.com/problems/remove-boxes/](https://leetcode-cn.com/problems/remove-boxes/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions](https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月26日 - -[85. 最大矩形](https://github.com/hollischuang/algorithm/tree/master/leetcode/085-MaximalRectangle) - -[https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution](https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月27日 - -[903. DI 序列的有效排列](https://github.com/hollischuang/algorithm/tree/master/leetcode/903-ValidPermutationsForDISequence) - -[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) - -英文官方题解: - -[https://leetcode.com/articles/valid-permutations-for-di-sequence/](https://leetcode.com/articles/valid-permutations-for-di-sequence/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月28日 - -[629. K个逆序对数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) - -英文官方题解: - -[https://leetcode.com/articles/k-inverse-pairs-array/](https://leetcode.com/articles/k-inverse-pairs-array/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月29日 - -[956. 最高的广告牌](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) - -英文官方题解: - -[https://leetcode.com/problems/tallest-billboard/solution/](https://leetcode.com/problems/tallest-billboard/solution/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月30日 - -[664. 奇怪的打印机](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) - -英文官方题解: - -[https://leetcode.com/problems/strange-printer/solution/](https://leetcode.com/problems/strange-printer/solution/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年04月01日 - -[943. 最短超级串](https://github.com/hollischuang/algorithm/tree/master/leetcode/943-FindTheShortestSuperstring) - -[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) - -英文官方题解: - -[https://leetcode.com/articles/find-the-shortest-superstring/](https://leetcode.com/articles/find-the-shortest-superstring/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年04月02日 - -[32. 最长有效括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/032-LongestValidParentheses) - -[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) - -英文官方题解: - -[https://leetcode.com/articles/longest-valid-parentheses/](https://leetcode.com/articles/longest-valid-parentheses/) - -知识点:动态规划 - -难度:困难 - ---- - - -2019年04月03日 - -[403. 青蛙过河](https://github.com/hollischuang/algorithm/tree/master/leetcode/403-FrogJump) - -[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) - -知识点:动态规划 - -难度:困难 - ---- - - -2019年04月04日 - -[321. 拼接最大数](https://github.com/hollischuang/algorithm/tree/master/leetcode/321-CreateMaximumNumber) - -[https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) - -无官方题解,网友高票Java答案: - -[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) - -知识点:动态规划 - -难度:困难 - ---- diff --git a/_site/contribute.md b/_site/contribute.md deleted file mode 100644 index ed55f6f..0000000 --- a/_site/contribute.md +++ /dev/null @@ -1,105 +0,0 @@ -提交答案步骤 ---- - ->各位网友好,在向本项目提交您的答案详解时,请阅读以下内容 - -
- -**0. 从题目列表或者leetCode题库选择题目** - -1) 从本项目的题目列表中选择,每日更新,来自leetCode免费公开题库 - -[https://github.com/hollischuang/algorithm/blob/master/daily.md](https://github.com/hollischuang/algorithm/blob/master/daily.md) - -2) 或者直接从leetCode免费题库中自行选择 - -[https://leetcode-cn.com/problemset/all/](https://leetcode-cn.com/problemset/all/) - -
- -**1. 为运行成功的代码写出详细注释** - -* 可以提交一个精简版的答案,仅包括代码和详细注释 - -``` -精简版答案包括: - -1) 能够在leetCode上成功提交的代码 - -2) 代码详细注释 - -3) 参考或引用的链接 - -``` - -![精简版答案示例](https://raw.githubusercontent.com/hollischuang/Interview/master/algorithm/leetcode/sample/concise.png) - ->*精简版答案示例下载地址:* - ->[https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/concise.md](https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/concise.md) - -
- -* 或者提交一个详尽版的答案,参照leetCode官方题解样式 - -``` -详尽版答案包括: - -1) 能够在leetCode上成功提交的代码 - -2) 代码详细注释 - -3) 复杂度分析:包括时间复杂度和空间复杂度 - -4) 方法和思路概述 - -5) 参考或引用的链接 - -``` - -![详尽版答案示例](https://raw.githubusercontent.com/hollischuang/Interview/master/algorithm/leetcode/sample/full.png) - ->*详尽版示例下载地址:* - ->[https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/full.md](https://github.com/hollischuang/algorithm/blob/master/leetcode/sample/full.md) - -* 引用和参考: - -``` - -不强制原创,如果提交的答案有借鉴、转载、翻译, - -请务必注明引用出处 -``` - -
- -**2. 找到题目所在目录,新建md文件并提交,命名规则 "英文或拼音昵称.md"** - -1) 在/Interview/algorithm/leetcode/文件夹下找到题目文件夹,如 - -``` -/Interview/algorithm/leetcode/141-LinkedListCycle - -如果项目里还没有该题的文件夹,请按照驼峰式命名法新建"题号-题目名称.md",题号小于百位数请加0 - -比如题号是24的swap-nodes-in-pairs,命名后如下 - -/Interview/algorithm/leetcode/024-SwapNodesInPairs -``` - -2) 文件名请务必使用英文或拼音: - -``` -比如你的昵称叫offical, 文件就命名为 official.md -``` - -3) 建好后完整路径和名称如下所示: - -``` -/Interview/algorithm/leetcode/141-LinkedListCycle/offical.md -``` - -4) 在git上提交你的文件,管理员审核通过后大家就能看到你的答案并和你讨论了 - ---- diff --git a/_site/leetcode/001-twoSum/hatrick.md b/_site/leetcode/001-twoSum/hatrick.md deleted file mode 100644 index 8b955cc..0000000 --- a/_site/leetcode/001-twoSum/hatrick.md +++ /dev/null @@ -1,39 +0,0 @@ -**1. 两数之和** ---- -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - -解决方案 -**思路** -思路1: 根据题意我们其实可以直接使用双重for循环,然后拿到两个值相加就等于目标值的那两个下标返回即可, -只是这样的时间复杂度是O(N^2) -思路2: 我们可以转换思路,先将目标值与我们需要下标对应元素值保存起来,等到下一个我们需要的差值,就会拿到之前key, -既可以得到两个下标 - -``` -private static int[] twoSum(int[] nums, int target) { - //定义容器,存放首个下标,当有其差值出现的时候,便可以等到另一个下标 - Map map = new HashMap<>(); - //用来存储最后返回结果 - int[] result = new int[2]; - for (int i = 0; i < nums.length; i++) { - //判断之前的key是否已经保存到map中,如果已经存在,那么当前的值加上之前的值既为目标值 - if (map.containsKey(target - nums[i])) { - result[0] = map.get(target - nums[i]); - //这个时候i所对应的元素还没有放到map中,但是我们要找的值已经找到返回即可 - result[1] = i; - return result; - } - map.put(nums[i], i); - } - return result; - } - -``` -**复杂度分析** -时间复杂度:O(N) 循环所有数组元素,当然根据目标值,每次查找花费O(1)时间,所以最后复杂度为O(N) -空间复杂度:O(N) 使用map数据结构,存储的元素取决于传入的元素数量 - - -**参考资料** -* 本题leetCode英文官方题解: -[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) diff --git a/_site/leetcode/001-twoSum/official.md b/_site/leetcode/001-twoSum/official.md deleted file mode 100644 index 729d988..0000000 --- a/_site/leetcode/001-twoSum/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**1. 两数之和** ---- -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - diff --git a/_site/leetcode/001-twoSum/woody.md b/_site/leetcode/001-twoSum/woody.md deleted file mode 100644 index 996a728..0000000 --- a/_site/leetcode/001-twoSum/woody.md +++ /dev/null @@ -1,53 +0,0 @@ ->答案示例,本人自行编写后参考LeetCode官方题库。 - -**001.两数之和** ---- -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - -摘要 - -本文适用于初学者。 - - -```java - -class Solution { - //这道题虽然不难,但在解决的过程中会发现有更优质的方法去解决 - public int[] twoSum(int[] nums, int target) { - //第一眼看到这个题的时候,很像冒泡排除,选择排序 - int i=0; int j=i+1; - //其实这个效率低的方法直接冒泡就可以 - // 确定要循环几次,来走完所有的情况 - for(i=0;i 题目只是单纯的要求两个数相加求和,那我们直接用迭代的方式来控制对应位置上数字两两相加。需要注意的有两点:一是需要考虑两个个位数相加的进位,超过10之后向前进一,这里用一个变量来保存进位。二是因为两个数字的长度不一定一样,长度短的如果位数不够,则用0来补足。 - -- code(scala version) -``` - def addTwoNumbers(l1: ListNode, l2: ListNode): ListNode = { - - var ll1 = l1 - var ll2 = l2 - - //定义指向头结点的变量 - var result: ListNode = new ListNode() - //定义一个dummy指针来指向头节点,这样可以任意的移动刚开始指向头节点的变量而不用担心头结点的丢失 - var dummy: ListNode = result - - //保存两个一位数相加后结果的十位数上的值:结果大于等于10则为1,否则为0 - var carry: Int = 0 - var sum, x, y: Int = 0 - while (ll1 != null || ll2 != null) { - //如果当前链表的当前节点为空,则值为null - if (ll1 != null) x = ll1.x else x = 0 - if (ll2 != null) y = ll2.x else y = 0 - sum = x + y + carry - result.next = new ListNode(sum % 10) - carry = if (sum > 9) 1 else 0 - result = result.next - - //链表当前节点不为空,则向后推移一个节点,若为空,则不变 - if (ll1 != null) ll1 = ll1.next - if (ll2 != null) ll2 = ll2.next - } - //当两个链表中的所以节点都相加完之后,判断最后一个相加的结果是否超过10,超过10的时候需要额外增加一个节点来保存进位的结果 - if (carry == 1) result.next = new ListNode(1) - //返回dummy指针的next,即结果的头指针 - dummy.next - } -``` -- 时间空间复杂度分析 - > 时间复杂度:O(max(m,n)) m,n分别为两个链表的长度,因为需要相应位置相加,所以需要遍历两个链表 - > 空间复杂度:O(max(m,n)) m,n分别为两个链表的长度,最后结果长度一定跟最大的数长度相同或者比其大一位,我们用对应长度的链表保存。 - -- 参考资料 -[official solution: https://leetcode.com/problems/add-two-numbers/solution/](https://leetcode.com/problems/add-two-numbers/solution/) diff --git a/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md b/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md deleted file mode 100644 index 2a220b1..0000000 --- a/_site/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md +++ /dev/null @@ -1,43 +0,0 @@ -**1. 003-LongestSubstringWithoutRepeatingCharacters** ---- -[https://leetcode.com/problems/longest-substring-without-repeating-characters/](https://leetcode.com/problems/longest-substring-without-repeating-characters/) - -- 解决思路 - > 题目需要求解最长无重复字符的子串长度。首先依次的遍历该字符串,用一个数据结构(set,map等)来保存已经遍历过的字符,当前字符没有出现过,则将其添加到我们定义的数据结构中,当前无重复子串长度加一。如果当前字符出现过,则需要将数据结构中与该字符相同字符之前的字符全部删除,并重新计数新的子串长度。此处需要用一个变量来保存之前无重复子串的最大长度,每次出现重复字符时都要跟之前最大的长度比较判断是否需要更新。 - -- code(scala version) -``` - def lengthOfLongestSubstringWithSet(s: String): Int ={ - //传入的string的长度 - var length = s.length - //用set保存出现过的字符 - var elemSet: Set[Char] = Set() - - var begin, end = 0 - //用来保存当前所计算的最长长度 - var maxLength = 0 - while(begin < length && end < length){ - //如果set中不包含当前字符,则将当前字符添加入set,并向后移动给一个字符 - if(!elemSet.contains(s.charAt(end))){ - elemSet += s.charAt(end) - end = end +1 - //更新maxLength,此处是重点:注意一定要用max函数比较 当前的不重复字符串长度 与 上一次出现重复字符时记录的最长不重复字符串长度 - maxLength = Math.max(maxLength , end - begin) - } else{ - //如果set中包含当前字符,则利用循环将出现重复字符之前的字符全部从set中删除,保证set所留的都是需要重新计算长度的字符 - do { - elemSet -= s.charAt(begin) - begin = begin + 1 - } while(s.charAt(begin-1)!=s.charAt(end)) - } - } - - maxLength - } -``` -- 时间空间复杂度分析 - > 时间复杂度:O(n) n为字符串长度,此处需要遍历两次字符串,所以时间复杂度为O(2n)=O(n) - > 空间复杂度:O(min(m,n)) 因为我们需要O(k)的空间来保存无重复字符的子串。k的最大长度不会超过原始字符串的长度n,也不会超过原始字符串中字符所在的字符表或者字母表集合的大小m。k取m和n的最小值。 - -- 参考资料 -[https://leetcode.com/problems/longest-substring-without-repeating-characters/solution/](https://leetcode.com/problems/longest-substring-without-repeating-characters/solution/) \ No newline at end of file diff --git a/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md b/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md deleted file mode 100644 index 7634117..0000000 --- a/_site/leetcode/005-LongestPalindromicSubstring/hatrick.md +++ /dev/null @@ -1,60 +0,0 @@ -**5. 最长回文子串** ---- -[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) - -解决方案 -**思路** -从1到字符串长度开始遍历,找每个长度可能存在的字符串。 -注意:每个长度只要找到一个即可,并且注意当前长度存在回文串的条件为上次迭代存在回文串或者上上次. -注意剪枝操作,不然的话有可能会超时 -``` - public static String longestPalindrome(String s) { - //用来记录上次最长的回文串长度 - int max = 1; - //存储当前长度对应的回文串 - Map subStringMap = new HashMap<>(); - subStringMap.put(1, Character.toString(s.charAt(0))); - int len = s.length(); - //当前迭代回文串存在的条件是,要么上次迭代存在回文串,要么上上次存在 - boolean flag = false; - for (int i = 2; i <= len; i++) { - for (int t = 0; t + i <= len; t++) { - if ((i - 1) != max && (i - 2) != max) - break; - if (flag) { - flag = false; - continue; - } - String subString = s.substring(t, t + i); - if (check(subString)) { - //注意,只要当前长度找到一个回文串就可以了,不需要再找了 - max = i; - if (!subStringMap.containsKey(i)) { - subStringMap.put(i, subString); - } else - flag = true; - break; - } - } - } - return subStringMap.get(max); - } - - private static boolean check(String subString) { - int len = subString.length(); - int mid = len / 2; - for (int i = 0; i < mid; i++) { - //从两遍向中间靠拢对比 - if (subString.charAt(i) != subString.charAt(len - 1 - i)) - return false; - } - return true; - } -``` -**复杂度分析** -时间复杂度:O(N*N) -空间复杂度:O(N) 额外用了一个存储结构 - - -**参考资料** -[https://blog.csdn.net/cserwangjun/article/details/80878797](https://blog.csdn.net/cserwangjun/article/details/80878797) diff --git a/_site/leetcode/005-LongestPalindromicSubstring/official.md b/_site/leetcode/005-LongestPalindromicSubstring/official.md deleted file mode 100644 index 7bb01c7..0000000 --- a/_site/leetcode/005-LongestPalindromicSubstring/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**5. 最长回文子串** ---- -[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git a/_site/leetcode/015-threeSum/hatrick.md b/_site/leetcode/015-threeSum/hatrick.md deleted file mode 100644 index 8c48ec4..0000000 --- a/_site/leetcode/015-threeSum/hatrick.md +++ /dev/null @@ -1,52 +0,0 @@ -**15. 三数之和** ---- -[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) - - -解决方案 -**思路** -首先考虑数组遍历时去重: -方法一:先将数组排好序,在遍历的时候与上一个进行比较,相同则直接进入下一个 -方法二:用容器Set——简单,但是同样需要排序,增加算法复杂度并且此题三个数操作不方便, -    降低复杂度一般的途径就是利用已有的而未用到的条件将多余的步骤跳过或者删去,由于三个数是具有一个特点的:和为某个定值,这个条件只是用来判断了而并没有使用 -    并且,由上个去重得知,后面使用的数组是已经排序好的。此时仔细想想应该就能想到,从两端使用两个指针相向移动,两端指针所指数之和如果小于目标值,只需要移动左边的指针,否则只需要移动右边的指针!! - 例如[1,1,1,4,5,7,8,8,9]中 定目标值为15,从两边开始,1+9为10,小于15,移动右边指针左移变成1+8只会更少,所以移动左边变成4+9以此类推 - -``` - public static List> threeSum(int[] nums) { - List> result = new ArrayList<>(); - Arrays.sort(nums); - - for (int i = 0; i < nums.length - 2; i++) { - int left = i + 1; - int right = nums.length - 1; - if (i > 0 && nums[i] == nums[i - 1]) - continue; // 去掉重复的起点 - while (left < right) { - int sum = nums[left] + nums[right] + nums[i]; - if (sum == 0) { - result.add(Arrays.asList(nums[i], nums[left], nums[right])); - while (left < right && nums[left] == nums[left + 1]) - left++; // 去掉重复的左点 - while (left < right && nums[right] == nums[right - 1]) - right--; // 去掉重复的右点 - right--; // 进入下一组左右点判断 - left++; - } else if (sum > 0) { - right--; // sum>0 ,说明和过大了,需要变小,所以移动右边指针 - } else { - left++; // 同理,需要变大,移动左指针 - } - } - } - return result; - } - -``` -**复杂度分析** -时间复杂度:O(N2) 使用排序+去重+双指针移动定位 -空间复杂度:O(N) - - -**参考资料** -[https://www.cnblogs.com/Xieyang-blog/p/8242900.html](https://www.cnblogs.com/Xieyang-blog/p/8242900.html) diff --git a/_site/leetcode/015-threeSum/official.md b/_site/leetcode/015-threeSum/official.md deleted file mode 100644 index f849931..0000000 --- a/_site/leetcode/015-threeSum/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**15. 三数之和** ---- -[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) - diff --git a/_site/leetcode/020-validParentheses/official.md b/_site/leetcode/020-validParentheses/official.md deleted file mode 100644 index a82a70a..0000000 --- a/_site/leetcode/020-validParentheses/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**20. 有效的括号** ---- -[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) - diff --git a/_site/leetcode/024-swapNodesInPairs/official.md b/_site/leetcode/024-swapNodesInPairs/official.md deleted file mode 100644 index 0004d08..0000000 --- a/_site/leetcode/024-swapNodesInPairs/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**24. 两两交换链表中的节点** ---- -[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) - diff --git a/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md b/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md deleted file mode 100644 index 5e33667..0000000 --- a/_site/leetcode/025-reverseNodesInKGroup/bigablecat.md +++ /dev/null @@ -1,75 +0,0 @@ -25. k个一组翻转链表 ---- - -[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) - -```java - /** - * 递归解法 - *

- * //定义ListNode如下 - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - * - * @param head - * @param k - * @return - */ - public ListNode reverseKGroup(ListNode head, int k) { - if (head == null || head.next == null) return head; - ListNode prev = null; //定义一个前驱结点prev,初始值为null - ListNode next = head.next; //定义当前结点的后继结点next - ListNode tail = head; //定义尾结点,缓存当前头结点,反转后变成尾结点 - int k0 = k; //定义k0缓存原始k值 - // while循环中的代码每次操作的都是前一个结点的后继结点 - // 当循环至k-1次时,操作的是本组最后一个结点 - // 所以在循环开始前让k=k-1,将循环减少1次,否则会计算下一组的头结点 - k = k - 1; - while (next != null && k > 0) { - head.next = prev; //反转当前结点 - //反转完成后为下一轮循环赋值 - prev = head; //当前结点赋值给前驱结点变量prev - head = next; //后继结点赋值给当前结点变量head - next = head.next; //获得新的后继结点 - k--; - } - //while循环结束后,head是本组结点原顺序的尾结点,翻转后的新头结点 - //对head进行翻转操作,本组结点全部翻转完毕 - head.next = prev; - - //如果k>0说明本组的结点总数少于k - if (k > 0) { - //用原始值k0减去剩余的k,得到本组结点的实际个数 - k = k0 - k; - //重新反转链表 - //因为本组长度小于k,根据题意要保持原有顺序 - //上面的while循环已经做了反转,重新调用reverseKGroup再反转一次回到原有顺序 - head = reverseKGroup(head, k); - } else { - k = k0;//k恢复原始值 - //获取下一组的头结点 - next = reverseKGroup(next, k); - //将本组的尾结点与下一组的头结点连接 - tail.next = next; - } - //每次都返回新的头结点 - return head; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -若链表结点个数为n,k个一组,共n/k组, -方法依次对每组结点进行处理,总共需要(n/k)次, -因为使用了递归调用,所以递归本身的时间复杂度是n/k, -方法中使用了while循环,遍历每组中的k个结点,时间复杂度为k, -最终时间复杂度是(n/k)*k = n - -空间复杂度:O(n),本题中递归的空间复杂度约为n/k,所以空间复杂度是O(n) - ---- diff --git a/_site/leetcode/025-reverseNodesInKGroup/official.md b/_site/leetcode/025-reverseNodesInKGroup/official.md deleted file mode 100644 index 392197d..0000000 --- a/_site/leetcode/025-reverseNodesInKGroup/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**25. k个一组翻转链表** ---- -[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) - diff --git a/_site/leetcode/032-LongestValidParentheses/official.md b/_site/leetcode/032-LongestValidParentheses/official.md deleted file mode 100644 index 181dca1..0000000 --- a/_site/leetcode/032-LongestValidParentheses/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**32. 最长有效括号** ---- -[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) diff --git a/_site/leetcode/036-ValidSudoku/SpecialYang.md b/_site/leetcode/036-ValidSudoku/SpecialYang.md deleted file mode 100644 index c9382fd..0000000 --- a/_site/leetcode/036-ValidSudoku/SpecialYang.md +++ /dev/null @@ -1,113 +0,0 @@ -**有效的数独** ---- -https://leetcode.com/problems/valid-sudoku/ - -此题其实很简单,根本无需采用dfs的方式即可解决,平常的循环做法即可。主要解决如下问题: -1. 保证每一行不出现重复的数字 -2. 保证每一列不出现重复的数字 -3. 保证每一个子九宫格不出现重复的数字 - -本题没有要求你解数独,只是单纯的让你判断是否合法,那还不简单,遍历判断呗 - -### 思路一 -循环遍历九宫格,判断每一个已填充数字的单元格是否是合法。 -1. 对于行,我们判断该行中除了当前列以外是否出现了重复数字 -2. 对于列,我们判断该列中除了当前行以外是否出现了重复数字 -3. 对于九宫格,我们判断该九宫格除了当前位置以外是否出现了重复数字 - -```java - /** - * 常规遍历做法 - * @param board - * @return - */ - public boolean isValidSudoku1(char[][] board) { - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - //对每一个不是'.'的格子进行判断 - if (board[i][j] != '.' - && !isValidSudoku(board, i, j)) { - return false; - } - } - } - return true; - } - - /** - * 判断该单元格出现的数字是否是合法的 - * @param board - * @param row - * @param col - * @return - */ - public boolean isValidSudoku(char[][] board, int row, int col) { - char ch = board[row][col]; - //行 - for (int i = 0; i < 9; i++) { - if (i != row && ch == board[i][col]) { - return false; - } - } - //列 - for (int i = 0; i < 9; i++) { - if (i != col && ch == board[row][i]) { - return false; - } - } - //九宫格 - //定位该单元格所处的九宫格的起始行 - int startRow = row / 3 * 3; - //定位该单元格所处的九宫格的起始列 - int startCol = col / 3 * 3; - for (int i = startRow; i < startRow + 3; i++) { - for (int j = startCol; j < startCol + 3; j++) { - if (i != row && j != col && ch == board[i][j]) { - return false; - } - } - } - return true; - } -``` -#### 复杂度 -- 时间复杂度:O(n^2),双重循环嘛。至于判断逻辑则是常量级别 -- 空间复杂度:O(1) - -### 思路二 -思路一其实对于每一个单元格进行判断时的算法常量级别还是有点大的。每次都会从行的开头或者列的开头判断,所以我们可以缓存起来,这样下次判断的时候,即可快速查找是否有响应的值,这时就要用O(1)查询的哈希结构了,**集合**非常适合本情况。 -我们利用3个set,分别代表每行,每列,每个九宫格出现的数字 -1. 数字存到**行集合**的形式为:`rows.add(num + " in row " + i)` -2. 数字存到**列集合**的形式为:`cols.add(num + " in col " + j)` -3. 数字存到**九宫格集合**的形式为:`blocks.add(num + "in block " + i / 3 + "-" + j / 3)` - -```java - /** - * 空间换时间 - * @param board - * @return - */ - public boolean isValidSudoku2(char[][] board) { - Set rows = new HashSet<>(); - Set cols = new HashSet<>(); - Set blocks = new HashSet<>(); - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - if (board[i][j] != '.') { - char num = board[i][j]; - if (!rows.add(num + " in row " + i) || - !cols.add(num + " in col " + j) || - !blocks.add(num + "in block " + i / 3 + "-" + j / 3)) { - return false; - } - } - } - } - return true; - } -``` -#### 复杂度 -- 时间复杂度:O(n) -- 空间复杂度:O(n) - -参考:https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings diff --git a/_site/leetcode/036-ValidSudoku/official.md b/_site/leetcode/036-ValidSudoku/official.md deleted file mode 100644 index 16e3f01..0000000 --- a/_site/leetcode/036-ValidSudoku/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**36. 有效的数独** ---- - -[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) diff --git a/_site/leetcode/037-SudokuSolver/SpecialYang.md b/_site/leetcode/037-SudokuSolver/SpecialYang.md deleted file mode 100644 index 9a59455..0000000 --- a/_site/leetcode/037-SudokuSolver/SpecialYang.md +++ /dev/null @@ -1,97 +0,0 @@ -**解数独** ---- -https://leetcode.com/problems/sudoku-solver/ - -这道题其实是有效数独的延伸,要求你为给定的数独图的中所有空位填入合适的数字,并且满足数独图的要求。 - -难度其实不大,就是普通的dfs问题。分2个步骤: -1. 递过程:对于每一个空的单元格,尝试从1到9,填入单元格中,并检验是否有效。若有效,则向下递,否则换另一个数填入 -2. 归过程:即回溯,当前的单元格恢复为空白 - -我们还是从(0,0)开始,一直探索到不满足条件,然后回溯,再次向下探索,直到(9,0)为止。因为题目保证了必然有解,所以当探索到(9,0)位置时,说明之前填入的数都是合法的。 - -```java - public void solveSudoku(char[][] board) { - dfs(board, 0, 0); - } - - /** - * 递归填充值 - * 每个待填的格子 从1开始到9尝试填充 - * @param board - * @param row - * @param col - * @return - */ - public boolean dfs(char[][] board, int row, int col) { - //递归结束条件 - if (row == 9 && col == 0) { - return true; - } - /* - 首先生成下一个格子的合法位置 - 在这里处理的目的是为了避免后面的循环部分,每次都要求下一个位置 - */ - int newCol = col + 1, newRow = row; - //换行 - if (newCol == 9) { - newCol = 0; - newRow += 1; - } - //如果该单元格不用填充,则直接往前递 - if (board[row][col] != '.') { - return dfs(board, newRow, newCol); - } - //尝试1到9填充 - for (char i = '1'; i <= '9'; i++) { - if (isValid(board, row, col, i)) { - //递 - board[row][col] = i; - //要当前填充有解,直接往上回溯 - if (dfs(board, newRow, newCol)) { - return true; - } - //归 - board[row][col] = '.'; - } - } - return false; - } - - /** - * 判断如果放入该值,是否满足合法 - * @param board - * @param row - * @param col - * @param ch - * @return - */ - public boolean isValid(char[][] board, int row, int col, char ch) { - //满足行要求 - for (int i = 0; i < 9; i++) { - if (i != row && ch == board[i][col]) { - return false; - } - } - //满足列要求 - for (int i = 0; i < 9; i++) { - if (i != col && ch == board[row][i]) { - return false; - } - } - //满足单元格要求 - int startRow = row / 3 * 3; - int startCol = col / 3 * 3; - for (int i = startRow; i < startRow + 3; i++) { - for (int j = startCol; j < startCol + 3; j++) { - if (i != row && j != col && ch == board[i][j]) { - return false; - } - } - } - return true; - } -``` -#### 复杂度 -- 时间复杂度:O(9^k),k为空白的单元格数 -- 空间复杂度:O(1),虽然深度最大为81,但是是固定值,故可认为是常量级别 diff --git a/_site/leetcode/037-SudokuSolver/official.md b/_site/leetcode/037-SudokuSolver/official.md deleted file mode 100644 index 3ab44bf..0000000 --- a/_site/leetcode/037-SudokuSolver/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**37. 解数独** ---- - -[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) diff --git a/_site/leetcode/050-powxN/bigablecat.md b/_site/leetcode/050-powxN/bigablecat.md deleted file mode 100644 index 1b1c9ee..0000000 --- a/_site/leetcode/050-powxN/bigablecat.md +++ /dev/null @@ -1,57 +0,0 @@ -**50. Pow(x, n)** ---- -[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) - - -* 网友高票Java解法,递归分治 - -```java - - public double myPow(double x, int n) { - //如果n==0,返回1,因为x的0次方为1 - if (n == 0) - return 1; - if (n < 0) { - //因为 n = -1*(-n),所以x的n次方等于x的-1次方的-n次方 - //所以n等于负数时进行如下两步操作 - // n = -n让n变为正 - n = -n; - //让x成为x的倒数 - x = 1 / x; - //判断原来的n值是否超出了JavaInteger的下界 - if (-n == Integer.MIN_VALUE) { - //考虑到Java语言中Integer的取值范围在-2147483648到2147483647之间 - //Integer.MIN_VALUE = -2147483648, - //Integer.MAX_VALUE = 2147483647, - //当n的值在取值范围之外,编译无法通过,不予考虑 - //当 n = -2147483648 时,让 n = -n 得到 n = 2147483648 超过了Integer.MAX_VALUE=2147483647 - //为了避免这种情况,在n = -n = 2147483648后 - //让n-1 = 2147483647,同时取出一个x,按照奇数的计算方式返回结果 - return x * myPow(x, (n - 1)); - } - } - //接下来进行分治,将求x的n次方转变为求x平方的(n/2)次方 - //判断n是否为偶数,如果是偶数,只需递归调用myPow,如果是奇数,取出一个x,再与myPow结果相乘 - return (n % 2 == 0) ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); - } - - -``` - -**复杂度分析** - -时间复杂度:O(logn), -每次递归,n就被2分一次,n/2/2..., -所以总共调用递归方法的次数是logn次, -递归方法中没有循环,只有常数级的操作, -所以总的时间复杂度是O(logn) - -空间复杂度:O(logn), -每次递归都占用O(1)的空间 - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) diff --git a/_site/leetcode/051-NQueens/melody-l.md b/_site/leetcode/051-NQueens/melody-l.md deleted file mode 100644 index b9e7f9f..0000000 --- a/_site/leetcode/051-NQueens/melody-l.md +++ /dev/null @@ -1,94 +0,0 @@ -**051. NQueens** ---- -[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) - -方法一:回溯法 -```java - -public class Solution { - public List> solveNQueens(int n) { - // 构造棋盘 - char[][] board = new char[n][n]; - // 初始化棋盘所有的棋子 - for(int i = 0; i < n; i++) - for(int j = 0; j < n; j++) - board[i][j] = '.'; - // 初始化结果集 - List> resultList = new ArrayList>(); - // 从第0列开始搜索所有结果,保存到resultList结果集中 - search(board, 0, resultList); - - return resultList; - } - - /** - * 递归获取所有的结果 - * @param board 棋盘 - * @param column 所在列 - * @param resultList 最终结果集 - */ - public void search(char[][] board, int column, List> resultList) { - // 如果最后一列已经遍历完,则将棋盘保存,添加到最终结果集中并返回 - if(column == board.length) { - resultList.add(construct(board)); - return; - } - - // 寻找第column列的哪一行适合放置皇后的位置 - for(int i = 0; i < board.length; i++) { - // 如果在第i行,第column列添加皇后能够满足棋盘的0~column列不冲突 - if(validate(board, i, column)) { - // 第i行,第column列放置一个皇后 - board[i][column] = 'Q'; - // 继续探索第column+1列适合放置皇后的位置 - search(board, column + 1, resultList); - // 重置column列的结果,继续探索其他位置的可能性 - board[i][column] = '.'; - } - } - } - - /** - * 验证将皇后放在第y列,第x行,是否可行 - * 由于棋盘的0~y-1列的皇后位置都是有效的, - * 所以验证方式为:让0~y-1列的皇后与当前的皇后比,若都不存在冲突,则有效 - * 冲突检测,正负对角线(测试斜率是否为正负一),是否同一行(不可能同列) - * @param board 棋盘 - * @param x 所在行 - * @param y 所在列 - * @return 位置是否有效 - */ - public boolean validate(char[][] board, int x, int y) { - // 从第i行开始遍历 - for(int i = 0; i < board.length; i++) { - // 从第j列开始遍历 - for(int j = 0; j < y; j++) { - // 如果此位置为皇后,且满足两点斜率为正负1或者同行,则存在冲突 - if(board[i][j] == 'Q' && (x - i == y - j || x - i == j - y || x == i)) - return false; - } - } - - return true; - } - - // 产生了一个结果集序列 - public List construct(char[][] board) { - List result = new LinkedList(); - for(int i = 0; i < board.length; i++) { - String s = new String(board[i]); - result.add(s); - } - return result; - } -} - -``` - ---- - - -**参考资料** - -* 网友推荐题解: -[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) diff --git a/_site/leetcode/051-NQueens/official.md b/_site/leetcode/051-NQueens/official.md deleted file mode 100644 index b61c943..0000000 --- a/_site/leetcode/051-NQueens/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**51. N-皇后** ---- - -[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) diff --git a/_site/leetcode/052-N-QueensII/hatrick.md b/_site/leetcode/052-N-QueensII/hatrick.md deleted file mode 100644 index b4d30b5..0000000 --- a/_site/leetcode/052-N-QueensII/hatrick.md +++ /dev/null @@ -1,61 +0,0 @@ -**52. N皇后 II** ---- - -[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) - -```java - -public class NQueenII { - private int count = 0; - - public int totalNQueens(int n) { - int[] x = new int[n]; - queens(x, n, 0); - return count; - } - - private void queens(int[] x, int n, int row) { - for (int i = 0; i < n; i++) { - //判断是否合法 - if (check(x, n, row, i)) { - //将皇后放在第row行,第i列 - x[row] = i; - //如果是最后一行,则输出结果 - if (row == n - 1) { - count++; - //回溯,寻找下一个结果 - x[row] = 0; - return; - } - //寻找下一行 - queens(x, n, row + 1); - //回溯 - x[row] = 0; - } - } - } - - /** - * @param x 数组解 - * @param n 棋盘长宽 - * @param row 当前放置行 - * @param col 当前放置列 - * @return - */ - private boolean check(int[] x, int n, int row, int col) { - for (int i = 0; i < row; i++) { - if (x[i] == col || x[i] + i == col + row || x[i] - i == col - row) { - return false; - } - } - return true; - } -} - -``` ---- - - -**参考资料** - -[https://blog.csdn.net/xygy8860/article/details/46861817](https://blog.csdn.net/xygy8860/article/details/46861817) diff --git a/_site/leetcode/052-N-QueensII/official.md b/_site/leetcode/052-N-QueensII/official.md deleted file mode 100644 index 090fa43..0000000 --- a/_site/leetcode/052-N-QueensII/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**52. N皇后 II** ---- - -[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) diff --git a/_site/leetcode/053-maximumSubarray/BambooYH.md b/_site/leetcode/053-maximumSubarray/BambooYH.md deleted file mode 100644 index 83e556f..0000000 --- a/_site/leetcode/053-maximumSubarray/BambooYH.md +++ /dev/null @@ -1,59 +0,0 @@ -**最大的子数组和** ---- -[https://leetcode.com/problems/maximum-subarray/](https://leetcode.com/problems/maximum-subarray/) - -解决方案: -方法一:**DP** -**思路** -找一个数组中,连续子数组的最大和。最暴力的解法就是两重循环,从第一个元素开始,遍历后面的元素,依次计算子数组的和。然后在从第二个元素开始遍历。这样的做法显然时间复杂度比较高,是`O(n^2)`.我们可以用动态规划的思想来解决这个问题。假设有`array[0]~array[n-1]`共n个元素,换个角度来看问题,我们也就是求分别以`array[i]`结尾的子数组的最大和。如果我们求以`array[n-1]`结尾的子数组最大和`Sum(n-1)`,我们可以先求`array[n-2]`结尾的子数组最大和`Sum(n-2)`,如果这个`Sum(n-2)>0`,那么说明这段子数组对后面的数组一定有贡献,因为这个数是个正数。n -**算法** -从左向右遍历,依次计算以`array[i]`为结尾的子数组的最大和。在遍历的过程中,用一个变量`max`记录曾经出现过的最大值。遍历完成后返回`max`。 -``` -public class Solution { - public int maxSubArray(int[] A) { - int n = A.length; - //创建一个跟原数组等大小的辅助数组dp,dp[i]表示以A[i]结尾的子数组的最大和 - int[] dp = new int[n]; - //初始化dp[0],因为以A[0]结尾的子数组的最大和就是A[0] - dp[0] = A[0]; - //记录遍历过程中出现过的最大值 - int max = dp[0]; - - for(int i = 1; i < n; i++){ - //如果dp[i-1]>0,那么dp[i] = dp[i-1]+A[i],因为dp[i-1]是个正数,所以对dp[i]有贡献 - dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0); - //记录当前出现的最大值 - max = Math.max(max, dp[i]); - } - - return max; - } -} -``` -复杂度分析: -n表示数组的长度 -空间复杂度:O(1) -时间复杂度:O(n) - -上面定义了一个DP数组是为了方便理解,其实上面的DP数组可以用一个变量`cur`来表示,代码如下: -``` -public class Solution { - public int maxSubArray(int[] A) { - int n = A.length; - int cur = A[0]; - int max = A[0]; - - for(int i = 1; i < n; i++){ - cur = cur > 0 ? A[i]+cur : A[i]; - max = Math.max(max, cur); - } - - return max; - } -} -``` - -复杂度分析: -n表示数组的长度 -空间复杂度:O(1) -时间复杂度:O(n) \ No newline at end of file diff --git a/_site/leetcode/053-maximumSubarray/official.md b/_site/leetcode/053-maximumSubarray/official.md deleted file mode 100644 index e50ab30..0000000 --- a/_site/leetcode/053-maximumSubarray/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**53. 最大子序和** ---- -[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/062-UniquePaths/BambooYH.md b/_site/leetcode/062-UniquePaths/BambooYH.md deleted file mode 100644 index c42de98..0000000 --- a/_site/leetcode/062-UniquePaths/BambooYH.md +++ /dev/null @@ -1,64 +0,0 @@ -**不同路径** - -[https://leetcode.com/problems/unique-paths/](https://leetcode.com/problems/unique-paths/) - -方法一:**动态规划** -**思路** -这道题是一道特别经典的动态规划题,而且有助于理解动态规划。首先分析题意,这部是最重要的,只有认真分析题意,才可以找出正确的状态转移方程。首先题目要求从左上角,走到右下角。在每次移动的过程中,只有两个方向可以选择,要么往右走,要么往下走。这是非常关键的,也就是说,如果我们走到了`array[i][j]`这个点,那上一步要么在这个点的上边`array[i-1][j]`,要么在这个点的左边`array[i][j-1]`,只有这两种情况。换句话说,如果我们用dp[i][j]表示到array[i][j]这个点的路径数,那么`dp[i][j] = dp[i-1][j] + dp[i][j-1]`,这个肯定是正确的,因为只有上述描述的两种情况。 - -**算法** -我们从上到下,从左到右遍历,然后利用公式`dp[i][j] = dp[i-1][j] + dp[i][j-1]`算出最终结果。 -``` -class Solution { - public int uniquePaths(int m, int n) { - int[][] dp = new int[m][n]; - //初始化,到达dp[0][j]只有1条路径,因为只能往右和下走 - for(int i = 0; i < n; i++) { - dp[0][i] = 1; - } - //初始化,到达dp[i][0]只有一条路径 - for(int i = 0; i < m; i++) { - dp[i][0] = 1; - } - //遍历 - for(int i = 1; i < m; i++) { - for(int j = 1; j < n; j++) { - dp[i][j] = dp[i-1][j] + dp[i][j-1]; - } - } - - return dp[m-1][n-1]; - } -} -``` -复杂度分析: -假设矩阵的行数为M,列数为N -时间复杂度:O(M*N) - -空间复杂度:O(M*N) - -## 优化 -上述代码可以进行空间优化,我们可以看到,dp[i][j]只与两个数值有关,而且这两个数值,一个是它左边的,一个是它右边的,所以我们可以只用一个大小为n的一维数组。具体代码如下 -``` -class Solution { - public int uniquePaths(int m, int n) { - int[] dp = new int[n]; - //初始化 - for(int i = 0; i < n; i++) { - dp[i] = 1; - } - for(int i = 1; i < m; i++) { - for(int j = 1; j < n; j++) { - //右边的dp[j]其实就相当于dp[i-1][j],因为这个值是更新之前的值,dp[j-1]相当于dp[i][j-1]. - dp[j] = dp[j-1] + dp[j]; - } - } - - return dp[n-1]; - } -} -``` -复杂度分析: -假设矩阵的行数为M,列数为N -时间复杂度:O(M*N) -空间复杂度:O(N) \ No newline at end of file diff --git a/_site/leetcode/062-UniquePaths/official.md b/_site/leetcode/062-UniquePaths/official.md deleted file mode 100644 index 4cd834b..0000000 --- a/_site/leetcode/062-UniquePaths/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**62. 不同路径** ---- -[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) diff --git a/_site/leetcode/063-UniquePathsII/SpecialYang.md b/_site/leetcode/063-UniquePathsII/SpecialYang.md deleted file mode 100644 index f182475..0000000 --- a/_site/leetcode/063-UniquePathsII/SpecialYang.md +++ /dev/null @@ -1,115 +0,0 @@ -63.不同的路径Ⅱ ---- -https://leetcode.com/problems/unique-paths-ii/ -题目的意思是给定一个网格,机器人从左上角开始走,走到右下角一共有多少种步数,同时网格中可能有障碍物。机器人的方向只能向右和向左两种走法,显然当前位置的可以由它的上和左方向走来,所以这是经典的动态规划问题。 -### 思路一 -因为考虑障碍物,所以状态方程如下: -```math -dp[i][j] = dp[i][j - 1] + dp[i]- 1][j], \; -\;if grid[i][j] == 0 - -dp[i][j] = 0, \;\; if grid[i][j] = 1 -``` -我们这里额外引入空间来存放到第i行,第j列的走法 -``` - /** - * 当前格子只能由它的上面和左边过来 - * 所以状态转移方程为: - * dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - * dp[i][j] = 0, if obstacle - * @param obstacleGrid - * @return - */ - public int uniquePathsWithObstacles1(int[][] obstacleGrid) { - int m = obstacleGrid.length; - int n = obstacleGrid[0].length; - //额外空间,用于方便处理边界 - int[][] dp = new int[m + 1][n + 1]; - dp[1][0] = 1; - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (obstacleGrid[i - 1][j - 1] == 0) { - dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; - } - } - } - return dp[m][n]; - } -``` -#### 复杂度 -- 时间复杂度:O(m `$\times$` n) -- 空间复杂度:O(m `$\times$` n) -### 思路二 -对状态方程进行优化,压缩状态 -``` - /** - * dp[i][j]仅依赖它的上方和左边两个状态 - * 所以压缩状态,dp[i - 1]对应dp[i][j - 1], dp[i]对应dp[i - 1][j] - * - * 注意每一行的第0列特殊处理一下 - * @param obstacleGrid - * @return - */ - public int uniquePathsWithObstacles3(int[][] obstacleGrid) { - int m = obstacleGrid.length; - int n = obstacleGrid[0].length; - //额外空间,用于方便处理边界 - int[] dp = new int[n + 1]; - dp[0] = 1; - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (obstacleGrid[i - 1][j - 1] == 0) { - dp[j] = (i != 1 && j == 1 ? 0 : dp[j - 1]) + dp[j]; - } else { - //这里要归0,因为会被下一个行作为头部使用 - dp[j] = 0; - } - } - } - return dp[n]; - } -``` -#### 复杂度 -- 时间复杂度:O(m `$\times$` n) -- 空间复杂度:O(n) - -### 思路三 -我们不需要额外的空间,用网格本身来作dp状态。 -- 首先我们对第0行和第0列进行特殊处理,判断每一个位置之前值是否为1(表示路径可达),然后看当前位置是否是障碍物。若不是障碍物,则当前值设置为1,表示可达;否则设置为0,表示不可达。我们可以看到对于为1的障碍物我们都清0,因为此时0代表路径数,其实就是不可达。 -- 对第0列也进行同样的处理 -- 从第1行开始,从每行的第1列开始,遍历判断当前位置的值是不是障碍物,若是,则设置0,表示不贡献路径数,否则为头部和左边的和 - -```java - /** - * 用网格自身作为dp - * @param obstacleGrid - * @return - */ - public int uniquePathsWithObstacles2(int[][] obstacleGrid) { - int m = obstacleGrid.length; - int n = obstacleGrid[0].length; - if (obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) { - return 0; - } - obstacleGrid[0][0] = 1; - for (int i = 1; i < n; i++) { - obstacleGrid[0][i] = (obstacleGrid[0][i - 1] == 1 && obstacleGrid[0][i] == 0) ? 1 : 0; - } - for (int i = 1; i < m; i++) { - obstacleGrid[i][0] = (obstacleGrid[i - 1][0] == 1 && obstacleGrid[i][0] == 0) ? 1 : 0; - } - for (int i = 1; i < m; i++) { - for (int j = 1; j < n; j++) { - if (obstacleGrid[i][j] == 0) { - obstacleGrid[i][j] = obstacleGrid[i][j - 1] + obstacleGrid[i - 1][j]; - } else { - obstacleGrid[i][j] = 0; - } - } - } - return obstacleGrid[m - 1][n - 1]; - } -``` -#### 复杂度 -- 时间复杂度:O(m `$\times$` n) -- 空间复杂度:O(1) \ No newline at end of file diff --git a/_site/leetcode/063-UniquePathsII/official.md b/_site/leetcode/063-UniquePathsII/official.md deleted file mode 100644 index 7c71971..0000000 --- a/_site/leetcode/063-UniquePathsII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**63. 不同路径 II** ---- -[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) diff --git a/_site/leetcode/064-minimumPathSum/melody-l.md b/_site/leetcode/064-minimumPathSum/melody-l.md deleted file mode 100644 index f81c6a3..0000000 --- a/_site/leetcode/064-minimumPathSum/melody-l.md +++ /dev/null @@ -1,54 +0,0 @@ -**064. MinimunPathSum** ---- -[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) - -方法一:动态规划 - -由于题目规定,每次只能向下或者向右移动一步。因此,对于(i,j)的最小路径,只能从左边(i, j-1)和上边(i-1, j)中选择最小的路径。所以递推式为: -设(i,j)所在位置的权重为V(i,j),最小路径为A(i,j),则: -* 若i=0 且 j!=0, A(i, j) = A(i-1, j) + V(i, j) -* 若i!=0 且 j=0, A(i, j) = A(i, j-1) + V(i, j) -* 若i!=0 且 j!=0, A(i ,j) = Min{A(i-1, j) , A(i, j-1)} + V(i, j) -* 若i=0 且 j=0, A(i, j) = V(i, j) - -由于A(i, j)是依赖于左上角的,所以从左上角的(0,0)开始向右计算,这样能够保证所有的(i,j)递推式中依赖的值都已经被计算了。 -```java - -public class Solution { - // 复用grid, - // gird中数组的数值经过计算保存由<0,0>到达该点的最小路径和 - public int minPathSum(int[][] grid) { - int row = grid.length;// 行 - int column = grid[0].length; // 列 - // 按照顺序遍历 - for (int i = 0; i < row; i++) { - for (int j = 0; j < column; j++) { - if (i == 0 && j != 0) { // 如果是第一行的 - // 路径只能是从左边出发的 - grid[i][j] = grid[i][j] + grid[i][j - 1]; - } else if (i != 0 && j == 0) { //如果是第一列的 - // 路径只能是从上面出发的 - grid[i][j] = grid[i][j] + grid[i - 1][j]; - } else if (i == 0 && j == 0) { //如果是起点 - grid[i][j] = grid[i][j]; - } else { // 非第一行和第一列的 - // 能到达这个位置, - // 只能由这个位置上面,或者这个位置左边到达了 - // 因此选择上面路径和最小的相加 - grid[i][j] = Math.min(grid[i][j - 1], grid[i - 1][j]) + grid[i][j]; - } - } - } - // 遍历完后,返回最后一个的值 - return grid[row - 1][column - 1]; - } -} - - -``` - ---- - -**参考资料** -* 网友推荐题解: -[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) diff --git a/_site/leetcode/064-minimumPathSum/official.md b/_site/leetcode/064-minimumPathSum/official.md deleted file mode 100644 index ce1339d..0000000 --- a/_site/leetcode/064-minimumPathSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**64. 最小路径和** ---- -[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) diff --git a/_site/leetcode/069-SqrtX/official.md b/_site/leetcode/069-SqrtX/official.md deleted file mode 100644 index b9d2b1f..0000000 --- a/_site/leetcode/069-SqrtX/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**69. x 的平方根** ---- - -[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) diff --git a/_site/leetcode/070-ClimbingStairs/melody-l.md b/_site/leetcode/070-ClimbingStairs/melody-l.md deleted file mode 100644 index ac89d60..0000000 --- a/_site/leetcode/070-ClimbingStairs/melody-l.md +++ /dev/null @@ -1,113 +0,0 @@ -**070. ClimbingStairs** ---- -[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) - -首先判断该问题是否为dp问题。 -对于台阶问题,由于只能走一步或者两步,所以对于N级台阶,很明显得到,第N级台阶的方法数 = 第N-1级台阶方法数 + 第N-2级台阶方法数。即第N级的“最优决策”只与N-1的“最优决策”和N-2的“最优决策”有关,即满足最优子结构和无后效性,而本身问题是有界的,因此该问题为dp问题。 -令F(n)表示n级台阶的方法数,则有: -* F(n) = F(n-1) + F(n-2) (n>=3), -* F(1) = 1 -* F(2) = 2 - -方法一:递推式的递归版本 - -```java - -public class Solution { - /** - * 递推公式,使用递归的实现 - * @param n 问题中的台阶数 - * @return 返回总步数 - */ - public int climbStairs(int n) { - if (n > 2) - return climbStairs(n - 1) + climbStairs(n - 2);// 递推公式递归 - - if (n == 2) - return 2; // 当n=2 - else if (n == 1) - return 1;// 当n=1 - - return 0; - } -} - -``` - -方法二:递推式的递归缓存版 - -递归中存在重复的计算,例如:当n=5时, -* F(5) = F(4)+F(3) -* F(4) = F(3)+F(2) -此时,F(3)重复计算了一次,因此可以在这个地方添加缓存保存中间值。 - -```java - -public class Solution { - /** - * 递推公式,使用递归的实现,添加缓存(又称记忆化搜索)。 - * @param n 问题中的台阶数 - * @return 返回总步数 - */ - public int climbStairs(int n) { - int[] cache = new int[n + 1]; // step从1开始,所以为了方便理解,cache从位置1开始缓存数据 - return doClimbStairs(n, cache); - } - - public int doClimbStairs(int step, int[] cache) { - if (step == 2) - return 2; // 当n=2 - else if (step == 1) - return 1;// 当n=1 - - if (cache[step] > 0) // int[] 初始化默认值为全0,若缓存命中则值大于0 - return cache[step]; // 命中直接返回 - else { - cache[step] = doClimbStairs(step - 1, cache) + doClimbStairs(step - 2, cache);// 未命中,使用递推公式递归 - return cache[step]; //返回结果 - } - } -} - -``` - -方法三:递推式非递归版本 -因为F(n) = F(n-1) + F(n-2) (n>=3)。 -所以,该式子的计算过程是可以用数组表示的,数组的位置为n的值是位置为n-1的值与位置n-2的值之和。 -所以算法思路为:顺序遍历数组,取数组当前位置的前两个位置的值相加赋值给当前位置。 - -```java - -public class Solution { - // 递推公式,非递归版本 - public int climbStairs(int n) { - if (n == 1) - return 1; // 算法思路数组长度至少为2,所以1时直接返回结果 - - // 构造int[] result;存储爬n个台阶的方法数,为了方便对应,所以长度取n+1 - // 如果不希望每一步的结果都被记录,则只需要int result;存储每个阶段的值, - // 循环到n结束的时候将最终结果返回即可 - int[] result = new int[n + 1]; - int start = 1; // 第1个台阶 - int end = 2; // 第2阶台阶 - result[start] = 1; // 第1个台阶方法数为1 - result[end] = 2;// 第2个台阶方法数为2 - - for (int i = 3; i <= n; i++) { - result[i] = result[i - 1] + result[i - 2]; // 第i个台阶数为前两个台阶的方法数之和 - } - - return result[n]; - } -} - -``` - ---- - - -**参考资料** -* 斐波那契数列的数学公式: -[https://blog.csdn.net/beautyofmath/article/details/48184331](https://blog.csdn.net/beautyofmath/article/details/48184331) -* 官方题解: -[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) diff --git a/_site/leetcode/070-ClimbingStairs/official.md b/_site/leetcode/070-ClimbingStairs/official.md deleted file mode 100644 index 1d51693..0000000 --- a/_site/leetcode/070-ClimbingStairs/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**70. 爬楼梯** ---- -[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) diff --git a/_site/leetcode/072-EditDistance/official.md b/_site/leetcode/072-EditDistance/official.md deleted file mode 100644 index ac7654f..0000000 --- a/_site/leetcode/072-EditDistance/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**72. 编辑距离** ---- -[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) diff --git a/_site/leetcode/075-SortColors/bigablecat.md b/_site/leetcode/075-SortColors/bigablecat.md deleted file mode 100644 index 1daac68..0000000 --- a/_site/leetcode/075-SortColors/bigablecat.md +++ /dev/null @@ -1,67 +0,0 @@ -**75. 颜色分类** ---- -[https://leetcode-cn.com/problems/sort-colors/](https://leetcode-cn.com/problems/sort-colors/) - -* 网友高票答案: - -```java - - /** - * https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution - * 网友高票答案 - * - * @param A - */ - public void sortColors(int A[]) { - // 定义整数second代表数字2蓝色,zero代表数字0红色 - // 本方法的思路是将数字2蓝色后移到数组的右侧 - // 数字0红色前移到数组左侧 - // 剩余数字1白色在移动过程中也聚集到了中间 - // second初始值为n-1,即数组A下标的上限 - // zero初始值为0,即数组A下标的下限 - int second = A.length - 1, zero = 0; - //从左向右遍历数组A - for (int i = 0; i <= second; i++) { - //如果当前元素A[i]为2蓝色,且下标i比second小 - //交换当前元素A[i]和A[second]在数组A中的位置 - //second--作为参数传入swap方法,递减是在swap方法结束之后才进行的 - //所以swap方法中操作的是A[second] - while (A[i] == 2 && i < second) swap(A, i, second--); - //如果当前元素A[i]为0白色,且下标i比zero大 - //交换当前元素A[i]和A[zero]在数组A中的位置 - //zero++作为参数传入swap方法,递增是在swap方法结束之后才进行的 - //所以swap方法中操作的是A[zero] - while (A[i] == 0 && i > zero) swap(A, i, zero++); - } - } - - /** - * swap方法,交换数组中两个元素的位置 - * - * @param nums 数组 - * @param i 左侧元素的下标 - * @param j 右侧元素的下标 - * @return - */ - public int[] swap(int[] nums, int i, int j) { - //定义一个临时变量存放右侧元素 - int temp = nums[j]; - //将左侧元素赋值给右侧元素 - nums[j] = nums[i]; - //将临时变量存储的原右侧元素赋值给左侧元素 - nums[i] = temp; - //返回交换后的数组 - return nums; - } - -``` - -**复杂度分析** - -空间复杂度:O(1), -只定义了3个整型变量,没有使用更多额外空间,空间复杂读是O(1) - -**参考资料** - -* 网友高票答案: -[https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution](https://leetcode.com/problems/sort-colors/discuss/26472/Share-my-at-most-two-pass-constant-space-10-line-solution) diff --git a/_site/leetcode/075-SortColors/official.md b/_site/leetcode/075-SortColors/official.md deleted file mode 100644 index d7e50c9..0000000 --- a/_site/leetcode/075-SortColors/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**75. 颜色分类** ---- -[https://leetcode-cn.com/problems/sort-colors/](https://leetcode-cn.com/problems/sort-colors/) diff --git a/_site/leetcode/085-MaximalRectangle/passself.md b/_site/leetcode/085-MaximalRectangle/passself.md deleted file mode 100644 index 187fb26..0000000 --- a/_site/leetcode/085-MaximalRectangle/passself.md +++ /dev/null @@ -1,189 +0,0 @@ -#85. 最大矩形 - -Leetcode 地址 [https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) - -**题目分析** - -该题目需要有两种结题方式,第一种是利用dp动态规划,第二种是用栈的思路。dp的方式[参考](https://leetcode.com/problems/maximal-rectangle/discuss/29054/share-my-dp-solution)。 - -**思路:** - -已知二维二进制矩阵 - -``` -["1","0","1","0","0"], -["1","0","1","1","1"], -["1","1","1","1","1"], -["1","0","0","1","0"] -``` - -1.定义三个数组 - -**left[]:** 从左到右,连续出现"1"的string 的第一个坐标 - -**right[]:** 从右到左, 连续出现"1"的最后一个坐标 - -**height[]:** 从上到下的高度 - -**result:** (right[i] - left[i]) * heights[i] 其实就是计算面积 (right[i] - left[i])就是宽度 - -height 过程: - -``` -1 0 1 0 0 -2 0 2 1 1 -3 1 3 2 2 -4 0 0 3 0 -``` - -left : - -``` -0 0 2 0 0 -0 0 2 2 2 -0 0 2 2 2 -0 0 0 3 0 -``` -right: - -``` -1 5 3 5 5 -1 5 3 5 5 -1 5 3 5 5 -1 5 5 4 5 -``` -3. - -**具体代码** - -``` -class Solution { - public int maximalRectangle(char[][] matrix) { - if (matrix == null || matrix.length == 0) return 0; - int m = matrix.length; - int n = matrix[0].length; - int result = 0; - int height[] = new int[n]; - int left[] = new int[n]; - int right[] = new int[n]; - Arrays.fill(right,n); - - for (int i = 0; i < m; i++) { - //curLeft 每一行的下标 类似index - int curLeft = 0,curRight = n; - for (int j = 0; j < n; j++) { - if (matrix[i][j] == '1') height[j] ++; - else height[j] = 0; - } - - for (int j = 0; j < n; j++) { - if (matrix[i][j] == '1'){ - left[j] = Math.max(curLeft,left[j]); - }else { - left[j] = 0; - curLeft = j + 1; - } - } - - for (int j = n- 1; j >= 0; j--) { - if (matrix[i][j] == '1'){ - right[j] = Math.min(curRight,right[j]); - }else{ - right[j] = n; - curRight = j; - } - } - - for (int j = 0; j< n;j++){ - result = Math.max(result,(right[j] - left[j]) * height[j]); - } - } - - return result; - } -} -``` -**时间复杂度** O(N*N) - -leetcode 代码提交后发现击败了98%的commit - -**第二种解法** - -第二种解法是使用栈。基本思路来源就是84题。我们可以这样想想,从每一行来看。每一行对应的矩阵的高度其实就相当于是当前行的直方图,也就相当于求直方图中最大面积。这样一来就和84解法一样了。 - -思路解析 - -将两行加在一起,例如下面两行 - -``` -1 0 1 0 0 -1 0 1 1 1 -``` -加起来得到 - -``` -2 0 2 1 1 -``` -那么这两行的最大长方形要不就是2,要不就是衡向的三个1,那么如果是三行的结果是怎样的 - -``` -1 0 1 0 0 -1 0 1 1 1 -1 1 1 1 1 -``` -加起来得到 - -``` -3 1 3 2 2 -``` -这个结果可以看出,这里就将上面的矩阵表现成为了一个柱状图,值就是它的高度利用leetcode 84的代码 - -``` -private int largestRectangleArea(int[] heights) { - int max = 0, n = heights.length; - int[] small_left = new int[n]; - int[] small_right = new int[n]; - small_left[0] = -1; - small_right[n-1] = n; - for ( int i = 1; i < n; i++ ) { - int idx = i - 1; - while ( idx >= 0 && heights[idx] >= heights[i] ) - idx = small_left[idx]; - small_left[i] = idx; - } - for ( int i = n - 2; i >= 0; i-- ) { - int idx = i + 1; - while ( idx < n && heights[idx] >= heights[i] ) - idx = small_right[idx]; - small_right[i] = idx; - } - for ( int i = 0; i < n; i++ ) { - int area = (small_right[i] - small_left[i] - 1) * heights[i]; - if ( area > max ) - max = area; - } - return max; -} -``` - -计算leetcode 85的最大长方形结果 - -``` -public int maximalRectangle(char[][] matrix) { - if ( matrix == null || matrix.length == 0 ) return 0; - int m = matrix.length, n = matrix[0].length, max = 0; - int[] row_sum = new int[n]; - for ( int i = 0; i < m; i++ ) { - for ( int j = 0; j < n; j++ ) - // 遇到0重置,1累加 - row_sum[j] = ('0' == matrix[i][j]) ? 0 : row_sum[j] + 1; - int area = largestRectangleArea(row_sum); - if ( area > max ) - max = area; - } - return max; -} - -``` - - diff --git a/_site/leetcode/087-ScrambleString/official.md b/_site/leetcode/087-ScrambleString/official.md deleted file mode 100644 index 8b79f8e..0000000 --- a/_site/leetcode/087-ScrambleString/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**87. 扰乱字符串** ---- -[https://leetcode-cn.com/problems/scramble-string/](https://leetcode-cn.com/problems/scramble-string/) diff --git a/_site/leetcode/091-DecodeWays/melody-l.md b/_site/leetcode/091-DecodeWays/melody-l.md deleted file mode 100644 index 08615ca..0000000 --- a/_site/leetcode/091-DecodeWays/melody-l.md +++ /dev/null @@ -1,73 +0,0 @@ -**091. DecodeWays** - ---- -[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) - -* 该问题细节太多,需要对0参与的情况进行特殊考虑。 -1. 求递推式 -设result[i]表示前i+1项字符能构成的解码个数总数。 -* 若第i-1项与第i项组合,不能够小于26,则result[i]的加入不能够增加解码个数的总数,因为其只能作为单项列出来然后加入到之前的所有组合里面,因此result[i] = result[i-1]; -* 若第i-1项与第i项组合,能够小于等于26,则result[i]的加入能够增加解码个数。增加的解码个数是将i-1与i作为一个整体插入到i-2序列中会产生的解码个数。即result[i] = result[i-1] + result[i-2]; -2. 特殊情况说明 -因为提供的数据中存在有0的情况,这个需要单独拿出来看。题目示例没有给0所对应的例子。此处列举几例:`10解码只有1种,即10`,`100解码只有0种,因为10,0并不能被解码`,`101解码只有1中,因为01不能被当作1来看待`,`301解码只有0种,因为30没有对应的值,01不能被当作1来看待`。 -3. 算法思路 -递推式中的i>=2,所以先确定i=0,i=1的情况。然后顺序遍历数组后面的值,根据递推式相加即可。唯一需要针对有0的进行特殊考虑。 - - ---- - -方法一:动态规划 - -```java - -public class Solution { - public int numDecodings(String s) { - // String转为char数组进行计算 - char[] problem = s.toCharArray(); - // result[i]表示索引为i时, - // 前i+1项char数组所构成的String字符串的解码总数 - int[] result = new int[problem.length]; - - // 如果第一个字母为0,则一定不能解码, - // '01'是不能作为'1'解码的 - if (problem[0] == '0') - return 0; - // 如果第一个字母不为0,长度为1,则解码的方式有1种 - else if (problem.length == 1) - return 1; - - // 下面探讨:长度>=2 且 首字母不为'0'的情况 - // 索引为0的解码总数为1 - result[0] = 1; - // result[1]的值进行分类探讨,此时首字母肯定不为0, - if (problem[1] == '0' && problem[0] >= '3') { - // 类似于'30'开头,解码总数为0 - return 0; - } else if (problem[1] != '0' && problem[1] + problem[0] * 10 <= 554) { - // 类似于'12',解码总数为2 - result[1] = 2; - } else { - // 类似于'34'和'20' - result[1] = 1; - } - - for (int i = 2; i < problem.length; i++) { - if (problem[i] == '0' && (problem[i - 1] >= '3' || problem[i - 1] <= '0')) - // 带0,且与前面的组合不能够小于26,类似于'00'或者'30'这种 - return 0; - else if (problem[i] == '0' && problem[i - 1] < '3') - // 带0,且与前面的组合能够小于26,类似于'20'这种 - result[i] = result[i - 2]; - else if (problem[i - 1] != '0' && problem[i] + problem[i - 1] * 10 <= 554) - // 不带0,且与前面的组合能够小于26 - result[i] = result[i - 1] + result[i - 2]; - else - // 不带0,且与前面的组合不能够小于26 - result[i] = result[i - 1]; - } - - return result[problem.length - 1]; - } -} - -``` diff --git a/_site/leetcode/091-DecodeWays/official.md b/_site/leetcode/091-DecodeWays/official.md deleted file mode 100644 index 7e1c57f..0000000 --- a/_site/leetcode/091-DecodeWays/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**91. 解码方法** ---- -[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) diff --git a/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md b/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md deleted file mode 100644 index 5f84f3a..0000000 --- a/_site/leetcode/095-UniqueBinarySearchTreesII/melody-l.md +++ /dev/null @@ -1,82 +0,0 @@ -**095.UniqueBinarySearchTreesII** ---- -[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) - -方法一:动态规划+递归 -对于二叉搜索树,其左子树中的所有节点的值都小于根节点,右子树的所有节点的值都大于根节点。因此,该问题可以转为 -* 对于从1到n的序列A={1...n},求以i为根节点的所有二叉搜索树集合(其中,i>=1 且 i<=n)。 - -设以i为根节点的所有二叉树集合为F(i),很显然,F(i)的结果为:`{1...i-1}的可能BTS集合`和`{i+1...n}的可能BTS集合`的`笛卡尔积`。此时,这个问题又回归到了初始问题(求1到n的BTS集合)。这种再次回归到初始问题的就可以采用递归的办法解决。 - -当然,该问题经过不断递归是有解的。因为不断的递归之后,问题域的size是逐渐减小的。当size==1的时候,问题是可解的(此时,集合只有一个节点,所有的BTS组合唯一)。 - -综上,dp思路为: -设`F(start, end)`表示从start到end序列的所有BTS可能性的集合。则 `F(start, end)={ F(start, i-1) × F(i+1, end) | i属于{1, ... ,n} }`,此处`×`表示笛卡尔积。 - -```java -class Solution { - public List generateTrees(int n) { - // 测试用例中存在n=0的情况 - if (n <= 0) - return new ArrayList(); - - return getTrees(1, n); - } - - /** - * 获取从start到end的所有二叉搜索树集合 - * @param start 起始位置 - * @param end 终点位置 - * @return 从start到end之间的所有Tree组合的集合 - */ - private List getTrees(int start, int end) { - - List list = new LinkedList(); - - // 若上层递归root结点该方向无节点,则递归到此处 - if (start > end) { - list.add(null); - return list; - } - - // 若上层递归root结点该方向存在一个结点,则递归到此处 - // 这一步是可以省略的, - // 因为当start==end的时候,后面的循环递归的逻辑与该处逻辑等价 - // 这里提前返回,避免再次进入start>end的递归 - if (start == end) { - list.add(new TreeNode(start)); - return list; - } - - List leftNodeList, rightNodeList; - for (int i = start; i <= end; i++) { - // 获取start到i-1的所有二叉搜索树 - leftNodeList = getTrees(start, i - 1); - // 获取i+1到end的所有二叉搜索树 - rightNodeList = getTrees(i + 1, end); - // 获取到当根节点为i的左二叉搜索树和右二叉搜索树的所有情况 - // 遍历左BST与右BST组合的所有情况, - // 将所有情况都与root结合为一个二叉搜索树 - for (TreeNode leftNode : leftNodeList) { - for (TreeNode rightNode : rightNodeList) { - TreeNode root = new TreeNode(i); - root.left = leftNode; - root.right = rightNode; - list.add(root); - } - } - } - - return list; - } -} - -``` - ---- - - -**参考资料** - -* 官方题解: -[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) diff --git a/_site/leetcode/095-UniqueBinarySearchTreesII/official.md b/_site/leetcode/095-UniqueBinarySearchTreesII/official.md deleted file mode 100644 index ad28ab8..0000000 --- a/_site/leetcode/095-UniqueBinarySearchTreesII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**95. 不同的二叉搜索树 II** ---- -[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) diff --git a/_site/leetcode/096-uniqueBinarySearchTrees/official.md b/_site/leetcode/096-uniqueBinarySearchTrees/official.md deleted file mode 100644 index 0c96b15..0000000 --- a/_site/leetcode/096-uniqueBinarySearchTrees/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**96. 不同的二叉搜索树** ---- -[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) diff --git a/_site/leetcode/097-InterleavingString/official.md b/_site/leetcode/097-InterleavingString/official.md deleted file mode 100644 index a9c0de4..0000000 --- a/_site/leetcode/097-InterleavingString/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**97. 交错字符串** ---- -[https://leetcode-cn.com/problems/interleaving-string/](https://leetcode-cn.com/problems/interleaving-string/) diff --git a/_site/leetcode/098-validateBinarySearchTree/BambooYH.md b/_site/leetcode/098-validateBinarySearchTree/BambooYH.md deleted file mode 100644 index c57425e..0000000 --- a/_site/leetcode/098-validateBinarySearchTree/BambooYH.md +++ /dev/null @@ -1,47 +0,0 @@ -**98 判断叉查找树是否有效** ---- -[https://leetcode.com/problems/validate-binary-search-tree/](https://leetcode.com/problems/validate-binary-search-tree/) - -解决方案: -方法一:**栈、中序遍历** -**思路** -首先,我们要知道二叉搜索树的特点。 -- 若左子树不为空,则左子树节点值小于根节点的值 -- 若右字树不为空,则右字树节点值大于根节点的值 -- 任意节点的左右字树也为二叉搜索树 -- 没有键值相等的节点 -- [参考wiki](https://zh.wikipedia.org/zh-cn/%E4%BA%8C%E5%85%83%E6%90%9C%E5%B0%8B%E6%A8%B9) - -所以了解了二叉搜索树的特点之后,我们可以知道,中序遍历二叉搜索树,得到的是一个递增的序列。所以此题只需进行中序遍历,判断是否是一个递增序列就可以了。 -**算法** -采用非递归的方式进行中序遍历,在遍历的过程中,判断是否是一个递增的序列,如果不是,则返回false -**代码** -``` -class Solution { - public boolean isValidBST(TreeNode root) { - if(root == null) - return true; - Stack stack = new Stack(); - TreeNode pre = null; - while(root != null || !stack.isEmpty()) { //当左子节点存在的时候,将左子节点加入栈中 - while(root != null) { - stack.push(root); - root = root.left; - } - //弹出栈顶节点 - root = stack.pop(); - //如果当前节点小于等于前一个节点的值,则返回false - if(pre != null && root.val <= pre.val) - return false; - //将pre指向当前节点 - pre = root; - //继续遍历当前节点的右子节点 - root = root.right; - } - return true; - } -} -``` -复杂度分析 -空间复杂度:O(h),h表示当前树的树高,最坏情况下为n,平均为logn -时间复杂度:O(n), 当前树的节点的总数 diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md deleted file mode 100644 index 38bbe84..0000000 --- a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md +++ /dev/null @@ -1,121 +0,0 @@ -**二叉树的层序遍历** ---- -https://leetcode.com/problems/binary-tree-level-order-traversal/ - -其实二叉树层序遍历本身不难,只需一个队列,不断从根节点插入,然后弹出队列,并把其孩子节点再插入即可。你只要保证了从根->下的顺序,从左—>右的顺序,即就保证了层序。空想很难,不妨自己画个简单的二叉树,演练一遍即可。 -**难点在于如何使得按行打印呢**,也就说打印顺序不变,但是要把属于一行的节点放在一起。 - -### 思路一 -还是借助队列,只不过我们每次弹出时,都会记录下当前队列的长度。为什么这样做呢?因为当前长度正是这一层所有的节点数,然后我们再把其他们的所有的孩子节点加入队列,同样下一次弹出时,记录下队列长度,这时又是当前层的节点数。 - -以上的技巧需要你从根节点开始保证: -1. 根节点入队列 -2. 记录当前队列的长度,为1,当前层为1个节点 -3. 开始加入根节点左右孩子 -4. 记录当前队列的长度,为2,当前层为2个节点 -5. 开始加入他们的左右孩子 -6. 一直到队列为空 - -```java - /** - * 最不费脑的一个方法,推荐 - * @param root - * @return - */ - public List> levelOrder1(TreeNode root) { - List> result = new LinkedList<>(); - Queue queue = new LinkedList<>(); - if (root == null) { - return result; - } - queue.offer(root); - while (!queue.isEmpty()) { - int size = queue.size(); - List level = new LinkedList<>(); - while (size-- > 0) { - TreeNode node = queue.poll(); - level.add(node.val); - if (node.left != null) { - queue.offer(node.left); - } - if (node.right != null) { - queue.offer(node.right); - } - } - result.add(level); - } - return result; - } -``` - -#### 思路二 -双指针法。 -last指向当前层最后一个,nLast指向下一层最后一个。 -当队列弹出的节点等于last时,说明当前层遍历完毕,这时需更新last为nLast的层。 -nLast的更新则只需在添加孩子时,更新它即可,因为这些操作都是设计到下一层。 -```java - /** - * 双指针法 - * @param root - * @return - */ - public List> levelOrder2(TreeNode root) { - List> result = new LinkedList<>(); - Queue queue = new LinkedList<>(); - if (root == null) { - return result; - } - queue.offer(root); - TreeNode last = root, nLast = null; - List level = new LinkedList<>(); - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - level.add(node.val); - if (node.left != null) { - queue.offer(node.left); - nLast = node.left; - } - if (node.right != null) { - queue.offer(node.right); - nLast = node.right; - } - if (node == last) { - last = nLast; - result.add(level); - level = new LinkedList<>(); - } - } - return result; - } -``` - -### 思路三 -DFS,我们都知道层次遍历最符合BFS的方式。但就要是搞事情,此解法来自评论区。 -我们DFS时,会带上树高,若存放本层的节点的容器未创建,则创建,否则直接插入。DFS的遍历保证了同一层的左边的节点先于右边的节点。 -所以从根节点到叶子节点的过程中,各个节点是插入到不同层的容器里。 -```java - /** - * DFS 版 - * @param root - * @return - */ - public List> levelOrder3(TreeNode root) { - List> result = new ArrayList>(); - levelHelper(result, root, 0); - return result; - } - - public void levelHelper(List> result, TreeNode node, int height) { - if (node == null) { - return; - } - if (height >= result.size()) { - result.add(new LinkedList<>()); - } - result.get(height).add(node.val); - levelHelper(result, node.left, height + 1); - levelHelper(result, node.right, height + 1); - } -``` - -参考:https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS \ No newline at end of file diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md deleted file mode 100644 index ec6f741..0000000 --- a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md +++ /dev/null @@ -1,42 +0,0 @@ -**二叉树的层序遍历** ---- -[https://leetcode.com/problems/binary-tree-level-order-traversal/](https://leetcode.com/problems/binary-tree-level-order-traversal/) - -解决方案 -**思路** - 使用广度优先探索,使用队列。 - 若根节点为空,直接返回; - 否则将根节点入队,然后,判断队列是否为空,若不为空,则将队首节点出队,访问,并判断其左右子节点是否为空,若不为空,则压入队列。 - -``` -class Solution{ - List> res=new ArrayList(); - public List> levelOrder(TreeNode root) { - if(root==null) return res; //边界条件 - Queue q=new LinkedList(); //创建的队列用来存放结点,泛型注意是TreeNode - q.add(root); - while(!q.isEmpty()){ //队列为空说明已经遍历完所有元素,while语句用于循环每一个层次 - int count=q.size(); - List list=new ArrayList(); - while(count>0){ //遍历当前层次的每一个结点,每一层次的Count代表了当前层次的结点数目 - TreeNode temp=q.peek(); - q.poll(); //遍历的每一个结点都需要将其弹出 - list.add(temp.val); - if(temp.left!=null)q.add(temp.left); //迭代操作,向左探索 - if(temp.right!=null)q.add(temp.right); - count--; - } - res.add(list); - } - return res; - - } -} - -``` -**复杂度分析** -时间复杂度:O(NlogN) -空间复杂度:O(N+M) - -**参考资料** - [https://www.cnblogs.com/patatoforsyj/p/9496127.html](https://www.cnblogs.com/patatoforsyj/p/9496127.html) diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md deleted file mode 100644 index 570e750..0000000 --- a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**102. 二叉树的层次遍历** ---- - -[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) diff --git a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md b/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md deleted file mode 100644 index e47ef89..0000000 --- a/_site/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md +++ /dev/null @@ -1,42 +0,0 @@ -#### 二叉树的层次遍历 - -https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ - -**思路**: - -层次遍历需要借助队列这样一个辅助的数据结构. - -1.题目给出从左到右访问节点,自然想到的就是BFS,广度优先搜索。每个节点访问且仅访问一次。所以时间复杂度是O(N),根节点先入队列,然后队列不空,取出头元素, -如果左孩子存在就入队列,否则什么都不做,右孩子同理。直到队列为空,则表示树层次遍历结束。 - -2.深度优先搜索DFS,也可以做。但是最好还是BFS - -代码:(BFS) - -``` -class Solution: - def levelOrder(self, root): - """ - :type root: TreeNode - :rtype: List[List[int]] - """ - if not root: - return [] #若根节点为空,则返回空列表 - result = [] #模拟一个队列存储节点 - queue = collections.deque() #双端队列 - queue.append(root) #首先将根节点入队 - - while queue: - level_size = len(queue) #记录同层节点的个数 - current_level = [] #使用列表来存储同层节点 - - for _ in range(level_size): - node = queue.popleft() #将同层节点依次出队 - current_level.append(node.val) - if node.left: queue.append(node.left) #非空左孩子入队 - if node.right: queue.append(node.right) #非空右孩子入队 - result.append(current_level) - return result -``` - -时间复杂度是O(N) diff --git a/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md b/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md deleted file mode 100644 index 37730bb..0000000 --- a/_site/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md +++ /dev/null @@ -1,100 +0,0 @@ -**051. 二叉树的最大深度** ---- -[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) - -方法一:递归 -采用深度优先搜索递归的方式计算最大长度。 - -```java -public class Solution { - public int maxDepth(TreeNode root) { - // 判断当前结点是否为空 - if (root == null) { - // 若为空,则返回长度0 - return 0; - } else { - // 若不为空,则深度优先搜索 - - // 先递归获取左子树的最大长度, - int left_height = maxDepth(root.left); - // 递归获取右子树的最大长度 - int right_height = maxDepth(root.right); - - // 返回当前左右子树中最大的长度+1,加一是为了将自己的长度也算上 - return java.lang.Math.max(left_height, right_height) + 1; - } - } -} - -// 二叉树的定义 -class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } -} - -``` - -**复杂度分析** - -时间复杂度: -O(n)。每个节点只访问一次,所以为O(n)。 - -空间复杂度: -最差的情况,即树的高度即为节点个数,则递归N次,因此是O(n)。最好的情况即完全平衡,树的高度将是log(N),此时空间复杂度为O(log(N))。 - -方法二:迭代 - -依旧是深度优先搜索,使用栈来代替递归。两者区别是,递归计算深度是递归结束回溯阶段通过加一来更新深度;迭代计算深度是每访问到一个节点就更新一次深度。 - -```java - -public class Solution { - public int maxDepth(TreeNode root) { - // 声明栈,栈中存入KV,其中key是节点,value是当前节点的深度 - Queue> stack = new LinkedList<>(); - // 若当前节点不为空则入栈 - if (root != null) { - // 根节点入栈,深度为1 - stack.add(new Pair(root, 1)); - } - - // 需要确定的二叉树的最大深度, - // 通过不断和每个节点的深度比较来确定二叉树的最大深度 - int depth = 0; - while (!stack.isEmpty()) { - // 出栈 - Pair current = stack.poll(); - // 获取出栈的节点 - root = current.getKey(); - // 获取出栈节点的深度 - int currentDepth = current.getValue(); - if (root != null) { - // 比较深度大小,更新二叉树的深度 - depth = Math.max(depth, currentDepth); - // 左子节点入栈 - stack.add(new Pair(root.left, currentDepth + 1)); - // 右子节点入栈 - stack.add(new Pair(root.right, currentDepth + 1)); - } - } - return depth; - } -} - -``` - ---- - - -**参考资料** - -* 官方中文题解: -[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) - -* 官方英文题解: -[https://leetcode.com/articles/maximum-depth-of-binary-tree/](https://leetcode.com/articles/maximum-depth-of-binary-tree/) diff --git a/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md b/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md deleted file mode 100644 index ff5f1f6..0000000 --- a/_site/leetcode/104-MaximumDepthOfBinaryTree/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**104. 二叉树的最大深度** ---- - -[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) diff --git a/_site/leetcode/115-DistinctSubsequences/official.md b/_site/leetcode/115-DistinctSubsequences/official.md deleted file mode 100644 index 7e9fb1c..0000000 --- a/_site/leetcode/115-DistinctSubsequences/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**115. 不同的子序列** ---- - -[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) diff --git a/_site/leetcode/120-Triangle/melody-l.md b/_site/leetcode/120-Triangle/melody-l.md deleted file mode 100644 index 806e1f1..0000000 --- a/_site/leetcode/120-Triangle/melody-l.md +++ /dev/null @@ -1,59 +0,0 @@ -**120. Triangle** - ---- -[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) - -* 该问题如果从上到下的角度考虑,即求从根节点到每一个(i, j)的最短路径。 -令F(i,j)表示从根节点开始到(i,j)的最短路径,A(i,j)表示当前位置的值,则 -F(i,j) = min{F(i-1,j), F(i-1,j-1)} + A(i,j) (其中,若i<0或j<0,则F(i,j)=0) - -* 该问题如果从下往上考虑,即求从底部到以该结点(i,j)为根节点的最短路径。 -令F(i,j)表示从底部节点到以该结点(i,j)为根节点的最短路径,则 -F(i,j) = min{F(i+1,j), F(i+1, j+1)} + A(i,j) - -* 所以,若问题求从顶部到底端每个节点的最短路径,则从上到下考虑;若问题求全局唯一路径,则采用从下往上考虑;因此,该问题采用由下到上的递推式。 - ---- - -方法一:从下往上考虑: -这里只是用了一个int[rowSize]的大小进行存储。以leetcode中的例子来简单描述一下思路: -1. 先存储最后一行[4,1,8,3] -2. 逆序遍历,以6(3,1)为根节点,从4(4,1)与1(4,2)中选择最小值,因此选择1(4,2); -3. 选择1(4,2)后,加上自己的值,存储到[4,1,8,3]的第一个位置中,原因是对于第一个位置,只有6(3,1)会用到,5(3,2)需要比较的是(4,2)和(4,3) -4. 依次类推,倒数第二行遍历完,数列为[7,6,10, 3] -5. 同理,倒数三行遍历完,数列为[9,10, 10,3] -6. 第一行,数列为[11, 10,10,3] -7. 第一个即为最终结果。 - -```java - -public class Solution { - //从下层往上层递推 - public int minimumTotal(List> triangle) { - int row = triangle.size(); // 获得行数,其中行数与最后一行的个数相等 - int[] result = new int[row]; // 因为行数与最后一行个数一致,所以直接使用row,无需重复计算 - - for (int i = 0; i < row; i++) { - result[i] = triangle.get(row - 1).get(i);// 先将最后一行赋值给结果序列 - } - - for (int i = row - 2; i >= 0; i--) { // 从倒数第二行(row-2)开始,往上层,逐行遍历,遍历至第0层,因此边界为i>=0 - for (int j = 0; j < i + 1; j++) { // 遍历当前行;当前行的数据个数与 i+1 是相等的,因此此处边界为 j maxprofit) - //将新的最大利润缓存 - maxprofit = profit; - } - } - //返回一次交易能获得的最大利润 - return maxprofit; - } - -``` - -**复杂度分析** - -时间复杂:O(n^2), -本解法使用了嵌套循环, -内循环的迭代次数随着外循环控制变量i的递增而递减, -即内循环的迭代次数是(n-1)+...+2+1 = ((n-1)+1)/2, -外循环遍历数组一次,时间复杂度是n, -所以总的时间复杂度是n*((n-1)+1)/2 = n^2/2, -消去常数系数1/2,最终时间复杂度是O(n^2) - -空间复杂度:O(1), -只使用了两个变量maxprofit和profit, -空间复杂度为O(1) - ---- - -* 官方题解2:峰谷法一次遍历 - -```java - - /** - * https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/ - * 官方解法2:峰谷法 - * - * @param prices - * @return - */ - public int maxProfit2(int prices[]) { - //定义一个最低买入价格minprice,默认值为Integer的取值上限 - int minprice = Integer.MAX_VALUE; - //定义一个最大利润maxprofit,默认值为0 - int maxprofit = 0; - //遍历价格数组prices - for (int i = 0; i < prices.length; i++) { - //当价格小于最低买入价格minprice时 - if (prices[i] < minprice) - //prices[i]缓存到minprice - minprice = prices[i]; - //prices[i] - minprice得到第i天卖出时的利润 - else if (prices[i] - minprice > maxprofit) - //如果利润大于最大利润maxprofit,将其缓存到maxprofit - maxprofit = prices[i] - minprice; - } - //返回最大利润 - return maxprofit; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -遍历了数组一次 - -空间复杂度:O(1), -只使用了minprice和maxprofit两个整数变量 - ---- - -**参考资料** - -* 官方题解: -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) diff --git a/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md b/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md deleted file mode 100644 index 43c034a..0000000 --- a/_site/leetcode/121-bestTimeToBuyAndSellStock/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**121. 买卖股票的最佳时机** ---- - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) diff --git a/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md b/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md deleted file mode 100644 index 0a7e542..0000000 --- a/_site/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md +++ /dev/null @@ -1,52 +0,0 @@ -**最佳时机买卖股票2** ----- -https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ - -### 思路一 -题目的意思是不限买卖股票的次数,并且每次买股票的时候必须在上一股卖出之后,在此基础上求出最大利润。 -我们只需求出所有的有序段的差值之和即可。遍历数组,找到第一个高峰,然后计算高峰与低谷的差值,更新新的低谷,然后再继续寻找下一个高峰,累加差值即可。 -**你必然有这样的疑问,我找到高峰之后,可能后面还有更高的峰,我为什么非的此时再卖而不是在更高的峰卖呢?这样真的能达到最大值吗**? - -你这样想,你当前的高峰后面是另一个低谷,这个差值就是你分开买比一次性买到最高峰的多出来的部分啊,也就是重叠部分。如果你直接从低谷买到最高峰,那么这个差值你是赚不到。而你每一个低谷到第一个高峰都买卖啊,这个额外的差值你都赚到了。 - -![image](https://leetcode.com/media/original_images/122_maxprofit_1.PNG) -A + B > C,对吧 -```java - public int maxProfit1(int[] prices) { - int result = 0; - int low = 0; - int len = prices.length; - for (int i = 0; i < len; i++) { - //寻找当前碰到第一个高峰 - if (i + 1 == len || prices[i] >= prices[i + 1]) { - result += prices[i] - prices[low]; - //更新低谷 - low = i + 1; - } - } - return result; - } -``` - -### 思路二 -还是看上图,既然我们求的是所有的有序段的差值和,那么我们也可以不必每次都求出这个段区间后再求和。而是从小事做起,只要第二天比第一天高,我们就买卖。意味着我们不用考虑具体的有序段是什么,只需关注当前是有序,我们就累加利润即可。类似爬坡的过程,通过累加求出上图的中A的利润。 - -```java - /** - * 一阶段 - * 累加所有的增值即可 - * @param prices - * @return - */ - public int maxProfit2(int[] prices) { - int result = 0; - for (int i = 1; i < prices.length; i++) { - if (prices[i] > prices[i - 1]) { - result += prices[i] - prices[i - 1]; - } - } - return result; - } -``` -参考: -- https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/ \ No newline at end of file diff --git a/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md b/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md deleted file mode 100644 index 9f2750e..0000000 --- a/_site/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md +++ /dev/null @@ -1,141 +0,0 @@ -**122. 买卖股票的最佳时机 II** ---- -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) - -* 官方题解1:暴力法 - -```java - - public int maxProfit(int[] prices) { - return calculate(prices, 0); - } - - public int calculate(int prices[], int s) { - //s是遍历起始的下标,如果超过数组长度直接返回0 - if (s >= prices.length) - return 0; - //定义一个最大值缓存max - int max = 0; - //外循环从起始位置起遍历元素 - for (int start = s; start < prices.length; start++) { - //定义最大利润的缓存maxprofit - int maxprofit = 0; - //i = start + 1,内循环从起始位置的第二天开始 - for (int i = start + 1; i < prices.length; i++) { - //如果当前价格大于起始位置的价格 - if (prices[start] < prices[i]) { - //prices[i] - prices[start]得到在start天买入,第i天卖出所获利润 - //因为在第i天卖出了,所以尝试在第i+1天买入 - //calculate(prices, i + 1)递归调用,得到在i+1天开始持有所能获得的最大利润 - //经过递归,profit获得的就是在第i天卖出到最后一天为止所能获得的最大利润 - int profit = calculate(prices, i + 1) + prices[i] - prices[start]; - //如果利润profit大于内循环已知的最大利润 - if (profit > maxprofit) - //将利润profit赋值给内循环最大利润maxprofit - maxprofit = profit; - } - } - //如果最大利润maxprofit大于外循环最大利润缓存max - if (maxprofit > max) - //将最大利润maxprofit赋值给max - max = maxprofit; - } - //最终返回以s天为起点的交易组合中最大利润 - return max; - } - -``` - -**复杂度分析** - -时间复杂度:O(n^n), -共调用递归n^n次 - -空间复杂度:O(n), -每递归一次占用O(1)的空间复杂度, -递归函数的调用在内循环中,最大深度是n, -所以空间复杂度是O(n) - ---- - -* 官方题解2:峰谷法 - -```java - - public int maxProfit(int[] prices) { - //定义数组的起始位置 - int i = 0; - //定义一个谷值valley - int valley = prices[0]; - //定义一个峰值peak - int peak = prices[0]; - //定义一个最大利润 - int maxprofit = 0; - //从头遍历数组 - while (i < prices.length - 1) { - //prices[i] >= prices[i + 1] 只要当天的价格大于或等于次日的价格,就一直递增 - while (i < prices.length - 1 && prices[i] >= prices[i + 1]) - i++; - //当prices中元素不满足prices[i] >= prices[i + 1]时,即prices[i] < prices[i + 1] - //说明prices[i]是最近的谷底 - valley = prices[i]; - //继续遍历,用同样的手法找到峰值 - while (i < prices.length - 1 && prices[i] <= prices[i + 1]) - i++; - peak = prices[i]; - //最大利润是峰值和谷底的差值 - //+=将所有差值不断累加,得到了最大利润总和 - maxprofit += peak - valley; - } - //返回最大利润 - return maxprofit; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -遍历一次,虽然嵌套了while循环,但是使用同一个控制变量, -最终只遍历了数组一次 - -空间复杂度:O(1), -需要常量的空间 - ---- - -* 官方题解3:一次遍历法 - -```java - - public int maxProfit(int[] prices) { - //定义一个最大利润变量maxprofit - int maxprofit = 0; - //变量价格数组 - for (int i = 1; i < prices.length; i++) { - //如果当天价格高于前一天价格 - if (prices[i] > prices[i - 1]) - //当天价格减去前一天价格,得到利润 - //maxprofit累加当天所得利润 - maxprofit += prices[i] - prices[i - 1]; - } - //最终返回的maxprofit是所有利润总和 - return maxprofit; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -遍历数组一次 - -空间复杂度:O(1), -需要常量空间 - ---- - -**参考资料** - -* 官方题解: -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) \ No newline at end of file diff --git a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md deleted file mode 100644 index 1c5bed7..0000000 --- a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md +++ /dev/null @@ -1,106 +0,0 @@ -**123.买卖股票的最佳时机 III** ---- -https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ - -### 思路一 -这个题是典型的动态规划问题,这里题目虽然说的要求最多购买2次,那么我们可以拓展一下,提出最多购买k次的最大值。 -主要有以下状态转移方程: -```math -dp[k][i] = max(dp[k][i - 1], dp[k - 1][j] + prices[i] - prices[j] ( j in [0, i - 1])) - -dp[k][i] = max(dp[k][i - 1], prices[i] + max(dp[k - 1][j] - prices[j] ( j in [0, i - 1]))) -``` -dp[k][i]表示第k次交易截止到第i天最大的收益,它等于第k次交易截止到第i - 1天最大的收益和第k次交易截止到第j天并且我在第j天重新买了一张,第i天卖掉的最大值。 -注意到上式中`max(dp[k - 1][j] - prices[j] ( j in [0, i - 1]))`会重复计算,所以这里我们只需在遍历时维护一个关于dp[k - 1][j] - prices[j] ( j in [0, i - 1])的最大值即可。 - -```java - /** - * - * dp[k][i] = max(dp[k][i - 1], dp[k - 1][j] + prices[i] - prices[j] ( j in [0, i - 1])) - * = max(dp[k][i - 1], prices[i] + max(dp[k - 1][j] - prices[j]) - * @param prices - * @return - */ - public int maxProfit4(int[] prices) { - if (prices == null || prices.length == 0) { - return 0; - } - int totalK = 2; - int[][] dp = new int[totalK + 1][prices.length]; - for (int k = 1; k <= totalK; k++) { - int maxProfit = - Integer.MIN_VALUE; - for (int i = 1; i < prices.length; i++) { - maxProfit = Math.max(maxProfit, dp[k - 1][i - 1] - prices[i - 1]); - dp[k][i] = Math.max(dp[k][i - 1], prices[i] + maxProfit); - } - } - return dp[totalK][prices.length - 1]; - } -``` -### 思路二 -思路二的状态方程引入冗余,为了之后的简化: -```math -dp[k][i] = max(dp[k][i - 1], dp[k - 1][j - 1] + prices[i] - prices[j] ( j in [0, i])) - -dp[k][i]= max(dp[k][i - 1], prices[i] + max(dp[k - 1][j - 1] - prices[j]) ( j in [0, i]) -``` -其中j可以取到i,意思是我们当天买,当天卖,引入这样的情况只不过是为了后续简化方便,这里我们把K放到了内循环,所以要用max来存放k不同时维护的最大值。 -```java - public int maxProfit5(int[] prices) { - if (prices == null || prices.length == 0) { - return 0; - } - int totalK = 2; - int[][] dp = new int[totalK + 1][prices.length]; - int[] max = new int[totalK + 1]; - Arrays.fill(max, - prices[0]); - for (int i = 1; i < prices.length; i++) { - for (int k = 1; k <= totalK; k++) { - max[k] = Math.max(max[k], dp[k - 1][i - 1] - prices[i]); - dp[k][i] = Math.max(dp[k][i - 1], prices[i] + max[k]); - } - } - return dp[totalK][prices.length - 1]; - } -``` - -又因为dp只依赖i - 1,所以可以压缩状态为: -```java - public int maxProfit6(int[] prices) { - if (prices == null || prices.length == 0) { - return 0; - } - int totalK = 2; - int[] dp = new int[totalK + 1]; - int[] max = new int[totalK + 1]; - Arrays.fill(max, Integer.MIN_VALUE); - for (int i = 0; i < prices.length; i++) { - for (int k = 1; k <= totalK; k++) { - //注意这里为什么可以直接dp[k - 1] - prices[i]呢? - max[k] = Math.max(max[k], dp[k - 1] - prices[i]); - dp[k] = Math.max(dp[k], prices[i] + max[k]); - } - } - return dp[totalK]; - } -``` -答:当k = 1, dp[k - 1] = 0, 对应的第一次买;当k = 2, dp[k - 1] 其实是dp[1][i],也就说我第一次买,截止到i天取得最大值,虽然这里减去- prices[i],后面会prices[i]抵消掉。这就是思路二的独特,思路一是无法这么化简的。 - -展开: -``` - public int maxProfit3(int[] prices) { - int buy1 = Integer.MIN_VALUE; - int buy2 = Integer.MIN_VALUE; - int sell1 = 0; - int sell2 = 0; - for (int price : prices) { - buy1 = Math.max(buy1, - price); - sell1 = Math.max(sell1, price + buy1); - buy2 = Math.max(buy2, sell1 - price); - sell2 = Math.max(sell2, buy2 + price); - } - return sell2; - } -``` - -参考:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution \ No newline at end of file diff --git a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md b/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md deleted file mode 100644 index f205eb8..0000000 --- a/_site/leetcode/123-BestTimeToBuyAndSellStockIII/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**123. 买卖股票的最佳时机 III** ---- - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) diff --git a/_site/leetcode/131-PalindromePartitioning/official.md b/_site/leetcode/131-PalindromePartitioning/official.md deleted file mode 100644 index 9dfc49f..0000000 --- a/_site/leetcode/131-PalindromePartitioning/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**131. 分割回文串** ---- -[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) diff --git a/_site/leetcode/132-PalindromePartitioningII/official.md b/_site/leetcode/132-PalindromePartitioningII/official.md deleted file mode 100644 index e57bb22..0000000 --- a/_site/leetcode/132-PalindromePartitioningII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**132. 分割回文串 II** ---- -[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) diff --git a/_site/leetcode/139-WordBreak/official.md b/_site/leetcode/139-WordBreak/official.md deleted file mode 100644 index 62dd24b..0000000 --- a/_site/leetcode/139-WordBreak/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**139. 单词拆分** ---- -[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) diff --git a/_site/leetcode/140-WordBreakII/official.md b/_site/leetcode/140-WordBreakII/official.md deleted file mode 100644 index d2a3ae5..0000000 --- a/_site/leetcode/140-WordBreakII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**140. 单词拆分 II** ---- -[https://leetcode-cn.com/problems/word-break-ii/](https://leetcode-cn.com/problems/word-break-ii/) diff --git a/_site/leetcode/141-linkedListCycle/official.md b/_site/leetcode/141-linkedListCycle/official.md deleted file mode 100644 index 4ec772f..0000000 --- a/_site/leetcode/141-linkedListCycle/official.md +++ /dev/null @@ -1,62 +0,0 @@ -**141. 环形链表** ---- -[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) - -方法一:哈希表 -思路 - -我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。 - -常用的方法是使用哈希表。 - -算法 - -我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。 - -如果当前结点为空结点 null(即已检测到链表尾部的下一个结点), - -那么我们已经遍历完整个链表,并且该链表不是环形链表。 - -如果当前结点的引用已经存在于哈希表中,那么返回 true(即该链表为环形链表)。 - -```java - -public boolean hasCycle(ListNode head) { - //新建一个set用于存储从链表中遍历出的结点 - Set nodesSeen = new HashSet<>(); - //如果当前结点不为空,循环继续 - while (head != null) { - //set中如果已经存在当前结点,说明该链表是环形链表,返回true - if (nodesSeen.contains(head)) { - return true; - } else { - //否则将当前结点添加到set - nodesSeen.add(head); - } - //将下一个结点赋值给结点缓存head - head = head.next; - } - //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false - return false; -} - -``` - -**复杂度分析** - -时间复杂度: -O(n), 对于含有 n个元素的链表,我们访问每个元素最多一次。 添加一个结点到哈希表中只需要花费 O(1) 的时间。 - -空间复杂度: -O(n), 空间取决于添加到哈希表中的元素数目,最多可以添加 n 个元素。 - ---- - - -**参考资料** - -* 本题leetCode官方题解: -[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/142-linkedListCycleII/bigablecat.md b/_site/leetcode/142-linkedListCycleII/bigablecat.md deleted file mode 100644 index 439a91c..0000000 --- a/_site/leetcode/142-linkedListCycleII/bigablecat.md +++ /dev/null @@ -1,3 +0,0 @@ -**142. 环形链表 II** ---- -[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/142-linkedListCycleII/official.md b/_site/leetcode/142-linkedListCycleII/official.md deleted file mode 100644 index 439a91c..0000000 --- a/_site/leetcode/142-linkedListCycleII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**142. 环形链表 II** ---- -[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/_site/leetcode/146-lruCache/hatrick.md b/_site/leetcode/146-lruCache/hatrick.md deleted file mode 100644 index 6bf15ca..0000000 --- a/_site/leetcode/146-lruCache/hatrick.md +++ /dev/null @@ -1,98 +0,0 @@ -**146. LRU缓存机制** ---- -[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) - -**思路** -由于LRU缓存插入和删除操作频繁,使用双向链表维护缓存节点, - -“新节点”:凡是被访问(新建/修改命中/访问命中)过的节点,一律在访问完成后移动到双向链表尾部, -保证链表尾部始终为最“新”节点; -“旧节点”:保证链表头部始终为最“旧”节点,LRU策略删除时表现为删除双向链表头部; -从链表头部到尾部,节点访问热度逐渐递增,由于链表不支持随机访问,使用HashMap+双向链表实现LRU缓存; - -HashMap中键值对: - -双向链表:维护缓存节点Node -```java - class LRUCache { - private int capacity; - private HashMap caches; - private Node first; - private Node last; - - public LRUCache(int capacity) { - this.capacity = capacity; - caches = new HashMap<>(capacity); - } - - public void put(int key, int value) { - Node node = caches.get(key); - // 首先得先判断是否存在元素 - if (node == null){ - // 如果不存在,先判断容量 - if (capacity <= caches.size()) { - // 不够,先移除最后一个 - removeLast(); - } - node = new Node(); - node.key = key; - } - node.value = value; - moveNodeToFirst(node); - caches.put(key, node); - } - - private void removeLast() { - if (last != null) { - caches.remove(last.key); - // 最后 - last = last.pre; - if (last != null) { - last.next = null; - } else { - first = null; - } - } - } - - private void moveNodeToFirst(Node node) { - if (node == first || node == null) return; - // 先连接 - if (node.pre != null) { - node.pre.next = node.next; - } - if (node.next != null) { - node.next.pre = node.pre; - } - if (node == last) { - last = last.pre; - } - if (last == null || first == null) { - last = first = node; - return; - } - node.next = first; - first.pre = node; - first = node; - node.pre = null; - } - - public int get(int key) { - Node node = caches.get(key); - if (node == null) return -1; - moveNodeToFirst(node); - return node.value; - } - - } - - class Node { - Node next; - Node pre; - int key; - int value; - } -``` - -**参考资料** -[https://segmentfault.com/a/1190000009084949](https://segmentfault.com/a/1190000009084949) diff --git a/_site/leetcode/146-lruCache/official.md b/_site/leetcode/146-lruCache/official.md deleted file mode 100644 index 9bca4d1..0000000 --- a/_site/leetcode/146-lruCache/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**146. LRU缓存机制** ---- -[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) diff --git a/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md b/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md deleted file mode 100644 index e7afa20..0000000 --- a/_site/leetcode/152-MaximumProductSubarray/SpecialYang.md +++ /dev/null @@ -1,43 +0,0 @@ -**乘积最大子序列** ---- -https://leetcode.com/problems/maximum-product-subarray/ - -典型的动态规划问题,说实话,第一次做没做出来,菜是原罪,主要卡在了判断当前最大值上面,因为乘积的特性,使得当前的不是最大值可能由于后面的负负得正从而晋升为最大值。 - -卡在上面的原因,思维一直停留在和最大子序列那道题。在那道题里,我们判断当前最大值为之前的连续最大和加上当前的数字,或者只有当前的数字,即`dp[i] = max(dp[i - 1] + num[i], num[i])`。若加上当前的值的连续和还没有只有当前值大,说明之前的连续和没有贡献,所以新的子序列要从当前值开始。 - -在乘积里就不能这么做了,因为即使乘以当前值的累积没有只有当前值大,这种情路发生在dp[i - 1]为负数,num[i]为正数时。如果仅仅按照最大连续和的做法,就会开启新的序列,前面的dp[i - 1]就会丢弃。这时如果num[i + 1]为负数,那么`dp[i - 1] * num[i] * num[i + 1]` 显然比`num[i] * num[i + 1]`大,所以我们就会丢失这个最大值。 - -牛逼的思路就是我们不仅仅要记录以当前位置结尾累积的最大值,还要记录对应的最小值,并且在访问到负数时,之前的最大值与最小值要交换一下,以便之后的正确更新。 - -记录的最大最小值,我们就可以应对各种情况了,最大值可以在遇到正数时依旧最大,遇到负数可变为最小;最小值在遇到负数翻身别为最大,遇到正数可变为最小。 - -```java - /** - * 维护已i结尾的乘积最大值,最小值 - * - * 遇到负数,交换最大最小值,因为乘以负数时,最小值会变为最大值 - * @param nums - * @return - */ - public int maxProduct2(int[] nums) { - int result = nums[0]; - for (int i = 1, min = result, max = result; i < nums.length; i++) { - //遇到负数,交换以i - 1结尾的最大值,最小值 - if (nums[i] < 0) { - int temp = min; - min = max; - max = temp; - } - max = Math.max(nums[i], max * nums[i]); - min = Math.min(nums[i], min * nums[i]); - result = Math.max(result, max); - } - return result; - } -``` -复杂度: -- 时间复杂度:遍历一遍,O(n) -- 空间复杂度:3个变量,O(1) - -参考:https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity \ No newline at end of file diff --git a/_site/leetcode/152-MaximumProductSubarray/official.md b/_site/leetcode/152-MaximumProductSubarray/official.md deleted file mode 100644 index d6f0978..0000000 --- a/_site/leetcode/152-MaximumProductSubarray/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**152. 乘积最大子序列** ---- - -[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) diff --git a/_site/leetcode/167-TwoSumII/bigablecat.md b/_site/leetcode/167-TwoSumII/bigablecat.md deleted file mode 100644 index 8565565..0000000 --- a/_site/leetcode/167-TwoSumII/bigablecat.md +++ /dev/null @@ -1,75 +0,0 @@ -**167. 两数之和 II - 输入有序数组** ---- - -[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) - - -* 双指针法 - -```java - - /** - * https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution. - * 双指针法 - * - * 时间复杂度:O(N), - * 遍历数组1次 - * - * 空间复杂度:O(1), - * 只定义了一个长度为2的整型数组变量, - * 空间复杂度为O(1) - * - * @param numbers - * @param target - * @return - */ - public static int[] twoSum(int[] numbers, int target) { - //定义一个长度为2的整数数组,用于存储返回的index1和index2 - int[] indexArr = new int[2]; - //如果输入的数组numbers为空或者长度小于2,直接返回空数组indexArr - if (numbers == null || numbers.length < 2) return indexArr; - //定义整型变量index1,从numbers初始下标0开始 - int index1 = 0; - //定义整数index2,从numbers最后一个下标numbers.length - 1开始 - int index2 = numbers.length - 1; - //从下标0开始遍历数组 - for (int index = 0; index < numbers.length; index++) { - //求得下标index1和下标index2对应元素的和sum - int sum = numbers[index1] + numbers[index2]; - //查看sum是否等于目标值target - if (sum == target) { - //符合条件则跳出for循环 - break; - } - // 如果sum不等于目标值,分别对index1和index2进行增减操作 - if (sum > target) { // 当两数相加大于目标值 - //将index2递减,右移获取更小的值 - index2--; - } else if (sum < target) { // 当两数相加小于目标值 - // 将index1递增,左移获取更大的值 - index1++; - } - } - //返回的下标从1开始计数,所以index1和index2分别加1 - indexArr[0] = index1 + 1; - indexArr[1] = index2 + 1; - return indexArr; - } - -``` - -**复杂度分析** - -时间复杂度:O(N), -遍历数组1次 - -空间复杂度:O(1), -只定义了一个长度为2的整型数组变量, -空间复杂度为O(1) - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/discuss/51239/Share-my-java-AC-solution.) \ No newline at end of file diff --git a/_site/leetcode/167-TwoSumII/official.md b/_site/leetcode/167-TwoSumII/official.md deleted file mode 100644 index 0f7315a..0000000 --- a/_site/leetcode/167-TwoSumII/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**167. 两数之和 II - 输入有序数组** ---- - -[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) diff --git a/_site/leetcode/169-majorityElement/README.md b/_site/leetcode/169-majorityElement/README.md deleted file mode 100644 index e268062..0000000 --- a/_site/leetcode/169-majorityElement/README.md +++ /dev/null @@ -1,21 +0,0 @@ -**169. 求众数** ---- -[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) - -给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 - -你可以假设数组是非空的,并且给定的数组总是存在众数。 - -示例 1: - -``` -输入: [3,2,3] -输出: 3 -``` - -示例 2: - -``` -输入: [2,2,1,1,1,2,2] -输出: 2 -``` diff --git a/_site/leetcode/169-majorityElement/SpecialYang.md b/_site/leetcode/169-majorityElement/SpecialYang.md deleted file mode 100644 index 36cde3c..0000000 --- a/_site/leetcode/169-majorityElement/SpecialYang.md +++ /dev/null @@ -1,109 +0,0 @@ -**169. 求众数** ---- -[https://leetcode.com/problems/majority-element/](https://leetcode.com/problems/majority-element/) - -### 思路一 - -因为题目明确定义了众数的概念,即出现次数大于[n / 2]的数,那么**排序后的数组最中间的那个数必为众数**。 -你可能会有疑问,有序数组如果没有众数,那么中间那个数就不是众数。But,题目强调了给定的数组必有众数。 -```java - /** - * 排序法 - * @param nums - * @return - */ - public int majorityElement1(int[] nums) { - Arrays.sort(nums); - return nums[nums.length / 2]; - } -``` -#### 复杂度 -- 时间复杂度:此思路主要消耗在排序算法上,所以时间复杂度取决于你用的什么排序算法。 -- 空间复杂度:同上 - -### 思路二 -同样,众数的概念为出现次数大于n / 2次。那么就会有以下算法,俗称阵地法: -1. 一个值pivot用来表示当前出现次数超过0的数字,另一个值count表示它出现的次数 -2. 从头开始遍历数组 -3. 若保存的数字pivot的出现次数为0,那么就把pivot更新为当前的值,并且次数 + 1 -4. 若保存的数字的次数不为0,且与当前的值相等,那么次数 + 1 -5. 若保存的数字的次数不为0,且与当前的值不相等,那么次数 - 1 -6. 直到遍历完整个数组,最终pivot的值必为出现次数大于[n / 2]的数 -```java - /** - * 阵地法 - * @param nums - * @return - */ - public int majorityElement2(int[] nums) { - int pivot = 0; - int count = 0; - for (int i = 0; i < nums.length; i++) { - if (i == 0 || count == 0) { - pivot = nums[i]; - count++; - } else if (pivot != nums[i]) { - count--; - } else { - count++; - } - } - return pivot; - } -``` -#### 复杂度 -- 时间复杂度:需要遍历一遍数组,所以O(n) -- 空间复杂度:需要哨兵和计数器,所以O(1) - -### 思路三 -众数的概念为出现次数大于n / 2次,那么数组第[n / 2]大的数必为众数。 - -基于快排的partition方法油然而生,随机选择一个哨兵,然后把所有不大于它的数全部移动到它的左边,把所有大于的数全部移动到它的右边。判断哨兵所在的索引与n / 2 的大小关系,若大于,说明中间值在左部分,按同样的逻辑递归处理左部分;若小于,说明中间值在右部分,按同样的逻辑递归处理右部分。直到相等。 -```java - /** - * 基于快排的划分 - * @param nums - * @param low - * @param high - * @param target - */ - private void partition(int[] nums, int low, int high, int target) { - if (low < high) { - int end = low + new Random().nextInt(high - low + 1); - swap(nums, end, high); - int index = low; - for (int i = low; i < high; i++) { - if (nums[i] < nums[high]) { - swap(nums, i, index); - index++; - } - } - swap(nums, index, high); - if (index < target) { - partition(nums, index + 1, high, target); - } else if (index > target) { - partition(nums, low, index - 1, target); - } - } - } - - /** - * 交换函数 - * @param nums - * @param i - * @param j - */ - private void swap(int[] nums, int i, int j) { - if (i != j) { - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; - } - } -``` -#### 复杂度 -- 时间复杂度:快排的partition的时间复杂度为O(n),详细证明可参考算法导论 -- 空间复杂度:尾递归,不需要额外空间,O(1) - -### 参考 -1. [剑指Offer-30-数组中出现次数超过一半的数字](https://blog.csdn.net/dawn_after_dark/article/details/81152544) \ No newline at end of file diff --git a/_site/leetcode/169-majorityElement/bigablecat.md b/_site/leetcode/169-majorityElement/bigablecat.md deleted file mode 100644 index bd70016..0000000 --- a/_site/leetcode/169-majorityElement/bigablecat.md +++ /dev/null @@ -1,153 +0,0 @@ -**169. 求众数** ---- -[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) - -* 官方题解2,hashMap - -```java - - public int majorityElement(int[] nums) { - //获取通过hashMap方法得到的数组中所有元素的计数 - Map counts = countNums(nums); - //临时变量用于存储hashMap中取出的众数 - Map.Entry majorityEntry = null; - //遍历hashMap中的每一个元素 - for (Map.Entry entry : counts.entrySet()) { - //如果众数临时变量majorityEntry为空,或者当前取出的数字计数比众数大 - if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { - //让众数临时变量等于当前元素 - majorityEntry = entry; - } - } - //经过循环,得到计数最大的值,即所求的众数 - //majorityEntry是hashMap的元素,getKey()获得众数的数字 - return majorityEntry.getKey(); - } - - private Map countNums(int[] nums) { - //创建一个HashMap对象counts用于存储已经出现过的数字 - Map counts = new HashMap(); - //遍历int数组 - for (int num : nums) { - //查看hashMap中是否已经存在当前数字 - if (!counts.containsKey(num)) { - //如果不存在,使用当前数字做map的key,用计数1做value表示出现了1次 - counts.put(num, 1); - } else { - //如果已经存在,通过num这个key获得已经保存的value,即num的计数,在此基础上加1 - counts.put(num, counts.get(num) + 1); - } - } - //返回hashMap - return counts; - } - - -``` - -**复杂度分析** - -时间复杂度:O(n),遍历数组时间复杂度O(n), -遍历HashMap对象的所有元素时间复杂度也是O(n), -最终时间复杂度为n+n,所以是O(n) - -空间复杂度:O(n), -众数在n个元素中最少出现的次数为 2/n+1, -那么非众数元素最多不会超过 n-(2/n+1) = n-2/n-1个, -众数本身也是一个元素,与其他非众数元素不同, -所以最坏情况下,n中总共有 (n-2/n-1)+1 = n-2/n个不同的元素 -HashMap保存这些不同的元素需要占用n/2的空间, -所以空间复杂度是O(n/2) - ---- - -* 官方题解5,递归和分治 - -```java - - public int majorityElement(int[] nums) { - return majorityElementRec(nums, 0, nums.length - 1); - } - - /** - * 递归方法 - * - * @param nums - * @param lo - * @param hi - * @return - */ - private int majorityElementRec(int[] nums, int lo, int hi) { - //参数lo是数组首个元素的下标,参数hi是数组最后一个元素的下标,也是数组的长度 - if (lo == hi) { - return nums[lo]; - } - - //获取数组的中位数元素下标 - // (hi - lo) / 2得到当前数组中间位置的元素距离首个元素的距离 - // (hi - lo) / 2 + lo得到数组中间元素的下标 - int mid = (hi - lo) / 2 + lo; - //数组的左半部分从首个元素下标lo到中间元素下标mid - int left = majorityElementRec(nums, lo, mid); - //数组的右半部分从中间元素下标mid到最后一个元素下标hi - int right = majorityElementRec(nums, mid + 1, hi); - - // 如果左右两边获得的众数相等,则该众数必定是整个数组的众数,直接返回 - if (left == right) { - return left; - } - - //统计左半边众数出现的总次数 - int leftCount = countInRange(nums, left, lo, hi); - //统计右半边众数出现的总次数 - int rightCount = countInRange(nums, right, lo, hi); - - //返回较大的候选众数 - return leftCount > rightCount ? left : right; - } - - - /** - * 计算候选众数在某个数组片段中出现的总次数 - * - * @param nums - * @param num - * @param lo - * @param hi - * @return - */ - private int countInRange(int[] nums, int num, int lo, int hi) { - //定义一个计时器count - int count = 0; - //遍历从下标lo到下标hi的元素 - for (int i = lo; i <= hi; i++) { - //如果获得的元素与当前传入的候选众数num相等,计数器加1 - if (nums[i] == num) { - count++; - } - } - //返回候选众数在当前数组片段中出现的总次数 - return count; - } - -``` - -**复杂度分析** - -时间复杂度 : O(nlogn), -每次递归,n就被2分一次,n/2/2... -所以总共调用递归方法的次数是logn次, -递归方法中有循环,最坏情况对每组进行了全员遍历,时间复杂度是O(n), -所以总的时间复杂度是n*logn - -空间复杂度:O(logn), -因为进行了logn次的递归调用, -每次递归都占用O(1)的空间复杂度, -所以最终空间复杂度为O(logn) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) diff --git a/_site/leetcode/174-DungeonGame/passself.md b/_site/leetcode/174-DungeonGame/passself.md deleted file mode 100644 index e369d4c..0000000 --- a/_site/leetcode/174-DungeonGame/passself.md +++ /dev/null @@ -1,81 +0,0 @@ -#174. 地下城游戏 - -Leetcode 地址 [https://leetcode-cn.com/problems/dungeon-game/](https://leetcode-cn.com/problems/dungeon-game/) - -**题目分析** - -基本一看就是动态规划的题目, 有几个前提条件一定得注意。 - -* 1.骑士的初始健康点数为一个正整数。 -* 2.如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。即无论骑士到达哪个位置健康值必须大于等于1 - -**思路:** - -* 思路一 正向递推从左上角(0,0)到(row-1,row-1),这样效率一般会比反递推效率低很多 -* 思路二 到达最后一个房间的时候健康值至少剩下1,因此可以设置最后的状态为初始状态,由后向前依次决定在每一个位置至少需要多少健康值,这样一个位置的状态是由其下面一个和和右边一个的较小状态决定 .因此一个基本的状态方程是: - -``` -int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); -int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); -dp[i][j] = Math.min(right, down); -``` -还有一个条件就是在每个房间里面的健康值都大于等于1 ```dp[i][j] = max(dp[i][j], 1)``` - -**具体代码** - -``` -public int calculateMinimumHP(int[][] dungeon) { - if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) return 0; - int m = dungeon.length; - int n = dungeon[0].length; - int[][] dp = new int[m][n]; - for (int i = m - 1; i >= 0; i--) { - for (int j = n - 1; j >= 0; j--) { - if(i==m-1 && j==n-1) {//考虑边界 - dp[i][j]=Math.max(1 - dungeon[i][j], 1); - }else if(i==m-1) { - dp[i][j]=Math.max(dp[i][j + 1] - dungeon[i][j], 1); - }else if(j==n-1) { - dp[i][j]=Math.max(dp[i + 1][j] - dungeon[i][j], 1); - }else{ - int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); - int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); - dp[i][j] = Math.min(right, down); - } - } - } - return dp[0][0]; -} -``` - -**时间复杂度** O(M*N) - -**空间复杂度** O(M*N) - -leetcode 代码提交后发现击败了26%的commit - -**第二种解法** - -用一位数组来记录数据,空间复杂度变为o(n),执行效率和速度大幅提升 - -**具体代码** - -``` -public int calculateMinimumHP(int[][] dungeon) { - int m = dungeon.length, n = dungeon[0].length; - int[] dp = new int[n + 1]; - dp[n] = 1; - for (int i = m - 1; i >= 0; i--) { - for (int j = n - 1; j >= 0; j--) { - int health = 0; - if (i == m - 1) health = dp[j + 1] - dungeon[i][j]; - else if (j == n - 1) health = dp[j] - dungeon[i][j]; - else health = Math.min(dp[j + 1], dp[j]) - dungeon[i][j]; - dp[j] = health <= 0 ? 1 : health; - } - } - return dp[0]; -} -``` - - diff --git a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md deleted file mode 100644 index 3122d45..0000000 --- a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md +++ /dev/null @@ -1,44 +0,0 @@ -**买卖股票的最佳时机IV** -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) -方法一:**动态规划** -**思路** -这个题是一道明显的动态规划题,跟前面几道类似的题有区别,要求最多可以进行K次交易,当然少于K次也是可以的。首先我们可以注意到一种特殊情况,就是`K > Len(array)`,在这种情况下,其实就相当于可以进行任意次交易,因为不管进行多少次交易,一定不会超过K次。 -现在来考虑普通情况,我们用dp[i][j]表示,截止到第j天,最多i次交易所获得的最大利润。dp[i][j]的大小跟两个因素有关。 -`dp[i][j] = Max(dp[i][j-1],prices[j]-prices[m] + dp[i-1][m-1])(m > 0 && m <= j-1)`.也就是`dp[i][j] = Max(dp[i][j-1],prices[j] + max(dp[i-1][m-1] - prices[m]))`.在第一个式子中,我们可以看到m是一个范围,所以我们在第二个式子中,用max来代表m不同取值的情况。首先`dp[i][j]`跟`dp[i][j-1]`有关,有可能到第j-1天,第i次交易已经取得了最大利润,后面的天数都不会超过这个利润。`dp[i][j]`还跟`dp[i-1][m-1]`有关,也就是说,到第m-1天为止,只进行了i-1次交易,第i次交易就是`prices[j]-prices[m]`.我们要做的就是找到这个最大值。 -**算法** -先处理一下特殊情况,即`K > Len(array)`的情况。然后交易次数i从1开始,一直到K。对于每次交易,从第一天开始,一直遍历到最后一天,从而得到dp[i][j]的最大值。 - -**代码** -``` - public int maxProfit(int k, int[] prices) { - int len = prices.length; - //如果K大于数组长度的一半,就相当于可以进行任意次交易,这种情况下,只要数组局部上升,差就是我们的利润。 - if (k >= len / 2) return quickSolve(prices); - //初始化数组,i表示第i次交易,j表示进行到第j天为止 - int[][] t = new int[k + 1][len]; - for (int i = 1; i <= k; i++) { - //临时的利润最大值,其实这个就是上面思路部分所说的dp[i-1][m-1] - prices[m],通过tmpMax,我们可以在遍历j的过程中,求出dp[i-1][m-1] - prices[m]的最大值 - int tmpMax = -prices[0]; - //从1开始遍历,求截止到第j天,最多i次交易能获得的最大利润。 - for (int j = 1; j < len; j++) { - //参考思路部分 - t[i][j] = Math.max(t[i][j - 1], prices[j] + tmpMax); - tmpMax = Math.max(tmpMax, t[i - 1][j - 1] - prices[j]); - } - } - return t[k][len - 1]; - } - - - private int quickSolve(int[] prices) { - int len = prices.length, profit = 0; - for (int i = 1; i < len; i++) - //如果第i天的价格大于第i-1天的价格,就是我们可以得到的利润。 - if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1]; - return profit; - } -``` -复杂度分析: -假设数组的长度为N -空间复杂度: O(KN) -时间复杂度:·O(KN) \ No newline at end of file diff --git a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md b/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md deleted file mode 100644 index 095a7dd..0000000 --- a/_site/leetcode/188-bestTimeToBuyAndSellStockIV/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**188. 买卖股票的最佳时机 IV** ---- - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) diff --git a/_site/leetcode/191-NumberOf1Bits/bigablecat.md b/_site/leetcode/191-NumberOf1Bits/bigablecat.md deleted file mode 100644 index 6fe8774..0000000 --- a/_site/leetcode/191-NumberOf1Bits/bigablecat.md +++ /dev/null @@ -1,102 +0,0 @@ -**191. 位1的个数** ---- - -[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) - -* 官方题解1:遍历32位 - -```java - - public int hammingWeight(int n) { - //计数器,统计整数n的2进制数上有多少个1 - int bits = 0; - //定义mask默认值1,用来和整数的每一位进行与运算 - int mask = 1; - //遍历整数的32位 - for (int i = 0; i < 32; i++) { - // 在二进制的位与运算中,1 & 1 = 1, 1 & 0 = 0 - // 通过 n & mask 的位与运算,判断整数n的二进制数在第i个位上是否为1 - // (n & mask) != 0 表示n的二进制数在第i个位上的数字等于1 - if ((n & mask) != 0) { - //n二进数上每出现一次1,bits就递增一次 - bits++; - } - //位运算的左移运算符<<表示将当前整数的二进制数向左移动指定的位数 - //mask <<= 1 表示将mask左移一位 - //在mask的32位二进制数中,1不断从右向左移动,其他位上都是0 - mask <<= 1; - // 完整过程举例: - // 假设 n = 6,n的32位二进制数的最右边四位是 0110 - // 当i = 0时,mask = 1 的二进制数是 0001 - // 将 n的二进制数0110 和 mask当前的二进制数 0001 进行位与运算 - // 0110 & 0001 = 0,各个位上都没有同时为1,所以结果是0 - // 当i = 1时,mask经过位移,二进制数变成 0010 - // 0110 & 0010 = 1,在倒数第二位上同时为1,所以结果是1 - // bits在i=1时递增1以此类推 - } - //返回位1的统计结果 - return bits; - } - -``` - -**复杂度分析** - -时间复杂度:O(1), -只对整数的32位进行了一次遍历, -时间复杂度是常数,所以时间复杂度是O(1) - -空间复杂度:O(n), -没有使用额外空间,空间复杂读是O(1) - ---- - -* 官方题解2:消除最低有效的1位 - -```java - - public int hammingWeight(int n) { - //计数器,统计整数n的2进制数上有多少个1 - int sum = 0; - //当n不等于0时循环继续 - while (n != 0) { - //n不等于0说明n的二进制数中仍然有1存在 - //计数器加1 - sum++; - //n &= (n - 1)拆分后是两个步骤,即n = n & (n-1) - //将每次 n & (n-1)的结果赋值给整数n - //n & (n-1)的位与运算会消去n的二进制数中最低有效的1位 - //当消除n的二进制数中最后一个1位时,n == 0,跳出循环,任务结束 - n &= (n - 1); - // 完整过程举例: - // 假设 n = 6,n的32位二进制数的最右边四位是 0110 - // n - 1 的32位二进制数的最右边四位是 0101 - // n & (n-1),即 0110 & 0101 = 0100 - // 原本 0110 中的最低有效1位被消去,即右向左数的第一个1 - // 继续循环,0100 - 1 = 0011 - // 0100 & 0011 = 0000, - // 即0100中的1位也被消去,最终结果为0,统计得到2个1位 - } - - //返回1位的统计总数 - return sum; - } - -``` - -**复杂度分析** - -时间复杂度:O(1), -最差情况时间复杂度是32, -最终时间复杂度是O(1) - -空间复杂度:O(1), -没有使用额外的空间, -空间复杂度是O(1) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) diff --git a/_site/leetcode/198-houseRobber/hatrick.md b/_site/leetcode/198-houseRobber/hatrick.md deleted file mode 100644 index 921855c..0000000 --- a/_site/leetcode/198-houseRobber/hatrick.md +++ /dev/null @@ -1,49 +0,0 @@ -**198. 打家劫舍** ---- -[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) - -**思路** -你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统, -如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下, -能够偷窃到的最高金额。 - -1、首先想一想如果是暴力如何做? - -假设从最后一家店铺开始抢,那么只会遇到2种情况,即:抢这家店和下下家店,或者不抢这家店。 -所以我们得到递归的公式: -Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]); - -2、上面的暴力算法虽然能够得到正确的结果,但是显然递归的效率是很低的,如果有n家店铺,每家店铺有2种可能,那么时间复杂度就是2的n次方。那么如何优化呢? - -我们分析一下: -如果我们开始抢的是第n-1家店,那么后面可以是(n-3,n-4,n-5,n-6....); -如果我们开始抢的是第n-2家店,那么后面可以是(n-4,n-5,n-6,....); -那么这两种情况显然n-3之后的n-4,n-5,n-6,....都重复计算了。显然这里有非常大的优化空间。通常我们使用空间来换时间,即用一个数组记录每次计算的结果, -这样每次情况只需要计算一次,再次遇到只需直接返回结果即可,大大优化了时间 - - -```java - class Solution { - public static int[] result; - public int solve(int[] nums,int index){ - if(index < 0){ - return 0; - } - if(result[index] >= 0){ - return result[index]; - } - result[index]=Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]); - return result[index]; - } - public int rob(int[] nums) { - result = new int[nums.length]; - for(int i=0;i 0 && grid[i-1][j] == '1') { - q = (i-1)*col + j; - uf.union(p,q); - } - if(i < row-1 && grid[i+1][j] == '1') { - q = (i+1)*col + j; - uf.union(p,q); - } - if(j > 0 && grid[i][j-1] == '1') { - q = i * col + j-1; - uf.union(p,q); - } - if(j < col - 1 && grid[i][j+1] == '1') { - q = i*col + j + 1; - uf.union(p,q); - } - } - } - //返回count,这就是最终剩下的子集的数量。 - return uf.count; - } - -} -//并查集的数据结构 -class UnionFind{ - //用于存储他们的父节点 - public int[] visited = null; - //用于记录最后子集的个数 - public int count; - public UnionFind(char[][] grid) { - int row = grid.length; - int col = grid[0].length; - //计算该矩阵中有多少个1 - for(int i = 0; i < row; i++) { - for(int j = 0; j K,说明我们要找的元素在index的左边,继续在index的左边进行寻找,如果index == K,说明我们找到了第K大的元素。 -``` -public class Solution { - public int findKthLargest(int[] ele, int k) { - int len = ele.length; - return quickSort(ele,len-k,0,len-1); - } - public int quickSort(int[] ele, int k,int start, int end) { - //如果start>end,说明并不存在第K大的数 - if(start > end) - return -1; - int index = partition(ele,start,end); - //如果index == K,说明找到了第K大的数 - if(index == k) { - return ele[index]; - //如果indexK,说明要找的数,在index的左边 - } else { - return quickSort(ele,k,start,index-1); - } - } - //返回比较元素cmp的位置 - public int partition(int[] ele, int left, int right) { - //选第一个元素为比较元素 - int cmp = ele[right]; - int index = left - 1; - for(int i = left; i < right; i++) { - //如果当前元素小于cmp,则将该元素交换到cmp的前面 - if(ele[i] < cmp) { - swap(ele,i,++index); - } - } - //将cmp交换到最终的位置。 - swap(ele,right,++index); - //返回cmp的位置 - return index; - } - //用位运算交换两个数的位置 - public void swap(int[] ele, int i, int j) { - if(ele[i] == ele[j]) return; - ele[i] ^= ele[j]; - ele[j] ^= ele[i]; - ele[i] ^= ele[j]; - } -} - -``` -**复杂度分析** -空间复杂度:O(1) -时间复杂度:近似于O(n),一般情况下比快排的平均时间复杂度O(nlogn)要好一些。最坏情况下是O(n^2),这时候就是快排的最坏时间复杂度 - -**拓展1** -快排的过程中,比较元素的取法有很多种,可以选第一个,也可以选最后一个,也可以随机选一个.随机选一个的做法是,只需要将随机选的元素跟第一个或者最后一个交换。按照下面是各种选法的代码 -``` -//选最后一个元素为比较元素 - public static int partition1(int[] ele, int left, int right) { - int pivot = ele[right]; - int index = left - 1; - for(int i = left; i < right; i++) { - if(ele[i] < pivot) { - swap(ele,i,++index); - } - } - swap(ele,right,++index); - return index; - } - //选第一个元素为比较元素 - public static int partition2(int[] ele, int left, int right) { - int pivot = ele[left]; - int index = left; - for(int i = left + 1; i <= right; i++) { - if(ele[i] pivot) right--; - if(left < right) { - swap(ele,left,right); - left++; - } - while(left < right && ele[left] < pivot) left++; - if(left < right) { - swap(ele,left,right); - right--; - } - } - return left; - } - -``` -**拓展2** -当数组中有大量重复元素的时候,用三项切分快排更合适,代码如下: -``` - public static void quickSort_3Way(int[] ele, int left, int right) { - if(left >= right) - return; - //选取比较元素 - int pivot = ele[left]; - //遍历指针 - int leftScanPtr = left + 1; - /* - 因为存在大量重复元素,所以跟pivot相等的元素可能有多个,所以遍历完一遍之后,pivot相等的值有多个,聚集在一起,lt用来记录其左端,rt用来记录其右端 - 比如说比较元素是5,经过一趟遍历之后是324255578978,lt就是4,rt就是6 - */ - int lt = left; - int rt = right; - while(leftScanPtr <= rt) { - if(ele[leftScanPtr] < pivot) { - swap(ele,lt,leftScanPtr); - leftScanPtr++; - lt++; - }else if(ele[leftScanPtr] > pivot) { - swap(ele,rt,leftScanPtr); - rt--; - }else{ - leftScanPtr++; - } - } - quickSort_3Way(ele,left,lt-1); - quickSort_3Way(ele,rt+1,right); - } -``` - diff --git a/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md deleted file mode 100644 index c95274f..0000000 --- a/_site/leetcode/215-KthLargestElementInAnArray/bigablecat.md +++ /dev/null @@ -1,142 +0,0 @@ -**找数组中第K大的数** ---- -[https://leetcode.com/problems/kth-largest-element-in-an-array/](https://leetcode.com/problems/kth-largest-element-in-an-array/) - -* 《程序员面试金典(第5版)》第8章:排序与查找,结合leetCode上网友高效解法: - -```java - - /** - * @param nums - * @param k - * @return - */ - public int findKthLargest(int[] nums, int k) { - //调用递归方法找到第k个最大值 - // 第k个最大元素在数组nums从右向左数的第k个位置 - // 即从左往右数第(nums.length - k + 1)个位置 - // 数组下标从0计数,第k个最大元素的下标为 (nums.length - k + 1) - 1 = nums.length - k - return quickSelect(nums, 0, nums.length - 1, nums.length - k); - } - - /** - * 《程序员面试金典(第5版)》第8章:排序与查找 - * https://leetcode-cn.com/submissions/api/detail/215/java/3/ - *

- * 快速选择算法 - * - * @param nums 数组 - * @param left 最左侧元素下标 - * @param right 最右侧元素下标 - * @param K 目标位置 - * @return 第k个最大值 - */ - public int quickSelect(int[] nums, int left, int right, int K) { - //如果起始下标left和结尾下标right重合,即left和right所在位置即基准值 - if (left == right) { - //返回下标start在数组中对应的值nums[start] - return nums[right]; - } - // 调用分割方法partition,返回结果index是当前排序之后基准值pivot的下标 - // pivot左侧元素小于pivot,pivot右侧元素大于pivot - int index = partition(nums, left, right); - // 本方法内的大写字母K代表数组nums中第k大的值,距离当前左边界left有多远 - // (index - left)得到本轮求得的基准值坐标index距离当前左边界left有多远 - // K与(index - left)比较大小,判断K在基准值坐标index的左侧还是右侧 - if (K >= (index - left)) { - // K >= (index - left)表示nums中第k大的值在基准值右侧 - // 取值范围nums[index]到nums[right] - // K值是到左边界left的距离 - // 左边界更新为index时,当前K值减去index到左边界left的距离得到新的K值 - return quickSelect(nums, index, right, K - (index - left)); - } else { - //第k大的值比当前基准值小,在基准值左侧,取值范围nums[left]到nums[index-1]之间 - //因为左边界left没有改变,所以仍然使用当前K值 - return quickSelect(nums, left, index - 1, K); - } - } - - /** - * 使用QuickSelection快速选择算法,分割数组 - * - * @param nums 数组 - * @param left 数组最左侧元素的下标 - * @param right 数组最右侧元素的下标 - * @return - */ - public int partition(int[] nums, int left, int right) { - // 先定义一个基准值pivot - // 本方法中选用数组最左侧和最右侧下标的平均数 - // 取得一个位于数组中间位置的元素作为基准值 - int pivot = nums[(left + right) / 2]; - //在循环体中,left递增,right递减,两个下标不断靠近 - //当left和right交叉(left>right)时,当前一轮完成了排序,循环结束 - while (left <= right) { - // while循环自左向右不断检索数组nums - // 在到达或越过pivot之前,所有nums[left]都在pivot左侧 - // 当不满足条件nums[left] < pivot时 - // 得到了一个应该被放到pivot右侧的元素,它的下标为left - while (nums[left] < pivot) { - // left不断递增 - // 即指针不断向数组右侧移动 - // 直至到达或越过基准值pivot - left++; - } - // while循环自右向左不断检索数组nums - // 在到达或越过pivot之前,所有nums[right]都在pivot右侧 - // 当不满足条件nums[right] > pivot时 - // 得到了一个应该被放到pivot左侧的元素,它的下标为right - while (nums[right] > pivot) { - // right不断递增 - // 即指针不断向数组左侧移动 - // 直至到达或越过基准值pivot - right--; - } - //经过上两轮while循环,此时nums[left]>=pivot>=nums[right] - //可以推出nums[left]>=nums[right] - //如果此时left<=right,需要交换两个元素的值,保证数组按照从小到大的次序排列 - if (left <= right) { - // 调用swap方法 - // 交换数组nums中,下标left和right对应的两个元素 - swap(nums, left, right); - //交换后下标left继续递增1次,right继续递减1次 - left++; - right--; - } - } - //返回更新后的left值 - return left; - } - - /** - * swap方法,交换数组中两个元素的位置 - * - * @param nums 数组 - * @param left 左侧元素的下标 - * @param right 右侧元素的下标 - * @return - */ - public int[] swap(int[] nums, int left, int right) { - //定义一个临时变量存放右侧元素 - int temp = nums[right]; - //将左侧元素赋值给右侧元素 - nums[right] = nums[left]; - //将临时变量存储的原右侧元素赋值给左侧元素 - nums[left] = temp; - //返回交换后的数组 - return nums; - } - -``` - -**复杂度分析** - -空间复杂度:O(1), -没有使用额外空间,空间复杂读是O(1) - -**参考资料** - -* 《程序员面试金典(第5版)》第8章:排序与查找 - -* 网友高效答案: -[https://leetcode-cn.com/submissions/api/detail/215/java/3/](https://leetcode-cn.com/submissions/api/detail/215/java/3/) diff --git a/_site/leetcode/221-MaximalSquare/official.md b/_site/leetcode/221-MaximalSquare/official.md deleted file mode 100644 index 9be6e7b..0000000 --- a/_site/leetcode/221-MaximalSquare/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**221. 最大正方形** ---- -[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) diff --git a/_site/leetcode/225-implementStackUsingQueues/hatrick.md b/_site/leetcode/225-implementStackUsingQueues/hatrick.md deleted file mode 100644 index ea1ce4f..0000000 --- a/_site/leetcode/225-implementStackUsingQueues/hatrick.md +++ /dev/null @@ -1,66 +0,0 @@ -**232. 用栈实现队列** ---- -[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) - -解决方案 -**思路** -根据题意的描述,我们要用栈实现队列先进先出的特性,使用两个栈,每次入栈之前,将栈中元素放入辅栈,在入栈之后再拉回来 - -``` -class MyQueue { - - //设置一个flag标示位,表示每次第一个进栈的元素 - private int flag = -1; - //主栈 - private Stack s1 = new Stack<>(); - //辅助栈 - private Stack s2 = new Stack<>(); - - public MyQueue() { - } - - public void push(int x) { - //如果是第一次入栈 主栈和辅助栈都为空 - if (s1.empty()) { - //第一次进来将flag置为进栈的值 - flag = x; - } - //如果第二次进来话,需要将前面进栈的值弹出,并放到辅助栈里面 - while (!s1.empty()) { - s2.push(s1.pop()); - } - //保证当前栈中push值得时候是干净的栈,模拟队列 - s1.push(x); - //将辅助栈中的值弹出,放到主栈中,保证了主栈中先进先出的特性 - while (!s2.empty()) { - s1.push(s2.pop()); - } - } - - public int pop() { - //直接弹栈 出来的就是最先进去的哪一个 - int num = s1.pop(); - if (!s1.empty()) { - //然后将当前的s1栈顶的元素赋值给标志位 - flag = s1.peek(); - } - return num; - } - - public int peek() { - //取标志位 - return flag; - } - - public boolean empty() { - return s1.empty(); - } -} - -``` -**复杂度分析** -时间复杂度:O(N^2) -空间复杂度:O(N^2) - -**参考资料** - [https://blog.csdn.net/LaputaFallen/article/details/79998961?utm_source=blogxgwz5](https://blog.csdn.net/LaputaFallen/article/details/79998961?utm_source=blogxgwz5) \ No newline at end of file diff --git a/_site/leetcode/225-implementStackUsingQueues/official.md b/_site/leetcode/225-implementStackUsingQueues/official.md deleted file mode 100644 index 14dcd85..0000000 --- a/_site/leetcode/225-implementStackUsingQueues/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**225. 用队列实现栈** ---- -[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) - diff --git a/_site/leetcode/231-PowerOfTwo/hatrick.md b/_site/leetcode/231-PowerOfTwo/hatrick.md deleted file mode 100644 index 1074205..0000000 --- a/_site/leetcode/231-PowerOfTwo/hatrick.md +++ /dev/null @@ -1,44 +0,0 @@ -**231. 2的幂** ---- - -[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) -思路: -解法一: -直接判断当前这个数字是否等于1,如果等于1则当前是2的0次幂,其次判断当前的数字取模 -能否除尽,如果不能直接返回,如果能就继续计算 -```java - private boolean is2reverse(int n) { - if (n == 1) { - return true; - } - if (n >= 2 && n % 2 == 0) { - return is2reverse(n / 2); - } - return false; - } - -``` -**复杂度分析** -时间复杂度:O(N) -空间复杂度:O(1) ---- -解法二: -2的次幂,意味着n&(n-1)的值为0,如果不是2的次幂那么返回值不是0了 -```java - private boolean is2reverse(int n) { - if (n < 0) { - return false; - } - int x = n & (n - 1); - return x == 0; - } -``` - -**复杂度分析** -时间复杂度:O(1) -空间复杂度:O(1) ---- -**参考资料** - -* 网友高票Java解法: -[https://blog.csdn.net/chenchaofuck1/article/details/51226899](https://blog.csdn.net/chenchaofuck1/article/details/51226899) diff --git a/_site/leetcode/231-PowerOfTwo/official.md b/_site/leetcode/231-PowerOfTwo/official.md deleted file mode 100644 index 4a455bd..0000000 --- a/_site/leetcode/231-PowerOfTwo/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**231. 2的幂** ---- - -[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) diff --git a/_site/leetcode/232-implementQueueUsingStacks/hatrick.md b/_site/leetcode/232-implementQueueUsingStacks/hatrick.md deleted file mode 100644 index 9ef68cd..0000000 --- a/_site/leetcode/232-implementQueueUsingStacks/hatrick.md +++ /dev/null @@ -1,80 +0,0 @@ -**225. 用队列实现栈** ---- -[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode.com/problems/backspace-string-compare/) - -解决方案 -**思路** -根据题意的描述,我们要使用队列实现栈,我们需要两个队列,来进行值得互换,一次来保证一个当前栈,进而实现栈的特性 -**算法** -从一个队列中拿出放到另外一个队列里面,然后队列里最后一个也就是我们的"栈顶元素" -``` -class MyStack { - - //使用两个队列来交换数据格式 - private Queue q1 = new LinkedList<>(); - private Queue q2 = new LinkedList<>(); - - //保证当前的值只在一个队列里面 - public void push(int x) { - if (!q1.isEmpty()) - q1.add(x); - else - q2.add(x); - } - - public int pop() { - //如果队列1位空 - if (q1.isEmpty()) { - //则队列2有值,这里需要单独定义size 因为poll方法会使当前队列的长度动态变化 - int size = q2.size(); - //这里循环会留下q2队列最后添加的一项 - for (int i = 1; i < size; i++) { - //将队列2从头开始取添加到队列1(保证当前只有一个队列里面有元素,弹栈之后值并不完整) - q1.add(q2.poll()); - } - //将对列2中头部元素弹栈并移除,也就是队列中的最后一个进入的 - return q2.poll(); - } else { - //跟上面思路相同 - int size = q1.size(); - for (int i = 1; i < size; i++) { - q2.add(q1.poll()); - } - return q1.poll(); - } - } - - public int top() { - //定义临时变量 - int result; - //如果q1为空 - if (q1.isEmpty()) { - //这里的size方法需要单独提取出来 - int size = q2.size(); - //这里队列2会将最后进入的元素保留 - for (int i = 1; i < size; i++) { - q1.add(q2.poll()); - } - //拿到最后一个进入的元素赋值给临时变量 - result = q2.poll(); - //保证当前只有一个队列里面的元素是完整的 - q1.add(result); - } else { - int size = q1.size(); - for (int i = 1; i < size; i++) { - q2.add(q1.poll()); - } - result = q1.poll(); - q2.add(result); - } - return result; - } - - public boolean empty() { - return q1.isEmpty() && q2.isEmpty(); - } -} -``` -**复杂度分析** -时间复杂度:O(N^2),需要取出当前队列里面的n-1个元素 -空间复杂度:O(N^2),需要两个队列,取出放入组合 diff --git a/_site/leetcode/232-implementQueueUsingStacks/official.md b/_site/leetcode/232-implementQueueUsingStacks/official.md deleted file mode 100644 index 98ac7a7..0000000 --- a/_site/leetcode/232-implementQueueUsingStacks/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**232. 用栈实现队列** ---- -[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) - diff --git a/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md b/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md deleted file mode 100644 index 6326f69..0000000 --- a/_site/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md +++ /dev/null @@ -1,91 +0,0 @@ -**两个节点的最低公共祖先** ---- -[https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) -解决方案: -方法一:**递归** -**思路** -这个题,最容易想到的思路就是,先判断根节点是不是公共祖先,然后在判断根节点的左子节点和右子节点是不是公共祖先。但是这样有一个问题是,如果从上往下依次判断的话,会重复计算,所以最好的方法是从下往上开始判断。 -**算法** -假设要寻找p和q的公共祖先,在对树的遍历过程中,先判断当前节点root是否为null,或者是否为q和p中的一个,如果是的话,则返回root.如果不是的话,则对其左子树和右子树进行寻找。如果左子树返回的为null,那说明公共祖先一定在右字树。如果右子树返回的为null,说明公共祖先一定在左子树中。如果两个都不为null,说明左子树和右字树都各含有一个节点,则返回当前节点 -**代码** -``` -class Solution { - //后序遍历 - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - //如果当前节点为null,或者等于p、q中的一个,则返回当前节点 - if(root == null || root == p || root == q) return root; - //在左子树中寻找 - TreeNode left = lowestCommonAncestor(root.left,p,q); - //在右子树中寻找 - TreeNode right = lowestCommonAncestor(root.right,p,q); - //如果左子树返回的为null,那说明公共祖先一定在右子树。如果右子树返回的为null,说明公共祖先一定在左子树中。如果两个都不为null,说明左子树和右字树都各含有一个节点,则返回当前节点 - return left == null ? right : right == null ? left : root; - } - -} -``` -复杂度分析: -假设树的节点的个数为N -空间复杂度:O(N) 虽然代码中并没有用额外的空间,但是递归本身需要用到栈,最坏情况下,树的高度就是N -时间复杂度:O(N) 最坏情况下,需要都访问一遍 - -方法二:**循环遍历** -**思路**: -我们可以先找到从根节点分别到p和q的路径,然后对比两条路径,从下到上,第一个相同的节点就是他们俩的最低公共祖先。实现方式可以有多种。 -**算法** -从根节点开始找到p和q,在寻找的过程中,将节点和其父节点用hashmap存储,然后根据hashmap,我们可以找到从p和q到根节点的路径。进行对比之后,就可以找到最低公共祖先 -``` -class Solution { - - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - - //用来辅助遍历 - Deque stack = new ArrayDeque<>(); - - //存节点和其父节点 - Map parent = new HashMap<>(); - - parent.put(root, null); - stack.push(root); - - // 找p和q - while (!parent.containsKey(p) || !parent.containsKey(q)) { - - TreeNode node = stack.pop(); - - // While traversing the tree, keep saving the parent pointers. - 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<>(); - - // 找到从p到根节点的路径 - while (p != null) { - ancestors.add(p); - p = parent.get(p); - } - - // 找从q到根节点的路径,在寻找的过程中,跟p到根节点的路径进行比对,第一个相同的节点就是最低公共祖先 - while (!ancestors.contains(q)) - q = parent.get(q); - return q; - } - -} -``` -复杂度分析: -假设树节点数为N -空间复杂度:O(N),最坏情况下,树高为N -时间复杂度:O(N),最坏情况下,需要都访问一遍 - -参考资料 -- leetcode官方题解 [leetcode官方题解](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/) -- leetcode得票最多题解[leetcode discuss](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/discuss/65225/4-lines-C%2B%2BJavaPythonRuby) \ No newline at end of file diff --git a/_site/leetcode/239-slidingWindowMaximum/official.md b/_site/leetcode/239-slidingWindowMaximum/official.md deleted file mode 100644 index 2b651cf..0000000 --- a/_site/leetcode/239-slidingWindowMaximum/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**239. 滑动窗口最大值** ---- -[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) - diff --git a/_site/leetcode/242-ValidAnagram/bigablecat.md b/_site/leetcode/242-ValidAnagram/bigablecat.md deleted file mode 100644 index e0fd459..0000000 --- a/_site/leetcode/242-ValidAnagram/bigablecat.md +++ /dev/null @@ -1,92 +0,0 @@ -**242. 有效的字母异位词** ---- -[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) - -* 官方题解方法1:排序后对比是否相等 - -```java - - public boolean isAnagram(String s, String t) { - if (s == null || t == null) return false; - //如果长度不等,直接返回false - if (s.length() != t.length()) return false; - - //将两个字符串转换为字符数组char[] - char[] sChar = s.toCharArray(); - char[] tChar = t.toCharArray(); - - //使用Arrays的sort方法分别为两个字符数组排序 - //Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进,时间复杂度稳定为O(nlogn) - Arrays.sort(sChar); - Arrays.sort(tChar); - - //比较排序后的两个字符数组是否相等 - return Arrays.equals(sChar, tChar); - } - -``` - -**复杂度分析** - -时间复杂度:O(nlogn),假设n是s的长度 -排序的时间复杂度O(nlogn),对比两个字符串的时间复杂度O(n) -总的复杂度是 nlogn+n,舍弃n,所以最终复杂度是O(nlogn) - -空间复杂度:O(1),如果使用堆排序,需要O(1)的辅助空间; -本题的Java解法toCharArray有复制原字符串的行为,所以使用了O(n)的辅助空间 - ---- - -
- -* 官方题解方法2:用计数器统计每个字符出现的次数 - -```java - - if (s == null || t == null) return false; - //如果两个字符串长度不同,直接返回false - if (s.length() != t.length()) { - return false; - } - // 假设单词里的字符都在a~z的范围内,创建一个长度为26的int数组作为计数器 - // 数组中每个元素的默认值都是0,相当于为26个英文字母逐个建立了计数器 - int[] counter = new int[26]; - //遍历字符串s - for (int i = 0; i < s.length(); i++) { - //s.charAt(i)获取当前字符 - //s.charAt(i) - 'a' 得到当前字符与a的差,数值在0~25之间 - //counter[s.charAt(i) - 'a']从counter中获取当前字符所在位置的计数 - //counter[s.charAt(i) - 'a']++ 将当前字符在counter中的计数值+1 - counter[s.charAt(i) - 'a']++; - //同理,将t中当前字符在counter的计数值-1 - counter[t.charAt(i) - 'a']--; - } - //当所有字符遍历完成后,如果每个字符都出现了相同的次数,counter中所有元素都将归零 - //遍历counter查看计数器数组是否已经归零 - for (int count : counter) { - //出现非0的情况,说明有不同的字符 - if (count != 0) { - return false; - } - } - return true; - -``` - -**复杂度分析** - -时间复杂度: O(n). 遍历s的长度,时间复杂度为n - -空间复杂度: O(1),使用的counter数组容量是常数所以空间复杂度为 O(1) - ---- - - -**参考资料** - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) - - -* Collections.sort()的用法和要点: -[https://blog.csdn.net/wsll581/article/details/79953589](https://blog.csdn.net/wsll581/article/details/79953589) diff --git a/_site/leetcode/260-SingleNumberIII/README.md b/_site/leetcode/260-SingleNumberIII/README.md deleted file mode 100644 index 6797db8..0000000 --- a/_site/leetcode/260-SingleNumberIII/README.md +++ /dev/null @@ -1,17 +0,0 @@ -**260. 只出现一次的数字 III** ---- -[https://leetcode-cn.com/problems/single-number-iii/](https://leetcode-cn.com/problems/single-number-iii/) - -给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 - -示例 : - -``` -输入: [1,2,1,3,2,5] -输出: [3,5] -``` - -注意: - -1. 结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。 -2. 你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现? diff --git a/_site/leetcode/264-UglyNumberII/bigablecat.md b/_site/leetcode/264-UglyNumberII/bigablecat.md deleted file mode 100644 index 8bc4a83..0000000 --- a/_site/leetcode/264-UglyNumberII/bigablecat.md +++ /dev/null @@ -1,86 +0,0 @@ -**264. 丑数 II** ---- -[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) - -* 网友高票Java解法 - -```java - - /** - * https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution - * 网友高票Java解法 - *

- * 思路: - * 丑数从大到小依次为 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … - * 因为丑数只能被2,3,5整除 - * 可以将丑数拆分为3组 - * (factor2) 1×2, 2×2, 3×2, 4×2, 5×2, 6x2, 8x2 … - * (factor3) 1×3, 2×3, 3×3, 4×3, 5×3, 6x3, 8x3 … - * (factor5) 1×5, 2×5, 3×5, 4×5, 5×5, 6x5, 8x5 … - *

- * 即丑数在自身基础上不断累乘2,3,5中的一个数 - * 从这三组中依次选取最小的数存入丑数数组 - * 就得到了丑数从小到大排列的所有丑数 - * - * - * @param n - * @return - */ - public int nthUglyNumber(int n) { - //创建一个大小为n的整数数组ugly - int[] ugly = new int[n]; - //丑数从1开始,所以ugly数组的第一个元素赋值为1 - ugly[0] = 1; - //将丑数分为3组,factor2, factor3, factor5 分别与2,3,5累乘 - //定义下标index2,index3,index5获取丑数数组ugly中相应位置的数字 - int index2 = 0, index3 = 0, index5 = 0; - int factor2 = 2, factor3 = 3, factor5 = 5; - //从下标1,即ugly第二个元素开始循环,依次为ugly数组所有元素赋值 - for (int i = 1; i < n; i++) { - //获取累乘2,3,5的三组数中的最小值 - int min = Math.min(Math.min(factor2, factor3), factor5); - //让数组当前位置等于三者中最小值 - ugly[i] = min; - //下列代码 - //首先查看 ugly[i] = min 是从factor2,factor3,factor5三组中哪一组里取走数字 - // (factor2) 1×2, 2×2, 3×2, 4×2, 5×2, 6x2, 8x2 … - // (factor3) 1×3, 2×3, 3×3, 4×3, 5×3, 6x3, 8x3 … - // (factor5) 1×5, 2×5, 3×5, 4×5, 5×5, 6x5, 8x5 … - //然后通过这一组数对应的下标index2,index3或index5, - //从ugly数组中选取能够继续累乘的最小数字 - //累乘的同时,对应的索引递增,下次不会取到重复数字 - //比如ugly[1] = 2; - //此时factor2 = 2, factor3 = 3, factor5 = 5; - //即 ugly[1] = factor2 = ugly[0] x 2 = 1 x 2 - // factor2这一组的第一个数字被取走了 - // 接下来要获取factor2这一组的第二个数字 - // factor2 = ugly[1] x 2 = 2 x 2 = 4 - if (factor2 == min) - factor2 = 2 * ugly[++index2]; - if (factor3 == min) - factor3 = 3 * ugly[++index3]; - if (factor5 == min) - factor5 = 5 * ugly[++index5]; - } - //ugly数组从下标0开始获取第一个数字 - //那么第n个数字的下标就是n-1 - //所以最终返回ugly[n - 1] - return ugly[n - 1]; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -只有一个for循环进行了n次迭代 - -空间复杂度:O(n), -创建了一个大小为n的数组ugly - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) diff --git a/_site/leetcode/264-UglyNumberII/official.md b/_site/leetcode/264-UglyNumberII/official.md deleted file mode 100644 index 8795cdc..0000000 --- a/_site/leetcode/264-UglyNumberII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**264. 丑数 II** ---- -[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) diff --git a/_site/leetcode/279-PerfectSquares/official.md b/_site/leetcode/279-PerfectSquares/official.md deleted file mode 100644 index f0a46e8..0000000 --- a/_site/leetcode/279-PerfectSquares/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**279. 完全平方数** ---- -[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) diff --git a/_site/leetcode/279-PerfectSquares/zengdiqing1994.md b/_site/leetcode/279-PerfectSquares/zengdiqing1994.md deleted file mode 100644 index 2bcefcf..0000000 --- a/_site/leetcode/279-PerfectSquares/zengdiqing1994.md +++ /dev/null @@ -1,59 +0,0 @@ -279.完全平方数 - -https://leetcode-cn.com/problems/perfect-squares/ - -给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 - -示例 1: - -输入: n = 12 -输出: 3 -解释: 12 = 4 + 4 + 4. -示例 2: - -输入: n = 13 -输出: 2 -解释: 13 = 4 + 9. - -**思路:** -1.DP动态规划,关键在于状态的定义和状态方程,我们要知道12最少有多少个数构成,实际上如果我们走了一步的话,要知道11,8,3对应的步数,如果我们不走, -就需要知道12的步数,我们只要通过比较是走0步小,还是走1步那个更小即可。 - -状态转移方程: -num[n] = min(num[n],num[n-i**2]+1) - -所以可以先定一个n大小的数组(static类型),需要使数组初始化为无穷大 - -``` -class Solution: - _dp = list() #放到全局,能节省很多时间 - def numSquares(self, n): - """ - :type n: int - :rtype: int - """ - dp = self._dp - dp = [float('inf') for i in range(n+1)] #状态定义 - dp[0] = 0 - for i in range(n+1): - j = 1 - while i + j**2 <= n: - dp[i + j**2] = min(dp[i + j**2],dp[i] + 1) #状态转移方程 - j+=1 - return dp[n] -``` -但是这种方法时间复杂度O(n^2)超时了,参考了别人的代码: - -``` -class Solution: - _dp = [0] - def numSquares(self, n): - dp = self._dp - while len(dp) <= n: - dp += list((min(dp[-i*i] for i in range(1,int(len(dp)**0.5+1)))+1,)) #这里的int无法初始化list,我们只有通过加上一个',', - 将int变成tuple才可以初始化。 - return dp[n] -``` -这个时候时间复杂度是O(NlogN),时间大大减少 - -参考:https://www.codetd.com/article/2640989 diff --git a/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md b/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md deleted file mode 100644 index 6ecec86..0000000 --- a/_site/leetcode/295-FindMedianFromDataStream/BambooYH.md +++ /dev/null @@ -1,71 +0,0 @@ -**找数据流的中位数** ---- -[https://leetcode.com/problems/find-median-from-data-stream/](https://leetcode.com/problems/find-median-from-data-stream/) - -近似题目 -[找数组中第K大的数](https://github.com/hollischuang/Interview/tree/master/algorithm/leetcode/215-KthLargestElementInAnArray) -[找数据流中第K大的数](https://github.com/hollischuang/Interview/tree/master/algorithm/leetcode/703-KthLargestElementInAStream) - -解决方案: -方法一:**堆** -思路: -首先,最容易想到的就是,每加进来一个数都重新排序,然后找中位数,但是这样的时间复杂度肯定是接受不了的。 -中位数可能是一个,也可能是两个,如果是两个的话,需要取平均值。这个题最重要的一点是,我们要有两个指针,可以随着数据流动态的记录两个中位数的位置或者值。如果总数是奇数,则两个指针指向同一个位置。所以这个题可以有多个解法。 -这里我们采用栈来实现,用一个最大栈,一个最小栈。在处理的过程中,我们要维持`|Size(MaxHeap) - Size(MinHeap)| <= 1`,这时候,两个栈的栈顶就相当于两个指针,他们始终指向中位数 -**算法** -创建两个堆,最大堆和最小堆。向堆里加元素的算法是: -1. 如果当前元素总数是奇数,则先将元素放入到最小堆,然后将最小堆堆顶的元素取出来,放入最大堆里面 -2. 如果当前元素总数为偶数,则先将元素放入到最大堆里面,然后将最大堆堆顶的元素取出来,放入最小堆 - -取中位数的算法是: -1. 如果当前元素总数是奇数,则直接取最大堆堆顶的元素 -2. 如果当前元素总数是偶数,则分别取最大堆和最小堆堆顶的元素,然后取平均值 - -代码: -``` -class MedianFinder { - PriorityQueue min; - PriorityQueue max; - int count;//记录元素总数 - /** initialize your data structure here. */ - public MedianFinder() { - //初始化堆和count - count = 0; - min = new PriorityQueue(); - max = new PriorityQueue(new Comparator(){ - public int compare(Integer a, Integer b) { - return b - a; - } - }); - - } - - public void addNum(int num) { - count++; - //如果当前元素总数是奇数,则先将元素放入到最小堆,然后将最小堆堆顶的元素取出来,放入最大堆里面 - if((count & 1) == 1) { - min.offer(num); - max.offer(min.poll()); - // 如果当前元素总数为偶数,则先将元素放入到最大堆里面,然后将最大堆堆顶的元素取出来,放入最小堆 - }else { - max.offer(num); - min.offer(max.poll()); - } - - } - - public double findMedian() { - //如果当前元素总数是奇数,则直接取最大堆堆顶的元素 - if((count & 1) == 1) { - return max.peek(); - //如果当前元素总数是偶数,则分别取最大堆和最小堆堆顶的元素,然后取平均值 - }else { - return ((double)(max.peek()+min.peek()))/2; - } - } -} - -``` -复杂度分析: -空间复杂度:O(n),n为数据流的长度 -时间复杂度:O(logn) \ No newline at end of file diff --git a/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md b/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md deleted file mode 100644 index 6d13bf9..0000000 --- a/_site/leetcode/300-LongestIncreasingSubsequence/melody-l.md +++ /dev/null @@ -1,87 +0,0 @@ -**300. LongestIncreasingSubsequence** ---- -[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) - -方法一:动态规划 - -思路:从头开始遍历,查找以当前点为数组最后位置的最长子序列。由于当前点前面的所有点的最长子序列已经遍历完成了,所以只是需要找到前面所有子序列的最大值即可。 -即令F(i)表示数组nums的从0到i位的最长子序列长度。则有F(i)=max{F(0)...F(i-1)}+1 -所以代码如下: - -```java -public class Solution { - //从前往后 - public int lengthOfLIS(int[] nums) { - if (nums.length == 0) // 测试用例中有集合为空的例子 - return 0; - - int max = 0;// 保存最大值 - int[] result = new int[nums.length];// 保存每一位最长子序列结果的数组,初始化默认值为0 - for (int i = 0; i < nums.length; i++) { // 从左至右顺序遍历每一位 - result[i] = 1; // 对于每一位,其最长子序列至少为一 - for (int j = 0; j < i; j++) {// 从数组开始到当前位置,找寻前面所有的数的最大子序列长度 - // 最大子序列长度寻找标准: - // 1.查找的数比当前位置数小(即能构成上升序列) - // 2.查找的数的最大上升子序列长度加一 比目前所记录的最大上升子序列长度大 - if (nums[j] < nums[i] && (result[j] + 1) > result[i]) { - result[i] = result[j] + 1; - } - } - // 记录从开始到当前位置所求最大上升子序列长度最大的 - max = Math.max(result[i], max); - } - - return max; - } -} -``` - -方法二: 二分法+贪心 -(官方题解称之为dp,我个人倾向于贪心) - -根据题目中的序列进行举例分析nums = [10,9,2,5,3,7,101,18],最大上升子序列为[2,3,7,101],长度为4 -思路: 以未知的最长子序列为对象进行分析。 -假设已知nums序列的一个上升子序列为x[0...n]。题目是求x[0...n]的最大长度,因此所有的行为都以能够提高长度为目的。若现在将nums[i]插入x[0...n]中,判断其对增长上升子序列长度的影响。 -* 若nums[i]>x[n],则插入nums[i]能够增加上升子序列长度; -* 若nums[i]答案示例,本人自行编写后参考LeetCode官方题库。 - -**304. 二维区域和检索-矩阵不可变** ---- -[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) - -摘要 - -本文适用于初学者,潜入深出。 - - -```java - -package algorithm_leetcode; - -//看到这道题目时,给我第一印象似乎只有一种方法来解决 -class NumMatrix2{ - //定义成员变量 - private int[][] data; - public NumMatrix2(int[][] matrix){ - data=matrix; - } - //普通的方法用来计算完对应范围的数据的和 - public int sumRegion(int row1, int col1, int row2, int col2){ - int k=0; - //走完所有的ROWS - for(int i=row1;i<=row2;i++){ - //走完所有的COLUMS - for(int j=col1;j<=col2;j++){ - //进行累加 - k+=data[i][j]; - } - } - //返回给调用者 - return k; - } -} -//认为leetCode中省略的代码 -public class T304RangeSumQuery2DImmutable2 { - public static void main(String[] args) { - int[][] matrix={ {3, 0, 1, 4, 2}, - {5, 6, 3, 2, 1}, - {1, 2, 0, 1, 5}, - {4, 1, 0, 1, 7}, - {1, 0, 4, 0, 5}}; - int row1=2; - int col1=1; - int row2=4; - int col2=3; - NumMatrix2 obj = new NumMatrix2(matrix); - int param_1 = obj.sumRegion(row1,col1,row2,col2); - System.err.println(param_1); - } -} -//如果你在自己的工具上写完后,乍一看好像没有别的好的解决方法了吧 -//但是仔细思考下会发现leetCode中用了一个有参构造方法,类是对象的模板,对象是类的实例, -//分配空间-->递归创建父类对象-->初始化本类属性-->调用本类构造方法 -//这些都是在缓存中完成的,所以如果可以借助这个构造方法来做一些计算数组的事情会提高效率 -class NumMatrix { - //成员变量 - private int[][] dp; - //有参构造方法 - public NumMatrix(int[][] matrix) { - //排除数组长度为0的情况 - if (matrix.length == 0 || matrix[0].length == 0) return; - //建一个新的数组 - dp = new int[matrix.length + 1][matrix[0].length + 1]; - //走完matrix的所有ROWS - for (int r = 0; r < matrix.length; r++) { - //走完matrix的所有COLUMS - for (int c = 0; c < matrix[0].length; c++) { - //System.out.print("dp:"+dp[r + 1][c + 1]+"=" + dp[r + 1][c] +"+"+ dp[r][c + 1]+"+" + matrix[r][c] +"-"+ dp[r][c]); - //System.out.println(); - //这样是为了实现某个数据上如 dp[1][2] 你取到的这个值就是从dp[0][0]到dp[1][2]的所有值的和 - dp[r + 1][c + 1] = dp[r + 1][c] + dp[r][c + 1] + matrix[r][c] - dp[r][c]; - } - } - } - public int sumRegion(int row1, int col1, int row2, int col2) { - //System.out.println("dp:"+dp[row2 + 1][col2 + 1]+"-" + dp[row1][col2 + 1] +"-"+ dp[row2 + 1][col1]+"+" + dp[row1][col1]); - //想求得某个区域的和,要减去两个部分区域但是这两部分区域有交集,即会多减掉一个交集。 - return dp[row2 + 1][col2 + 1] - dp[row1][col2 + 1] - dp[row2 + 1][col1] + dp[row1][col1]; - } -``` - ---- - - -**参考资料** - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) diff --git a/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md b/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md deleted file mode 100644 index 78ce4c3..0000000 --- a/_site/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md +++ /dev/null @@ -1,85 +0,0 @@ -**309. 最佳买卖股票时机含冷冻期** ---- -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) - -* 网友高票Java答案(动态规划) - -```java - public static int maxProfit(int[] prices) { - //定义变量 - //sell表示只能卖出或持有时所得的总利润 - //prev_sell用于缓存上一次的sell值 - //buy表示只能买入或持有时所得的总利润 - //prev_buy用于缓存上一次的buy值 - int sell = 0, prev_sell = 0, buy = Integer.MIN_VALUE, prev_buy; - - for (int price : prices) { - // buy的值来自上一次循环结果,将其赋值给prev_buy - prev_buy = buy; - - // 如果当前日期只能买入或持有,buy的值有两种情况 - // 第一种情况:在当前日期进行了买入操作 - // prev_sell - price - // prev_sell 是前一次进行卖出操作时所得利润总和 - // price是当前日期价格,也就买入股票所需的支出 - // 利润-支出,得到在当前日期买入后剩余的利润 - // 第二种情况:当前日期不进行任何操作 - // 直接使用pre_buy的值即可 - // 从二者中比较出利润较大者,赋值给变量buy - // buy就是当前日期只能买入或持有时所得最大利润 - buy = Math.max(prev_sell - price, prev_buy); - - // 同理可得只能卖出或持有时所得利润sell的值 - prev_sell = sell; - - // 不同的是对的Math.max(prev_buy + price, prev_sell)部分的解释 - // prev_buy + price - // prev_buy 是前一次进行买入操作时所得利润总和 - // price是当前日期价格,也就卖出股票所得的收入 - // 利润+支出,得到在当前日期卖出后总共获得的利润 - sell = Math.max(prev_buy + price, prev_sell); - } - - //到最后一个交易日为止,最后的一次操作只能是卖出才能清仓 - //所以返回sell的值即可 - return sell; - - //上述代码中还有2个问题需要解决 - //第一个问题,会不会在同一天既买入又卖出? - //如果进行了卖出操作,sell = prev_buy + price - //prev_buy不是当天的买入的结果 - //所以同一天内,买和卖都是在上一次结果的基础上交易 - //第二个问题,会不会出现连续买入或连续卖出的情况? - //假设连续买入而没有卖出 - //在第i-1天买入,buy[i-1] = prev_sell - prices[i-1] - //在第i天继续买入,buy[i] = prev_sell - prices[i] - //因为没有卖出,所以prev_sell是相等的 - //这样buy[i]的操作实际上冲抵了buy[i-1]的操作 - //即原本在第i-1天用prev_sell买入 - //经过比较,发现第i天买入更划算 - //那么用prev_sell在第i天买入 - //可以看出,只要prev_sell的值保持不变 - //则永远只能在prev_sell的基础上发生1次买入 - //而prev_sell的值发生了变化,说明已经进行了一次卖出操作 - //再一次的买入是在新的卖出基础上进行的 - //同理,sell = prev_buy + price 中sell也只能是一种置换 - //结合冷冻期的解释,可以总结出 - //在同一天内,买和卖都只能基于上一次的交易结果 - //买和卖永远只会成对出现 - - } - -``` - -**复杂度分析** - -时间复杂度:O(n),遍历一次 - -空间复杂度:O(1),没有使用额外空间 - ---- - -**参考资料** - -* 网友高票Java答案: -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) diff --git a/_site/leetcode/312-BurstBalloons/melody-l.md b/_site/leetcode/312-BurstBalloons/melody-l.md deleted file mode 100644 index e1ec007..0000000 --- a/_site/leetcode/312-BurstBalloons/melody-l.md +++ /dev/null @@ -1,57 +0,0 @@ -**312. burst-balloons** - ---- -[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) - -* 该问题主要难推导出状态转移方程。 -1. 如果是贪心的思路,即每次选择都是最大值,是无法得到最优解的。例如本题中的例子,第一步选择的是1而不是5,如果按照贪心的思路应该选择的是5。 -2. 如果死dp的思路,中间态的定义是:设`dp[i][j]`表示的是 **序列nums在从i到j都戳破的情况下,得到的硬币的最大值**。因此,`dp[1][n]`表示的是都戳破得到硬币的最大值,即为我们所求。此时,**假设nums从i到j,所有的气球都戳破了而最后戳破的是k**,则此时的硬币分数为`nums[i-1] * nums[k] * nums[j+1]` 加上之前的分数。而之前的分数是`dp[i][k-1]`和`dp[k+1][j]`,即`dp[i][j] = nums[i-1] * nums[k] * nums[j+1] + dp[i][k-1] + dp[k+1][j]`。因此,若dp表示的是最大值,则算法思路为从i到j遍历,求出来的最大值即为所求。故递推式为: `dp[i][j] = Max{ nums[i-1] * nums[k] * nums[j+1] + dp[i][k-1] + dp[k+1][j] }, 其中k表示从i到j`。 - -* 有了递推式后,需要确定遍历顺序。根据递推式可以看出,递推的顺序是按照序列的长度递增来的,即先遍历序列长度为1的组合,后遍历序列长度为2的组合。 - ---- - -方法一:动态规划 - -```java - -public class Solution { - public int maxCoins(int[] nums) { - // 为了计算方便,使用新的数组来代替之前的数组 - // 新的数组在nums的前面加上一个1,在末尾加上了一个1, - // 这样能够统一处理, - // 因此下面遍历的时候,是从1开始,到nums.length结束,包括nums.length - int[] newNum = new int[nums.length + 2]; - System.arraycopy(nums, 0, newNum, 1, nums.length); - newNum[0] = 1; - newNum[nums.length+1] = 1; - // 用来存储所有的dp结果 - // dp[i][j]表示从i到j所有的气球都戳破所得到的最大值 - int[][] dp = new int[nums.length + 2][nums.length + 2]; - - // 由上文分析可知,从nums序列长度为1的开始遍历, - // 注意:长度为1,此处length为0。 - for (int length = 0; length < nums.length; length++) { - // 开始计算当nums长度一定的情况下,所有的可能组合的dp值 - for (int i = 1; i <= nums.length - length; i++) { - // 计算长度为length+1的时候,末尾j应该处于的位置, - // 此处不需要担心j超过数组长度, - // 因为i的遍历进行了限制,i只会遍历到最后一个满足length+1长度的起始索引位置 - int j = i + length; - // 确定了i与j的范围, - // 根据递推式从i到j顺序遍历,找到dp[i][j]的最大值 - for (int k = i; k <= j; k++) { - dp[i][j] = Math.max(dp[i][j], newNum[i - 1] * newNum[k] * newNum[j+1 ] + dp[i][k - 1] + dp[k + 1][j]); - } - } - } - - return dp[1][nums.length]; - } -} - -``` - -**参考资料** -* 网友答案: -[https://www.cnblogs.com/grandyang/p/5006441.html](https://www.cnblogs.com/grandyang/p/5006441.html) diff --git a/_site/leetcode/312-BurstBalloons/official.md b/_site/leetcode/312-BurstBalloons/official.md deleted file mode 100644 index 81fc5b0..0000000 --- a/_site/leetcode/312-BurstBalloons/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**312. 戳气球** ---- -[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) diff --git a/_site/leetcode/321-CreateMaximumNumber/README.md b/_site/leetcode/321-CreateMaximumNumber/README.md deleted file mode 100644 index e379863..0000000 --- a/_site/leetcode/321-CreateMaximumNumber/README.md +++ /dev/null @@ -1,48 +0,0 @@ -**321. 拼接最大数** ---- -[https://leetcode-cn.com/problems/create-maximum-number/](https://leetcode-cn.com/problems/create-maximum-number/) - -**难度** -困难 - -**题目描述** - -给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。 - -求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。 - -说明: 请尽可能地优化你算法的时间和空间复杂度。 - -**示例 1:** -``` -输入: -nums1 = [3, 4, 6, 5] -nums2 = [9, 1, 2, 5, 8, 3] -k = 5 -输出: -[9, 8, 6, 5, 3] -``` - -**示例 2:** -``` -输入: -nums1 = [6, 7] -nums2 = [6, 0, 4] -k = 5 -输出: -[6, 7, 6, 0, 4] -``` - -**示例 3:** -``` -输入: -nums1 = [3, 9] -nums2 = [8, 9] -k = 3 -输出: -[9, 8, 9] -``` - - -**相关话题** -贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/322-CoinChange/official.md b/_site/leetcode/322-CoinChange/official.md deleted file mode 100644 index 1e9be82..0000000 --- a/_site/leetcode/322-CoinChange/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**322. 零钱兑换** ---- -[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) diff --git a/_site/leetcode/338-CountingBits/bigablecat.md b/_site/leetcode/338-CountingBits/bigablecat.md deleted file mode 100644 index c5659b9..0000000 --- a/_site/leetcode/338-CountingBits/bigablecat.md +++ /dev/null @@ -1,104 +0,0 @@ -**338. 比特位计数** ---- - -[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) - -* 网友高效Java解法 - -```java - - public int[] countBits(int num) { - //新建一个数组,数组长度为num+1 - //因为题设 0 ≤ i ≤ num,从0到num总共需要num+1的空间 - int[] res = new int[num + 1]; - //从i=1开始,在num的长度内进行遍历 - //因为0的二进制数里位1的个数为0,res[0]的值本身就等于0,所以i=0无需统计 - for (int i = 1; i <= num; i++) { - //i & (i - 1)的位与运算会消去i的二进制数中最低有效的1位 - //所以正整数i的二进制数中位1的个数,与i & (i - 1)相比少了1个 - //res[i & (i - 1)]找到正整数i & (i - 1)中位1的个数 - //再多加1个,即得到正整数i中位1的个数 - res[i] = res[i & (i - 1)] + 1; - // 完整过程举例: - // 假设 i = 6,n的32位二进制数的最右边四位是 0110 - // i - 1 的32位二进制数的最右边四位是 0101 - // i & (i-1),即 0110 & 0101 = 0100 - // 原本 0110 中的最低有效1位被消去,即右向左数的第一个1 - } - return res; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -方法只用了一个循环,取决于整数num的大小, -所以时间复杂度是O(n) - -空间复杂度:O(n), -新建数组res,占用了n+1的空间, -所以空间复杂度是O(n) - ---- - -* 网友高票Java解法 - -```java - - public int[] countBits(int num) { - //新建一个数组,数组长度为num+1 - //因为题设 0 ≤ i ≤ num,从0到num总共需要num+1的空间 - int[] f = new int[num + 1]; - //从i=1开始,在num的长度内进行遍历 - //因为0的二进制数里位1的个数为0,f[0]的值本身就等于0,所以i=0无需统计 - for (int i = 1; i <= num; i++) { - // i >> 1 二进制右移1位,相当于整数运算中的 i / 2 - // i & 1 二进制的位与运算,相当于整数运算中的 i % 2 - // 数组f记录了每个相应位置正整数的二进制数里位1的个数 - // f[i/2]就是i/2这个正整数的二进制数里位1的个数 - // 加上 i % 2,也就是这个正整数模2的余数 - // 每一个正整数i,都遵循 f[i] = f[i/2] + (i%2) - f[i] = f[i >> 1] + (i & 1); - // 为什么会有上述结果 - // 实际上是这行代码利用了正整数转二进制数计算方法中的规律; - // 正整数转二进制数就是该正整数与2相除得到的整数结果继续除以2 - // 重复上述计算,直到运算结果等于1为止, - // 假设运算过程中有n次余数为1,那么二进制数中就n+1个位1 - // 其中n加上1是最终运算结果里的1 - // 举例如下: - // 9/2 = 4...1 - // 4/2 = 2...0 - // 2/2 = 1...0 - // 9在与2相除的过程中,出现了1次余数为1的情况, - // 最终结果为1,运算中总共出现了2次1,所以9的二进制数中有2个1 - // 从上述计算中还可以发现,9的二进制数中有多少个1, - // 可以参照9/2的正整数结果4的二进制数中有多少个1, - // 用4的二进制数中1的个数,加上9/2的余数,即9的二进制数中1的个数 - // f[i] = f[i >> 1] + (i & 1); 正是利用了上述规律 - } - return f; - } - - -``` - -**复杂度分析** - -时间复杂度:O(n), -方法只用了一个循环,取决于整数num的大小, -所以时间复杂度是O(n) - -空间复杂度:O(n), -新建数组f,占用了n+1的空间, -所以空间复杂度是O(n) - ---- - -**参考资料** - -* 网友高效Java解法: -[https://leetcode-cn.com/submissions/api/detail/338/java/1](https://leetcode-cn.com/submissions/api/detail/338/java/1) - -* 网友高票Java解法: -[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) diff --git a/_site/leetcode/343-IntegerBreak/hatrick.md b/_site/leetcode/343-IntegerBreak/hatrick.md deleted file mode 100644 index 7f62daf..0000000 --- a/_site/leetcode/343-IntegerBreak/hatrick.md +++ /dev/null @@ -1,38 +0,0 @@ -**343. 整数拆分** ---- -[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) - -解决方案 -**思路** -建立一个乘积数组,数组的下标i存放这i所能拆分之后的最大乘积,然后下标为n的数的最大乘积可以表示为两个更小的数所能拆分的乘积之和, -而这两个更小的数可以进一步拆分,不过这一步已经被记录在乘积数组中了,我们不必再考虑进一步的拆分 -``` -class Solution { - public int integerBreak(int n) { - int[] product =new int[n+1]; - //product数组用来存放数i所能拆分的最大乘积 - product[1]=1; - for(int i=1;i<=n;i++) - { - int a=1,b=i-1; - while(a<=b&&a+b==i) - { - int multi =(product[a]>a?product[a]:a)*(product[b]>b?product[b]:b); - //将数i拆分成a和b,要想产生最大乘积,我们需要选出a所拆分出的乘积和a本身中较大的一个数 - if(product[i]nums[i+1],这样循环就判断前面的数字能否整除后面的数字。定义一个数组dp,其中dp[i]表示数字nums[i]位置最大可整除的子集合的长度,还需要一个数组parent,来保存上一个整除的数字的位置,两个整型变量max和max_idx分别表示最大子集合的长度和起始数字位置,遍历数组。 - -1.数组排序 - -2.递归动态规划规律 如果nums[j]能整除nums[i], 且dp[i] < dp[j] + 1的话,更新dp[i]和parent[i],如果dp[i]大于max了,更新max和max_idx - -3.最后循环结束后,我们来填res数字,根据parent数组来找到每一个数字 - -**具体代码** - -``` -public List largestDivisibleSubset(int[] nums) { - - if (nums == null || nums.length == 0) { - return new ArrayList<>(); - } - Arrays.sort(nums); - int n = nums.length; - int[] dp = new int[n]; - int[] parent = new int[n]; - int max = 0, max_idx = 0; - for (int i = 0; i < n; i++) { - dp[i] = 1; - parent[i] = -1; - for (int j = 0; j < i; j++) { - if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) { - dp[i] = dp[j] + 1; - parent[i] = j; - } - } - if (max < dp[i]) { - max = dp[i]; - max_idx = i; - } - } - List res = new ArrayList<>(); - do { - res.add(nums[max_idx]); - max_idx = parent[max_idx]; - } while (max_idx != -1); - return res; -} - -``` -**时间复杂度** O(N^2) - - -leetcode 代码提交后执行时间48ms只击败了30%的用户有待优化 - -思路类似,cache一些数据优化执行效率42ms - -``` -public List largestDivisibleSubset(int[] nums) { - List> list = new ArrayList(); - if(nums.length < 1) return new ArrayList(); - int max = 0; - int p = 0; - for(int k = 0; k < nums.length; k++){ - list.add(k, new ArrayList()); - } - - if(nums.length >= 1){ - Arrays.sort(nums); - int[] leng = new int[nums.length]; - int j = 0; - for(int i = 0; i < nums.length; i++){ - for(j = i - 1; j >= 0; j--){ - if(nums[i] % nums[j] == 0 && nums[i] > nums[j]){ - if(leng[i] < leng[j] + 1){ - leng[i] = leng[j] + 1; - list.set(i,new ArrayList(list.get(j))); - list.get(i).add(nums[i]); - if(max < leng[i]) { - max = leng[i]; - p = i; - } - } - } - } - if(j < 0 && leng[i] == 0) { - list.get(i).add(nums[i]); - leng[i] = 1; - } - - } - } - return list.get(p); -} - -``` -leetcode上star效率更高的解法 [具体地址](https://leetcode.com/problems/largest-divisible-subset/discuss/83999/Easy-understood-Java-DP-solution-in-28ms-with-O(n2)-time) - - diff --git a/_site/leetcode/374-GuessNumberHigherOrLower/official.md b/_site/leetcode/374-GuessNumberHigherOrLower/official.md deleted file mode 100644 index 677d387..0000000 --- a/_site/leetcode/374-GuessNumberHigherOrLower/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**374. 猜数字大小** ---- -[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) diff --git a/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md b/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md deleted file mode 100644 index 24d3f34..0000000 --- a/_site/leetcode/375-GuessNumberHigherOrLowerII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**375. 猜数字大小 II** ---- -[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) diff --git a/_site/leetcode/376-WiggleSubsequence/melody-l.md b/_site/leetcode/376-WiggleSubsequence/melody-l.md deleted file mode 100644 index cfe0036..0000000 --- a/_site/leetcode/376-WiggleSubsequence/melody-l.md +++ /dev/null @@ -1,61 +0,0 @@ -**376.WiggleSubsequence** ---- -[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) - -方法一:贪心算法 -官方题解的dp算法实际上也是再找波峰与波谷的个数,所以个人倾向于贪心的思想更多一点。 - -贪心的思想是:对于摆动序列,只要有序列存在摆动的地方,那么这个摆动处的元素就得加入到结果集中。我们就是要计算摆动的个数。 -所以算法思路为:记录第一次出现波峰(nums[i+1]-nums[i]>0)或者波谷(nums[i+1]-nums[i]<0)的位置和状态,序列长度加一。按顺序查找序列,寻找一个与之前状态相反的状态,(即若之前状态是波峰则当前状态应该是波谷),找到后改变当前状态,序列长度加一,继续寻找。 - -```java -class Solution { - public int wiggleMaxLength(int[] nums) { - // 如果数组长度小于2,则不会有波动 - if (nums.length < 2) return nums.length; - // 如果没有波动序列,那么值应该为1,所以初始值设为1 - int size = 1; - // 下一个应该正(波峰)还是负(波谷)的标识量 - int nextSignal = nums[0]-nums[1]; - // 由于刚开始就计算了两个,因此判断起初计算的两个有没有波峰或波谷, - // 若有,则序列长度加一 - if(nextSignal!=0) size++; - - // 从第二个开始,向后面看, - // 如果发现存在波峰波谷交替出现,那么就保存到结果中 - for (int i=1; i 0) { - // 如果当前的状态(即当前是波峰或者波谷)和标识量(下一个应该是波峰还是波谷)是一致的, - // 则将结果加一, - // 当前状态改变为相反的状态 - size++; - nextSignal = -temp; - } else if (nextSignal==0 && temp!=0){ - // 若状态码为0,则说明之前一直都是相同的数字,没有起伏 - // 若temp不为0,则说明此时索引处的数字有起伏 - // 因此,下一个状态为此时索引处的相反状态, - // 然后结果加一 - nextSignal = -temp; - size++; - } - - // 备注:两个条件可以合并,这里是为了方便理解,所以分开写 - } - - return size; - } -} -``` - ---- - - -**参考资料** - -* 官方题解: -[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) diff --git a/_site/leetcode/376-WiggleSubsequence/official.md b/_site/leetcode/376-WiggleSubsequence/official.md deleted file mode 100644 index 17278c7..0000000 --- a/_site/leetcode/376-WiggleSubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**376. 摆动序列变** ---- -[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) diff --git a/_site/leetcode/377-CombinationSumIV/official.md b/_site/leetcode/377-CombinationSumIV/official.md deleted file mode 100644 index 6831959..0000000 --- a/_site/leetcode/377-CombinationSumIV/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**377. 组合总和 Ⅳ** ---- -[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) diff --git a/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md b/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md deleted file mode 100644 index 6ed3e49..0000000 --- a/_site/leetcode/378-KthSmallestElementInASortedMatrix/README.md +++ /dev/null @@ -1,22 +0,0 @@ -**378. 有序矩阵中第K小的元素** ---- -[https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/](https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/) - -给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 -请注意,它是排序后的第k小元素,而不是第k个元素。 - -示例: - -``` -matrix = [ - [ 1, 5, 9], - [10, 11, 13], - [12, 13, 15] -], -k = 8, - -返回 13。 -``` - -**说明:** -你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。 diff --git a/_site/leetcode/392-IsSubsequence/official.md b/_site/leetcode/392-IsSubsequence/official.md deleted file mode 100644 index 885cbdf..0000000 --- a/_site/leetcode/392-IsSubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**392. 判断子序列** ---- -[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) diff --git a/_site/leetcode/392-IsSubsequence/zengdiqing1994.md b/_site/leetcode/392-IsSubsequence/zengdiqing1994.md deleted file mode 100644 index f49497c..0000000 --- a/_site/leetcode/392-IsSubsequence/zengdiqing1994.md +++ /dev/null @@ -1,90 +0,0 @@ -##### 392. 判断子序列 - -https://leetcode-cn.com/problems/is-subsequence/ - -给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 - -你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 - -字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 - -示例 1: -s = "abc", t = "ahbgdc" - -返回 true. - -示例 2: -s = "axc", t = "ahbgdc" - -返回 false. - -后续挑战 : - -如果有大量输入的 S,称作S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码? - -**思路:** - -这里又用到了双指针: - -s: a b c - - | - - s_p - - -t: a h b g c k - - | - - t_p - - -这里我们不断移动t_p指针,看t_p指向的元素是否和s_p指向的相等,如果不相等的话继续移动t_p,如果相等的话也一并移动s_p,直到t_p到达了t的边界。在这期间, -如果s_p已经到达了s的边界的话,就直接返回True。若整个循环结束,就是t遍历完都没有返回true的话,就说明不存在,返回false - -代码: -``` -class Solution: - def isSubsequence(self, s, t): - if s == None or t == None: #判断字符串的是否为空 - return False - - len_s = len(s) #长度获取 - len_t = len(t) - if len_t < len_s: #判断长度的真实性 - return False - if len_s == 0: - return True - j=0 - for i in range(len_t): #若对于t串来讲,若和s相等,就继续移动 - if s[j] == t[i]: - j+=1 - if j == len_s: #最终如果移动的次数和s的长度相等就返回True - return True - return False -``` -这里的时间复杂度是O(t*s) - -python内置了find()函数可以快速定位字符的位置 -``` -class Solution: - def isSubsequence(self, s, t): - """ - :type s: str - :type t: str - :rtype: bool - """ - for seq_s in s: - s_index = t.find(seq_s) - if s_index == -1: - return False - if s_index == len(t) - 1: #如果找到的匹配的s达到了t的长度 - t = str() #字符串长度赋给t - else: - t = t[s_index+1:] #若还没匹配完,从下一个开始继续 - return True -``` -这里时间复杂度稍微低一些,为O(t*logs) - -参考:https://blog.csdn.net/fuxuemingzhu/article/details/79568772 diff --git a/_site/leetcode/403-FrogJump/README.md b/_site/leetcode/403-FrogJump/README.md deleted file mode 100644 index bfb5af2..0000000 --- a/_site/leetcode/403-FrogJump/README.md +++ /dev/null @@ -1,47 +0,0 @@ -**403. 青蛙过河** ---- -[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) - -**难度** -困难 - -**题目描述** - -一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 - -给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 - -如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 - -**请注意:** - -* 石子的数量 ≥ 2 且 < 1100; -* 每一个石子的位置序号都是一个非负整数,且其 < 231; -* 第一个石子的位置永远是0。 - -**示例 1:** -```shell -[0,1,3,5,6,8,12,17] - -总共有8个石子。 -第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, -第三个石子在序号为3的单元格的位置, 以此定义整个数组... -最后一个石子处于序号为17的单元格的位置。 - -返回 true。即青蛙可以成功过河,按照如下方案跳跃: -跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 -跳2个单位到第4块石子, 然后跳3个单位到第6块石子, -跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 -``` - -**示例 2:** -```shell - -[0,1,2,3,4,8,9,11] - -返回 false。青蛙没有办法过河。 -这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 -``` - -**相关话题** -贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/403-FrogJump/official.md b/_site/leetcode/403-FrogJump/official.md deleted file mode 100644 index bfb5af2..0000000 --- a/_site/leetcode/403-FrogJump/official.md +++ /dev/null @@ -1,47 +0,0 @@ -**403. 青蛙过河** ---- -[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) - -**难度** -困难 - -**题目描述** - -一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 - -给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 - -如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 - -**请注意:** - -* 石子的数量 ≥ 2 且 < 1100; -* 每一个石子的位置序号都是一个非负整数,且其 < 231; -* 第一个石子的位置永远是0。 - -**示例 1:** -```shell -[0,1,3,5,6,8,12,17] - -总共有8个石子。 -第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, -第三个石子在序号为3的单元格的位置, 以此定义整个数组... -最后一个石子处于序号为17的单元格的位置。 - -返回 true。即青蛙可以成功过河,按照如下方案跳跃: -跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 -跳2个单位到第4块石子, 然后跳3个单位到第6块石子, -跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 -``` - -**示例 2:** -```shell - -[0,1,2,3,4,8,9,11] - -返回 false。青蛙没有办法过河。 -这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 -``` - -**相关话题** -贪心算法,动态规划 \ No newline at end of file diff --git a/_site/leetcode/409-LongestPalindrome/README.md b/_site/leetcode/409-LongestPalindrome/README.md deleted file mode 100644 index 88bd80e..0000000 --- a/_site/leetcode/409-LongestPalindrome/README.md +++ /dev/null @@ -1,23 +0,0 @@ -**409. 最长回文串** ---- -[https://leetcode-cn.com/problems/longest-palindrome/](https://leetcode-cn.com/problems/longest-palindrome/) - -给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 - -在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。 - -注意: -假设字符串的长度不会超过 1010。 - -示例 1: - -``` -输入: -"abccccdd" - -输出: -7 - -解释: -我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。 -``` diff --git a/_site/leetcode/410-SplitArrayLargestSum/hatrick.md b/_site/leetcode/410-SplitArrayLargestSum/hatrick.md deleted file mode 100644 index 8b449ac..0000000 --- a/_site/leetcode/410-SplitArrayLargestSum/hatrick.md +++ /dev/null @@ -1,55 +0,0 @@ -**410. 分割数组的最大值** ---- -[https://leetcode-cn.com/problems/split-array-largest-sum/](https://leetcode-cn.com/problems/split-array-largest-sum/) - -解决方案 -**思路** -使用二分法,首先可以发现,难点在于怎么判断分割是否可行,可以发现,当m=1的时候肯定可行(和最大,全部元素在一块), -当m=nums.length的时候也可行(和最小,为全部元素中的最大值),那么就二分这个最大和最小值就可以了,判断是否可分, -可分就将和缩小,使得需要的m值变小;反之则扩大 -``` -//使用二分法进行动态查找 -public int splitArray(int[] nums, int m) { - long left = 0, right = 0; - for (int n: nums) { - right += n; - } - if (m == 1) { - return (int)right; - } - long result = 0; - long mid; - while (left <= right) { - mid = left+right >> 1; - if (judge(mid, nums, m)) { - result = mid; - right = mid-1; - } else { - left = mid+1; - } - } - return (int)result; - } - - private boolean judge(long mid, int[] nums, int m) { - int sum = 0; - for (int i = 0; i < nums.length; i++) { - if (nums[i] > mid) { - return false; - } - if (sum + nums[i] > mid) { - sum = nums[i]; - m--; - } else { - sum += nums[i]; - } - } - return m >= 1; - } -``` -**复杂度分析** -平均时间复杂度:O(nlogn) -空间复杂度:O(1) - -**参考资料** -[https://blog.csdn.net/zhangjingao/article/details/86607677](https://blog.csdn.net/zhangjingao/article/details/86607677) \ No newline at end of file diff --git a/_site/leetcode/410-SplitArrayLargestSum/official.md b/_site/leetcode/410-SplitArrayLargestSum/official.md deleted file mode 100644 index 6b0e45b..0000000 --- a/_site/leetcode/410-SplitArrayLargestSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**410. 分割数组的最大值** ---- -[https://leetcode-cn.com/problems/split-array-largest-sum/](https://leetcode-cn.com/problems/split-array-largest-sum/) diff --git a/_site/leetcode/413-arithmeticSlices/official.md b/_site/leetcode/413-arithmeticSlices/official.md deleted file mode 100644 index d925d9a..0000000 --- a/_site/leetcode/413-arithmeticSlices/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**413. 等差数列划分** ---- -[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) diff --git a/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md b/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md deleted file mode 100644 index 85ae787..0000000 --- a/_site/leetcode/416-PartitionEqualSubsetSum/bigablecat.md +++ /dev/null @@ -1,104 +0,0 @@ -**416. 分割等和子集** ---- -[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) - -* 网友高票Java解法 - -```java - - /** - * https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation - * 网友高票Java解法 - * - * @param nums - * @return - */ - public static boolean canPartition(int[] nums) { - int sum = 0; - - //遍历数组,求得所有数字之和 - for (int num : nums) { - sum += num; - } - - //sum & 1位运算用于判断数字的奇偶 - //1的二进制是0000...0001 即前面31位都是0,第32位是1 - //偶数的二进制末尾是0,奇数的二进制末尾是1 - //其他任何二进制数与1进行位与运算,结果只有0和1两种 - //如果sum是奇数,不能再分为相等的两个整数,不符合题意 - if ((sum & 1) == 1) { - return false; - } - //假设当前数组符合题意,即有两个子集的元素之和相等 - //sum /= 2得到其中一个子集的所有元素之和 - sum /= 2; - - //定义一个boolean数组dp - //数组的长度是sum+1 - //数组中的每一个元素dp[i]表示数字i能否由数组nums中的元素求和得到 - boolean[] dp = new boolean[sum + 1]; - //当和等于0时,必定有0相加得0,所以dp[0]为true - //dp[0]是整个dp数组的基数,其他元素的真值由dp[0]得到 - dp[0] = true; - - //再次遍历数组nums - for (int num : nums) { - //根据sum的大小进行sum次迭代 - for (int i = sum; i > 0; i--) { - //i的值由nums中的元素相加得到 - //下面的语句判断i是否包含了num - //当 i >= num 时,i可能包含了num - if (i >= num) { - //如果 i 包含num - //那么 i-num 是由num之外的另外若干元素相加得到 - //dp[i]表示i是否由数组中的元素相加得到 - //dp[i]的真值应该和dp[i - num]保持一致 - //只要dp[i]和dp[i - num]中有一个为真,说明dp[i]为真 - dp[i] = dp[i] || dp[i - num]; - //实际上所有真值都是通过基础值dp[0]推算而来 - //例如,当i=num时,必定有i-num = 0 - //那么dp[i] = dp[i] || dp[i-num] = dp[i] || dp[0] = dp[i] || true = true - //nums中的元素num必定可以通过自身的值求和得到,所以dp[i]为真是正确的 - } - } - } - //dp[sum]即表示sum是否可以通过数组nums的值相加而来 - return dp[sum]; - } - -``` - -**复杂度分析** - -时间复杂度:O(n^2), -根据题设,nums是正整数非空数组, -那么nums的任意一个元素nums[i]>=1, -sum是所有nums元素的和, -在进入循环前经过了折半处理, -所以sum >= nums.length()/2, -将sum看做n,那么nums.length()<=n*2, -本解法中有1个独立的for循环, -遍历nums数组1次, -时间复杂度<=O(n*2), -另有一对嵌套for循环, -嵌套for循环的外循环遍历数组nums一次, -时间复杂度<=O(n*2), -嵌套for循环的内循环与sum的大小一致, -内循环的复杂度为O(n), -嵌套循环的时间复杂<=O(n*2*n)=O(2n^2), -再加上独立的for循环, -总的时间复杂度<=O(n*2 + 2n^2), -消去低阶项n*2和常数系数2, -最终的时间复杂度<=O(n^2) - -空间复杂度:O(n), -创建了一个sum+1大小的boolean数组, -占用了n+1的空间, -空间复杂度为O(n) - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) diff --git a/_site/leetcode/416-PartitionEqualSubsetSum/official.md b/_site/leetcode/416-PartitionEqualSubsetSum/official.md deleted file mode 100644 index 2f25f64..0000000 --- a/_site/leetcode/416-PartitionEqualSubsetSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**416. 分割等和子集** ---- -[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) diff --git a/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md b/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md deleted file mode 100644 index 76e8b99..0000000 --- a/_site/leetcode/446-ArithmeticSlicesIISubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**446. 等差数列划分 II - 子序列** ---- -[https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/](https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/) diff --git a/_site/leetcode/455-AssignCookies/SpecialYang.md b/_site/leetcode/455-AssignCookies/SpecialYang.md deleted file mode 100644 index 94ec505..0000000 --- a/_site/leetcode/455-AssignCookies/SpecialYang.md +++ /dev/null @@ -1,34 +0,0 @@ -**分发饼干** -https://leetcode.com/problems/assign-cookies/ ---- -### 思路一 -说实话,我看的是英文版,第一次竟然没读懂题意了,打扰了! -后来看了翻译,才明白题意:现在有一堆孩子,每个孩子的胃口不一样,有一堆饼干,饼干的大小也不一。我们的目标是把这些饼干尽可能多的分配给这些小朋友,求出最多满足多少个小朋友。 -1. 只要饼干的尺寸大于等于孩子胃口,才可以满足 -2. 一个饼干只能分给一个小朋友,一个小朋友只能吃一个饼干 - - -典型的**贪心**做法,我们只需把最接近孩子胃口的饼干分配给对应的孩子即可,这样我们就可以把更大的饼干分给胃口更大的孩子。即优先使用最满足孩子胃口的饼干分配。 - -我们可以对孩子和饼干分配从小到大排序,然后遍历饼干,判断饼干与当前孩子大小关系,若满足,则分配给孩子,换下一个孩子和下一个饼干;若不满足,换下一个饼干与当前的孩子比较。 -```java - /** - * 优先把尺寸接近孩子胃口的饼干分发 - * - * 局部最优 - * @param g - * @param s - * @return - */ - public int findContentChildren(int[] g, int[] s) { - Arrays.sort(g); - Arrays.sort(s); - int child = 0, size = 0; - while (child < g.length && size < s.length) { - if (g[child] <= s[size++]) { - child++; - } - } - return child; - } -``` \ No newline at end of file diff --git a/_site/leetcode/455-AssignCookies/bigablecat.md b/_site/leetcode/455-AssignCookies/bigablecat.md deleted file mode 100644 index 65122e3..0000000 --- a/_site/leetcode/455-AssignCookies/bigablecat.md +++ /dev/null @@ -1,56 +0,0 @@ -**455. 分发饼干** ---- - -[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) - -* 网友高票Java解法 - -```java - - public int findContentChildren(int[] g, int[] s) { - //调用java.util.Arrays.sort排序方法 - //分别给孩子期望和饼干大小排序 - Arrays.sort(g); - Arrays.sort(s); - int i = 0; //定义数组g的下标初始值i - //遍历数组s - for (int j = 0; i < g.length && j < s.length; j++) { - //g[i]是数组g在i位置的元素,表示第i个孩子的胃口 - //s[j]是数组s在j位置的元素,表示第j个饼干的尺寸 - //经过排序,g[i]从孩子最小的胃口开始 - //g[i]<=s[j]说明j位置的饼干可以满足第i个孩子 - //此时让i++,看s[j]是否能满足更大胃口的孩子 - if (g[i] <= s[j]) i++; - } - //最后返回的i就是最多能满足多少个孩子 - return i; - } - -``` - -**复杂度分析** - -时间复杂度:O(nlogn), -设两个数组的长度分别是 m 和 n -Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进, -时间复杂度稳定为O(nlogn), -Arrays.sort使用了两次,所以排序的时间复杂度是 -mlogm + nlogn, -for循环内虽然对两个数组进行操作, -但是两个数组都没有被重复从头遍历, -所以最坏情况的遍历次数是两个数组的长度之和 -m+n, -最终的时间复杂度是 -O(mlogm + nlogn + m + n) = O(nlogn) - -空间复杂度:O(n), -Arrays.sort排序方法的空间复杂度是O(n), -使用了两次,所以空间复杂度是O(2n), -最终的空间复杂度是O(n) - ---- - -**参考资料** - -* 网友高票Java解法: -[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) diff --git a/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md b/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md deleted file mode 100644 index e172f8f..0000000 --- a/_site/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md +++ /dev/null @@ -1,20 +0,0 @@ -**462. 最少移动次数使数组元素相等 II** ---- -[https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/](https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii/) - -给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。 - -``` -例如: - -输入: -[1,2,3] - -输出: -2 - -说明: -只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1): - -[1,2,3] => [2,2,3] => [2,2,2] -``` diff --git a/_site/leetcode/464-CanIWin/official.md b/_site/leetcode/464-CanIWin/official.md deleted file mode 100644 index b49b347..0000000 --- a/_site/leetcode/464-CanIWin/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**464. 我能赢吗** ---- -[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) diff --git a/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md b/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md deleted file mode 100644 index e046179..0000000 --- a/_site/leetcode/467-UniqueSubstringsInWraparoundString/passself.md +++ /dev/null @@ -1,85 +0,0 @@ -#467. 环绕字符串中唯一的子字符串 - -Leetcode 地址 [https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) - -**题目分析** - -该题的一个非常重要的隐藏条件是,改字符串里面所有的字母都是由26个字母的顺序前后相连的。比如xyzabc,子字符串就是xyz,或者abc 这里只是穷举部分。所以题目的意思是,找出字符串p所有子串中,每个字母按照字母表顺序相连的子串。按照字母表顺序相连,即意味着前字符的ascii码比后字符小1,或者后字符比前字符小25(字符z与字符a的情况)。 - -**思路:** - -1.符合条件的子串中字符是顺序相连的,所以如果子串的前n个字符符合条件,那么第n+1个字符和第n个字符也是相连的,那么这n+1个字符肯定也是符合条件的 - -2.由于符合条件的子串中字符是顺序相连的,那么这个子串的长度有多长,就有多少种以该子串最后一个字符为结尾的小子串 - -3.题目只是找出唯一的子串数量,那么以某个字符为结尾的子串,无论该字符出现在哪,它所可能组成的子串都是一样的,所以我们只需要找到能组成最长子串的那个位置就行了。 - -4.找出每个字符所能组成的唯一子串数量,然后求和 - -**具体代码** - -``` -public int findSubstringInWraproundString(String p) { - int[] count = new int[26]; - int maxLength = 0; - - for (int i = 0; i < p.length(); i++) { - if (i > 0 && (p.charAt(i) - p.charAt(i - 1) == 1 || (p.charAt(i - 1) - p.charAt(i) == 25))) {// - maxLength++; - } - else { - maxLength = 1; - } - - int index = p.charAt(i) - 'a'; - count[index] = Math.max(count[index], maxLength); - } - - // Sum to get result - int sum = 0; - for (int i = 0; i < 26; i++) { - sum += count[i]; - } - return sum; -} - -``` -**时间复杂度** O(N) - -**空间复杂度** O(1) - -leetcode 代码提交后发现只击败了38%的用户有待优化 - -后来发现双指针解法,感叹大牛的解法代码如下 - -``` -public int findSubstringInWraproundStringPoint(String p) { - if (p == null || p.length() == 0) { - return 0; - } - int[] ways = new int[125]; - char[] cs = p.toCharArray(); - int left = 0; - int right = 1; - // NOTE: even if right == cs.length, can still go into the loop, to handle the "a" case (single char) - while (right <= cs.length) { - while (right < cs.length && ((cs[right] - cs[right-1] == 1) || (cs[right] == 'a' && cs[right-1] == 'z'))) { - right++; - } - while (left < right) { - ways[cs[left]] = Math.max(ways[cs[left]], right - left); - left++; - } - right++; - } - int sum = 0; - for (int way : ways) { - sum += way; - } - return sum; -} - -``` -[具体地址](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95440/Two-pointers-Java-solution-beats-100) - - diff --git a/_site/leetcode/472-ConcatenatedWords/official.md b/_site/leetcode/472-ConcatenatedWords/official.md deleted file mode 100644 index fc433c5..0000000 --- a/_site/leetcode/472-ConcatenatedWords/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**472. 连接词** ---- -[https://leetcode-cn.com/problems/concatenated-words/](https://leetcode-cn.com/problems/concatenated-words/) diff --git a/_site/leetcode/474-OnesAndZeroes/hatrick.md b/_site/leetcode/474-OnesAndZeroes/hatrick.md deleted file mode 100644 index b8781a6..0000000 --- a/_site/leetcode/474-OnesAndZeroes/hatrick.md +++ /dev/null @@ -1,47 +0,0 @@ -**474. 一和零** ---- -[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) - -解决方案 -**思路** -和01背包是很相似的题目,只不过背包问题是装一种东西,而我们这道题要求的是装上两种东西,也就是1和0。 -我们的1和0相当于两类物品,n和m就是它们所对应的容量。 -我们的到第i个字符串时, 它所对应的可以组成最多的字符串个数则就对应为: -dp[m][n]=MAX(dp[m][n],dp[m-count0][n-count1]+1) -所以我们要做的就是在迭代字符串的时候,即时更新dp[m][n];也就是说每多一个字符串,我就计算一下加进来这个字符串之后,我所能拼接成的最大字符串数量。 -也就是说 当我只有一个字符串的时候,我求出我的dp[m][n],当我有两个字符串的时候,我根据上面的情况,在继续求出我现在的dp[m][n], 每多一个,就更新一下。 -注意dp[m][n]是随着迭代而更新的 -``` -class Solution { - //0-1背包问题,优化存储空间 - public int findMaxForm(String[] strs, int m, int n) { - int l = strs.length; - int zeros, ones; - // dp[i][j]代表遍历到当前字符串时使用i个0和j个1所能组成的最大字符串数量 - int[][] dp = new int[m+1][n+1]; - for(int i = 0; i < l ; i++){ - zeros = 0; - ones = 0; - for(int j = 0; j < strs[i].length(); j++){ - if(strs[i].charAt(j) == '0'){ - zeros++; - }else{ - ones++; - } - } - for(int j = m; j >= zeros; j--){ - for(int k = n; k >= ones; k--){ - dp[j][k] = Math.max(dp[j][k], dp[j-zeros][k-ones] + 1); - } - } - } - return dp[m][n]; - } -} -``` -**复杂度分析** -时间复杂度:O(n) -空间复杂度:O(n) - -**参考资料** -[https://blog.csdn.net/qq_38595487/article/details/84235304](https://blog.csdn.net/qq_38595487/article/details/84235304) \ No newline at end of file diff --git a/_site/leetcode/474-OnesAndZeroes/official.md b/_site/leetcode/474-OnesAndZeroes/official.md deleted file mode 100644 index 3a329af..0000000 --- a/_site/leetcode/474-OnesAndZeroes/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**474. 一和零** ---- -[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) diff --git a/_site/leetcode/486-PredictTheWinner/official.md b/_site/leetcode/486-PredictTheWinner/official.md deleted file mode 100644 index c74a6b6..0000000 --- a/_site/leetcode/486-PredictTheWinner/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**486. 预测赢家** ---- -[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) diff --git a/_site/leetcode/494-TargetSum/official.md b/_site/leetcode/494-TargetSum/official.md deleted file mode 100644 index be7767e..0000000 --- a/_site/leetcode/494-TargetSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**494. 目标和** ---- -[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) diff --git a/_site/leetcode/504-Base7/README.md b/_site/leetcode/504-Base7/README.md deleted file mode 100644 index 9f127ba..0000000 --- a/_site/leetcode/504-Base7/README.md +++ /dev/null @@ -1,21 +0,0 @@ -**504. 七进制数** ---- -[https://leetcode-cn.com/problems/base-7/](https://leetcode-cn.com/problems/base-7/) - -给定一个整数,将其转化为7进制,并以字符串形式输出。 - -示例 1: - -``` -输入: 100 -输出: "202" -``` - -示例 2: - -``` -输入: -7 -输出: "-10" -``` - -注意: 输入范围是 [-1e7, 1e7] 。 diff --git a/_site/leetcode/514-FreedomTrail/hatrick.md b/_site/leetcode/514-FreedomTrail/hatrick.md deleted file mode 100644 index 68cb7ca..0000000 --- a/_site/leetcode/514-FreedomTrail/hatrick.md +++ /dev/null @@ -1,49 +0,0 @@ -**514. 自由之路** ---- -[https://leetcode-cn.com/problems/freedom-trail/](https://leetcode-cn.com/problems/freedom-trail/) -解决方案 -**思路** -路径搜索问题,或者字符串匹配问题,可以正向或者逆向匹配. -动态规划记录当前的状态result[i][j],即当前匹配到key的第i个字母,ring的第j个字母在12点方向, -要匹配key的下一个字母时,可以从上一个状态顺时针或者逆时针转移到现在的状态. -``` -class Solution { - public int findRotateSteps(String ring, String key) { - if (ring == null || key == null) return 0; - int m = ring.length(); - int n = key.length(); - int[][] result = new int[n][m]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - result[i][j] = Integer.MAX_VALUE; - } - } - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - if (key.charAt(i) == ring.charAt(j)) { - if (i == 0) { - result[i][j] = Math.min(j, m - j); - } else { - for (int k = 0; k < m; k++) { - if (result[i - 1][k] != Integer.MAX_VALUE) - result[i][j] = Math.min(result[i][j], result[i - 1][k] + Math.min(Math.abs(j - k), m - Math.abs(j - k))); - } - } - } - } - } - int ans = result[n - 1][0]; - for (int j = 1; j < m; j++) { - if (ans > result[n - 1][j]) - ans = result[n - 1][j]; - } - return ans + n; - } -} -``` -**复杂度分析** -平均时间复杂度:O(n*n*n) -空间复杂度:O(n) - -**参考资料** -[https://www.cnblogs.com/kexinxin/p/10372522.html](https://www.cnblogs.com/kexinxin/p/10372522.html) \ No newline at end of file diff --git a/_site/leetcode/514-FreedomTrail/official.md b/_site/leetcode/514-FreedomTrail/official.md deleted file mode 100644 index 53a53d6..0000000 --- a/_site/leetcode/514-FreedomTrail/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**514. 自由之路** ---- -[https://leetcode-cn.com/problems/freedom-trail/](https://leetcode-cn.com/problems/freedom-trail/) diff --git a/_site/leetcode/516-LongestPalindromicSubsequence/passself.md b/_site/leetcode/516-LongestPalindromicSubsequence/passself.md deleted file mode 100644 index 856e1c2..0000000 --- a/_site/leetcode/516-LongestPalindromicSubsequence/passself.md +++ /dev/null @@ -1,42 +0,0 @@ -##516. 最长回文子序列 - -LeetCode 地址 [https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) - -**解法一 暴力求解:** - -找到字符串的所有子串,遍历每一个子串以验证它们是否为回文串。一个子串由子串的起点和终点确定,因此对于一个长度为n的字符串,共有n^2个子串。这些子串的平均长度大约是n/2,因此这个解法的时间复杂度是O(n^3)。 - -这样的方式很容易造成超时,比较不可取。 - - -**解法二 动态规划** - -回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,那么dp[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。 - -核心思路就是从左开始遍历,然后不断的从原字符串中拿出1到length-1长度的字串,进行判断 -这里用一个二维数组来表示回文字符串的起始位置和结束位置 - -时间复杂度 O(n^2) - -``` -public static int longestPalindromeSubseq(String s) { - if (s == null || s.length() == 0) { - return 0; - } - int[][] dp = new int[s.length()][s.length()]; - - for (int i = s.length() - 1; i >= 0; --i) { - dp[i][i] = 1; - for (int j = i + 1; j < s.length(); ++j) { - if (s.charAt(j) == s.charAt(i)) { - dp[i][j] = dp[i + 1][j - 1] + 2; - } else { - dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); - } - } - } - - return dp[0][s.length() - 1]; - } -``` - diff --git a/_site/leetcode/517-SuperWashingMachines/official.md b/_site/leetcode/517-SuperWashingMachines/official.md deleted file mode 100644 index d4b3317..0000000 --- a/_site/leetcode/517-SuperWashingMachines/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**517. 超级洗衣机** ---- -[https://leetcode-cn.com/problems/super-washing-machines/](https://leetcode-cn.com/problems/super-washing-machines/) diff --git a/_site/leetcode/523-ContinuousSubarraySum/hatrick.md b/_site/leetcode/523-ContinuousSubarraySum/hatrick.md deleted file mode 100644 index 921ba1f..0000000 --- a/_site/leetcode/523-ContinuousSubarraySum/hatrick.md +++ /dev/null @@ -1,90 +0,0 @@ -**523. 连续的子数组和** ---- -[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) - -解决方案 -**思路** -1.遍历不同长度的子数组,判断是不是能被整除即可.有一个优化点在于可以用动态规划的思路.在len+1长度的子数组遍历时,可以用到len长度的子数组已经计算好的值,不需要再次计算了. -``` - public boolean checkSubarraySum(int[] nums, int k) { - //新增一个数组保存上一轮的全部sum数据 - //这里容易出错的地方在于将sums的数据初始化为0.会造成基础数据就不对. - int[] sums = nums.clone(); - //从len=2开始,进行长度不同的遍历 - for(int len=2;len<=nums.length;len++) { - for(int i = 0; i<=nums.length-len; i++) { - //此时将sums[i]的数据与nums[i+len-1]的数据相加获得新值 - sums[i] += nums[i+len-1]; - //排除掉[0,0],0 的特殊情况 - if(sums[i] ==0) { - return true; - } - //判断当前值是不是可以整除,可以直接返回true - if (k!=0&& sums[i]%k==0) { - return true; - } - } - } - //默认情况 - return false; - } -``` -**复杂度分析** - 时间复杂度:O(N2) - 空间复杂度:O(N) - ---- -2.引入一个概念,前缀和(prefix sum). -给定一个数组x,数组元素为x_0,x_1,x_2,...x_{n-1},x_n -如果有数组y,满足如下条件 -y_0=x_0 -y_1=x_0+x_1 -y_2=x_0+x_1+x_2 -... -y_{n-1}=x_0+x_1+x_2+...+x_{n-1} -y_n=x_0+x_1+x_2+...+x_{n-1}+x_{n} -那么称y为x的前缀和数组 -此时可以发现,数组x的子序列和均可由前缀和数组y获得,如{x_a}至{x_b}子序列的和,可以由y_b-y_{a-1}得到. -而且也可以用到动态规划的思路,一次遍历生成y数组,然后接下来的遍历就可以复用y数组了. -可以直接看文后链接,才疏学浅,大家可以深入理解一下 -``` - public boolean checkSubarraySum(int[] nums, int k) { - //生成前缀和数组,此时已经可以判断一次了 - int[] presums = new int[nums.length]; - for(int i=0;i end) return 0; - if (res[start][end][k] > 0) return res[start][end][k]; - int ans = removeStub(start, end - 1, 0) + (k + 1) * (k + 1); - for (int i = start; i < end; i++) - if (boxes[i] == boxes[end]) { - ans = Math.max(ans, removeStub(start, i, k + 1) + removeStub(i + 1, end - 1, 0)); - } - res[start][end][k] = ans; - return ans; - } - - public int removeBoxes(int[] boxes) { - if (boxes == null || boxes.length == 0) return 0; - int n = boxes.length; - this.res = new int[n][n][n + 1]; - this.boxes = boxes; - return removeStub(0, boxes.length - 1, 0); - } - - public static void main(String[] args) { - int[] array = new int[]{1, 3, 2, 2, 2, 3, 4, 3, 1}; - Leet546 leet546 = new Leet546(); - System.out.println(leet546.removeBoxes(array)); - } -} -``` -**时间复杂度** O(N^4) - -leetcode 代码提交后发现击败了28%的commit - -思路类似,后来优化后 - -``` -class Solution { - public int removeBoxes(int[] boxes) { - if(boxes == null || boxes.length == 0) return 0; - int length = boxes.length; - int[][][] dp = new int[100][100][100]; - return calculatePoints(boxes, dp, 0, boxes.length - 1, 0); - } - - public int calculatePoints(int[] boxes, int[][][] dp, int l, int r, int k) { - if (l > r) { - return 0; - } - if (dp[l][r][k] != 0) { - return dp[l][r][k]; - } - while (r > l && boxes[r] == boxes[r - 1]) { - r--; - k++; - } - dp[l][r][k] = calculatePoints(boxes, dp, l, r - 1, 0) + (k + 1) * (k + 1); - for (int i = l; i < r; i++) { - if (boxes[i] == boxes[r]) { - dp[l][r][k] = Math.max(dp[l][r][k], - calculatePoints(boxes, dp, l, i, k + 1) + calculatePoints(boxes, dp, i + 1, r - 1, 0)); - } - } - return dp[l][r][k]; - } -} - -``` -[参考资料1](https://blog.csdn.net/Wuzihui___/article/details/78714313) - -[参考资料2](https://github.com/lydxlx1/LeetCode/blob/master/src/_546.java) - diff --git a/_site/leetcode/547-friendCircles/bigablecat.md b/_site/leetcode/547-friendCircles/bigablecat.md deleted file mode 100644 index cd25033..0000000 --- a/_site/leetcode/547-friendCircles/bigablecat.md +++ /dev/null @@ -1,126 +0,0 @@ -**547. 朋友圈** ---- -[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) - -```java - - /** - * 定义一个并查集的内部类 - */ - class UnionFind { - //计数器 - private int count = 0; - //parent结点集合 - //rank深度 - private int[] parent, rank; - - //定义一个并查集构造器 - public UnionFind(int n) { - //计数器,记录集合中的分组数 - count = n; - //父结点数组 - parent = new int[n]; - //结点高度,或者说结点的辈分 - //rank值越高,结点越靠近根结点 - rank = new int[n]; - //创建时,让每个结点的父结点都指向自身 - for (int i = 0; i < n; i++) { - parent[i] = i; - } - //初始化完成后,得到这样一个并查集 - //所有结点的高度一致 - //所有结点的父结点等于自身,即每个结点自成一组 - //初始化分组数量为n - } - - - /** - * 查找指定结点p的根结点 - * @param p - * @return - */ - public int find(int p) { - //如果当前结点的父结点不等于自身 - while (p != parent[p]) { - //路径压缩,让结点p的父结点指向祖父结点 - parent[p] = parent[parent[p]]; - //让当前结点指向自身的父结点 - p = parent[p]; - } - return p; - } - - /** - * 合并方法 - * - * @param p - * @param q - */ - public void union(int p, int q) { - //查找结点p的根结点 - int rootP = find(p); - //查找结点Q的根结点 - int rootQ = find(q); - //如果两个根节点相等,说明两个结点已经在同一组 - if (rootP == rootQ) return; - //比较两个根结点的rank - if (rank[rootQ] > rank[rootP]) { - //rootQ的rank值高,说明rootQ离根结点更近 - //让rootP的父结点指向rooQ - //即rootP加入rootQ的同组 - parent[rootP] = rootQ; - } else { - //否则,让rootQ加入rootP同组 - parent[rootQ] = rootP; - //如果两个结点的rank值相等 - if (rank[rootP] == rank[rootQ]) { - // rankP已经成为父结点 - // 所以让rootP的高度递增 - rank[rootP]++; - } - } - //实现p和q的分组,计数器递减 - count--; - } - - //获取count值的方法 - public int count() { - return count; - } - } - - public int findCircleNum(int[][] M) { - int n = M.length; - //创建一个矩阵同等长度的并查集uf - UnionFind uf = new UnionFind(n); - //双重嵌套循环,遍历矩阵的每一个结点 - for (int i = 0; i < n - 1; i++) { - for (int j = i + 1; j < n; j++) { - //如果第i个同学和第j个同学互为好友 - //调用uf.union方法将两个同学分到同一个朋友圈 - if (M[i][j] == 1) uf.union(i, j); - } - } - //返回朋友圈的总个数 - return uf.count(); - } - -``` - -**复杂度分析** - -时间复杂度:O(n^n), -嵌套循环进行了n*n次循环, -时间复杂度为O(n^n) - -空间复杂度:O(n), -分别定义了大小为n的int数组parent和rank, -空间复杂度为O(2n), -消去常数项得到O(n) - ---- - -**参考资料** - -* 网友高票Java解法(unionfind): -[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) diff --git a/_site/leetcode/551-StudentAttendanceRecordI/official.md b/_site/leetcode/551-StudentAttendanceRecordI/official.md deleted file mode 100644 index 589b73d..0000000 --- a/_site/leetcode/551-StudentAttendanceRecordI/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**551. 学生出勤记录 I** ---- -[https://leetcode-cn.com/problems/student-attendance-record-i/](https://leetcode-cn.com/problems/student-attendance-record-i/) diff --git a/_site/leetcode/552-StudentAttendanceRecordII/official.md b/_site/leetcode/552-StudentAttendanceRecordII/official.md deleted file mode 100644 index ac3dba7..0000000 --- a/_site/leetcode/552-StudentAttendanceRecordII/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**552. 学生出勤记录 II** ---- -[https://leetcode-cn.com/problems/student-attendance-record-ii/](https://leetcode-cn.com/problems/student-attendance-record-ii/) diff --git a/_site/leetcode/576-OutOfBoundaryPaths/official.md b/_site/leetcode/576-OutOfBoundaryPaths/official.md deleted file mode 100644 index dfd9e93..0000000 --- a/_site/leetcode/576-OutOfBoundaryPaths/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**576. 出界的路径数** ---- -[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) diff --git a/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md b/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md deleted file mode 100644 index f17f136..0000000 --- a/_site/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md +++ /dev/null @@ -1,66 +0,0 @@ -https://leetcode-cn.com/problems/out-of-boundary-paths/ - -576. 出界的路径数 - -思路: 依然是DP动态规划 - -1.这里答案不想要的坐标不是被弃之不理,而是把上一步当前位置的元素代表的可能数加到结果的总个数中,并且此题dp数组每个元素存的不是走到这里的概率,而是 -走到这里的可能总路径数。注意在运算过程要取模。 - -``` -def findPaths(self, m, n, N, i, j): - if N == 0: - return 0 - lastStepCount = [[0 for i in range(n)] for j in range(m)] #对之前坐标进行遍历 - move = [[0, 1], [1, 0], [0, -1], [-1, 0]] #一次只能移动一个上下左右 - lastStepCount[i][j] = 1 #初始化定义 - res, mod = 0, 1000000007 - for step in range(1, N + 1): - currCount = [[0 for i in range(n)] for j in range(m)] #正则表达式循环现在的坐标 - for x in range(m): - for y in range(n): - for direction in move: - lastX, lastY = x + direction[0], y + direction[1] #对坐标进行位置移动 - if any([lastX < 0, lastX >= m, lastY < 0, lastY >= n]): - res = (res + lastStepCount[x][y]) % mod #如果出界了,就直接求出结果 - else: #否则就继续迭移动 - currCount[x][y] = (currCount[x][y] + lastStepCount[lastX][lastY]) % mod - lastStepCount = currCount #重新赋值 - return res -``` -时间复杂度O(N * m * n) - -2.另一种DP思想,从坐标[i, j]到其上、下、左、右都需要移动1步,剩余N-1步,那么问题转化为从上、下、左、右移动N-1步,一共有多少种方法。 - -``` -class Solution: - def findPaths(self, m, n, N, i, j): - tmp=[[[0 for i in range(n)] for j in range(m)] for k in range(N+1)] #坐标和移动次数的三维数组 - for k in range(1,N+1): - for p in range(m): - for q in range(n): - if 0==p: #如果横坐标是0 - up=1 #就可以向上走 - else: - up=tmp[k-1][p-1][q] #否则非0就要走N-1步 - if m-1==p: #如果横坐标已经是左移动1了,那么我们向下移动1 - down=1 - else: - down=tmp[k-1][p+1][q] #否则就是横坐标+1的地方走N-1步 - if 0==q: - left=1 - else: - left=tmp[k-1][p][q-1] #同理左右也是一样 - if n-1==q: - right=1 - else: - right=tmp[k-1][p][q+1] - tmp[k][p][q]=(up+down+left+right)%1000000007 #注意最后的结果要mod那个数 - return tmp[N][i][j] -``` -时间复杂度是O(N * m * n) - -其实这两种方法大体上都是一样的,都是想要求到上一步的情况,那么就直接用DP状态转移来进行递归。 - -参考:https://unclegem.cn/2018/11/01/Leetcode%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-576-%E5%87%BA%E7%95%8C%E7%9A%84%E8%B7%AF%E5%BE%84%E6%95%B0/ -https://www.smwenku.com/a/5c220ee2bd9eee16b4a76a6d/zh-cn/ diff --git a/_site/leetcode/629-KInversePairsArray/official.md b/_site/leetcode/629-KInversePairsArray/official.md deleted file mode 100644 index 7ce258c..0000000 --- a/_site/leetcode/629-KInversePairsArray/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**629. K个逆序对数组** ---- -[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) diff --git a/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md b/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md deleted file mode 100644 index 9415842..0000000 --- a/_site/leetcode/629-KInversePairsArray/zengdiqing1994.md +++ /dev/null @@ -1,117 +0,0 @@ -![629. K个逆序对数组](https://leetcode-cn.com/problems/k-inverse-pairs-array/submissions/) - -给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。 - -逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > a[j],则其为一个逆序对;否则不是。 - -由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。 - -示例 1: - -输入: n = 3, k = 0 -输出: 1 -解释: -只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。 -示例 2: - -输入: n = 3, k = 1 -输出: 2 -解释: -数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。 - -思路: - -求递推式,时间复杂度O(n * k) - -观察下列推导过程: - -当n=1时,k的取值范围是[0, 0] - -k c - -0 1 1 - -当n=2时,k的取值范围是[0, 1] - -k c - -0 1 1 - -1 1 1 - -当n=3时,k的取值范围是[0, 3] - -k c - -0 1 1 - -1 1 1 2 - -2 1 1 2 - -3 1 1 - -当n=4时,k的取值范围是[0, 6] - -k c - -0 1 1 - -1 2 1 3 - -2 2 2 1 5 - -3 1 2 2 1 6 - -4 1 2 2 5 - -5 1 2 3 - -6 1 1 - -当n=5时,k的取值范围是[0, 10] - -k c - -0 1 1 - -1 3 1 4 - -2 5 3 1 9 - -3 6 5 3 1 15 - -4 5 6 5 3 1 20 - -5 3 5 6 5 3 22 - -6 1 3 5 6 5 20 - -7 1 3 5 6 15 - -8 1 3 5 9 - -9 1 3 4 - -10 1 1 - -这个递推的过程很难想到,就借鉴别人的 - -![思路代码](http://bookshadow.com/weblog/2017/06/25/leetcode-k-inverse-pairs-array/) - -```py -class Solution: - def kInversePairs(self, n: 'int', k: 'int') -> 'int': - MOD = 10**9 + 7 - dp = [1] - for x in range(2, n + 1): - ndp = [] - num = 0 - for y in range(min(1 + x * (x - 1) // 2, k + 1)): #分两种情况 - if y < len(dp): num = (num + dp[y]) % MOD - if y >= x: num = (MOD + num - dp[y - x]) % MOD - ndp.append(num) - dp = ndp - return k < len(dp) and dp[k] or 0 -``` - diff --git a/_site/leetcode/638-ShoppingOffers/bigablecat.md b/_site/leetcode/638-ShoppingOffers/bigablecat.md deleted file mode 100644 index 70f7cd4..0000000 --- a/_site/leetcode/638-ShoppingOffers/bigablecat.md +++ /dev/null @@ -1,134 +0,0 @@ -**638. 大礼包** ---- -[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) - -```java - - public int shoppingOffers(List price, List> special, List needs) { - //新建一个map用于记录每次的结果 - Map, Integer> map = new HashMap(); - return shopping(price, special, needs, map); - } - - /** - * https://leetcode.com/articles/shopping-offers/ - * 英文官方题解 - * - * - * @param price 商品价格列表 - * @param special 商品大礼包 - * @param needs 待购清单 - * @param map - * @return - */ - public int shopping(List price, List> special, List needs, Map, Integer> map) { - //如果map包含当前待购清单,不再重复计算,直接返回结果 - if (map.containsKey(needs)) - return map.get(needs); - //定义一个内循环控制变量j,用于列表needs - //调用dot方法获取不使用大礼包时,购买清单的总价格res - int j = 0, res = dot(needs, price); - //遍历大礼包,获得各种购买组合 - for (List s : special) { - //克隆待购清单clone,可以直接对该数组操作 - ArrayList clone = new ArrayList<>(needs); - //遍历待购清单 - for (j = 0; j < needs.size(); j++) { - //clone.get(j)表示待购清单中第j个商品的数量 - //s.get(j)表示礼包中当前商品的数量 - //diff是二者的差 - int diff = clone.get(j) - s.get(j); - //如果diff<0表示礼包中的商品数量大于待购清单,不合题意,排除 - if (diff < 0) - //跳出本次循环,继续下一次循环 - break; - //在克隆待购清单中当前商品对应位置存储差值 - //存储的差值表示余下还有多少量可以购买,用于传入下方的递归函数做参数 - clone.set(j, diff); - } - //j == needs.size()表示j是整数列表的长度,即needs中最后一个元素的下标 - if (j == needs.size()) - //s.get(j) 获取大礼包整数列表s第j个下标的元素,即当前大礼包的价格 - //shopping(price, special, clone, map) 递归调用shopping函数 - //第三个参数clone,记录了每种商品余下可购买的数量 - //递归调用的shopping返回余下可购买数量所能获得的最优总价 - //所以s.get(j) + shopping(price, special, clone, map) - //就是包含当前礼包所能得到的最优价格 - //Math.min比较已有结果和包含当前礼包的最优价格,取其中较小值 - res = Math.min(res, s.get(j) + shopping(price, special, clone, map)); - } - //将待购清单对应的结果存入map - map.put(needs, res); - return res; - //上述方法是如何计算礼包组合之外,单独购买的那部分总价? - //关键点有2个: - // 1) clone: - // 经过购买组合之后,待购清单的克隆数组clone里的商品数量会减少, - // 当所有可能的大礼包组合都用尽之后, - // clone里剩余的待购数量就是只能单独购买的那部分商品 - // 2) dot方法: - // dot方法获得不使用大礼包时待购清单的总价, - // 大礼包组合用尽之后的clone待购清单, - // 经过dot方法就能得到单独购买的那部分商品的总价 - } - - /** - * 两个整数列表对应下标的数值相乘,并将结果累加 - * - * @param a - * @param b - * @return - */ - public int dot(List a, List b) { - int sum = 0; - //遍历整数列表a - for (int i = 0; i < a.size(); i++) { - //将整数列表a和整数列表b对应位置的数值相乘并累加 - sum += a.get(i) * b.get(i); - } - //返回最终结果 - return sum; - } - - -``` - -**复杂度分析** - -时间复杂度:O(n^2), -设数组special的长度为m, -数组needs的长度为k, -外循环遍历special数组时间复杂度为 m, -内循环遍历needs时间复杂度为 k, -两个循环嵌套时间复杂度为 m*k, -外循环中有递归函数, -每次调用的时间复杂度也是 m*k,共调用m次, -总的时间复杂度是 m*k + m*(m*k) = m*k + m^2, -舍去低阶项 m*k,得到时间复杂度m^2*k -根据题意,商品的种类比起礼包的数量相当于一个常数, -即k的值非常小,可以看做常数, -所以最终的时间复杂度大致为O(n^2) - -空间复杂度:O(n^2), -设数组special的长度为m, -数组needs的长度为k, -使用了map存储计算结果, -每存储一个键值对使用O(1)的空间复杂度 -最多有m次递归,每次递归可能会产生一个键值对, -所以map的空间复杂度为O(m); -另外在每次外循环都克隆了一个最大为needs长度k的数组, -外循环遍历special的循环次数是m, -每次都有递归函数再次使用了m次循环, -所以有m*m次克隆一个最大长度为k的数组, -空间复杂度为 m^2*k, -因为商品种类k的值相对较小,可以看做常数, -所以克隆数组占用的空间可以看做 m^2, -总的空间复杂度为map占用的O(m)+数组占用的O(m^2), -省去低阶项,最终的空间复杂度为O(n^2) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) diff --git a/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md b/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md deleted file mode 100644 index eca592c..0000000 --- a/_site/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md +++ /dev/null @@ -1,75 +0,0 @@ -**646.最长数对链** ---- -https://leetcode.com/problems/maximum-length-of-pair-chain/ -如果你把一对数捏成一个数,这不就是最长上升子序列问题吗? -### 思路一 -动态规划问题,我们首先按照第1个数的大小排序所有的数对,然后有如下状态转移方程: -```math -dp[i] = max(dp[i], dp[j] + 1) (j \in [0, i)) -``` -dp[i]表示以第i个数对结尾的最大数对链长度,那么dp[i]的值为dp[i]自身(初始为1)与 从第j个数对连接到i数对的最大值,可以联想最长上升子序列问题哈。 -```java - /** - * 最长递增子序列问题的变形 - * - * @param pairs - * @return - */ - public int findLongestChain1(int[][] pairs) { - Arrays.sort(pairs, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o1[0] - o2[0]; - } - }); - int[] dp = new int[pairs.length + 1]; - int max = 0; - for (int i = 0; i < pairs.length; i++) { - dp[i] = 1; - for (int j = 0; j < i; j++) { - if (pairs[j][1] < pairs[i][0]) { - dp[i] = Math.max(dp[i], dp[j] + 1); - } - } - max = Math.max(max, dp[i]); - } - return max; - } -``` -#### 复杂度 -- 时间复杂度:O(n^2) -- 空间复杂度:O(n) - -### 思路二 -按第二个数排序,这样我们优先安排第二个数最小的,因为安排当前第二个数最小比安排当前不是第二个数最小要好。 -假设全局最优的链中第i个的第二个数不是当时安排的最小,那么必然这里可以替换成最小,最终只会导致这个全局长度不变或者增大,所以最好的选择就是每次都安排最小的。 -```java - /** - * 贪心 - * 以第二数排序 - * 优先添加末尾数小的,这样可以给后面的pair更大的选择 - * @param pairs - * @return - */ - public int findLongestChain2(int[][] pairs) { - Arrays.sort(pairs, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o1[1] - o2[1]; - } - }); - int curEnd = Integer.MIN_VALUE; - int max = 0; - for (int[] pair : pairs) { - if (curEnd < pair[0]) { - curEnd = pair[1]; - max++; - } - } - return max; - } -``` -#### 复杂度 -- 时间复杂度:O(nlogn) -- 空间复杂度:O(1) -以上两者都依赖你所选的排序算法。 \ No newline at end of file diff --git a/_site/leetcode/646-MaximumLengthOfPairChain/official.md b/_site/leetcode/646-MaximumLengthOfPairChain/official.md deleted file mode 100644 index 356c896..0000000 --- a/_site/leetcode/646-MaximumLengthOfPairChain/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**646. 最长数对链** ---- -[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) diff --git a/_site/leetcode/647-PalindromicSubstrings/bigablecat.md b/_site/leetcode/647-PalindromicSubstrings/bigablecat.md deleted file mode 100644 index 9aab0a1..0000000 --- a/_site/leetcode/647-PalindromicSubstrings/bigablecat.md +++ /dev/null @@ -1,198 +0,0 @@ -**647. 回文子串** ---- -[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) - -* 英文官方题解1:Expand Around Center - -```java - /** - * https://leetcode.com/articles/palindromic-substrings/ - * 英文官方解法1:Expand Around Center - - * - * @param S - * @return - */ - public int countSubstrings(String S) { - //定义N为数组的长度,ans是回文子串的个数 - int N = S.length(), ans = 0; - // 回文子串是以某点为中心左右对称的 - // 比如aba的中心是字母b - // abba的中心在两个字母b的中间 - // 字符串的长度为N,最多有多少个这样的中心点? - // 如果以单个字符为中心, - // 即以S[i]为中心,0<=i= 0,因为left依次递减,所以left的下限是0 - //right < N,同理right依次递增,所以right的上限是数组S的长度N - //S.charAt(left) == S.charAt(right)中心点两边的字符相等 - //说明扩展到left和right当前所在位置时,符合回文的条件 - while (left >= 0 && right < N && S.charAt(left) == S.charAt(right)) { - //发现一个回文子串,ans递增1位 - ans++; - //从中心向外扩散 - //left递减,right递增 - left--; - right++; - } - } - //返回最终累加的回文子串数目 - return ans; - } - -``` - -**复杂度分析** - -时间复杂度:O(n^2), -外循环运行2*N-1次,时间复杂度为n, -每个内循环最多运行n次,时间复杂度为n, -嵌套循环的时间复杂度是O(n^2), - -空间复杂度:O(1), -没有使用额外的存储空间 - ---- - -* 英文官方题解2:Manacher - -```java - /** - * https://leetcode.com/articles/palindromic-substrings/ - * 英文官方解法2:Manacher - * - * @param S - * @return - */ - public int countSubstrings2(String S) { - //创建字符数组A,数组长度是S长度的2倍加3 - //为什么长度定义为2 * S.length() + 3会在下方代码中体现 - char[] A = new char[2 * S.length() + 3]; - //以'@'作为数组A的开头,防止越界 - A[0] = '@'; - //在字符之前加入'#' - A[1] = '#'; - //以'$'作为数组A的结尾,防止越界 - A[A.length - 1] = '$'; - //定义数组A的长度时+ 3,即加了上述3个字符 - //数组A的下标0和1都已定义,变量t从2开始记录下标 - int t = 2; - //S.toCharArray()将字符串S转为字符数组 - //遍历字符数组的每一个元素 - for (char c : S.toCharArray()) { - //将当前字符存入字符数组,同时下标t递增 - A[t++] = c; - //在每个字符后存入一个符号'#' - A[t++] = '#'; - //定义数组A的长度时,用2*S.length() - //因为每个字符后都有一个对应的'#',即S的长度扩充了2倍 - } - //经过上述处理后,字符串S中的每个字符,左右两侧都有'#' - //即'aba'变成了'#a#b#a#' - - //定义一个新数组Z,长度与数组A相等 - // Z中每个整数元素与A中的字符元素一一对应 - // 记录A在该位置上字符的回文半径 - int[] Z = new int[A.length]; - //定义整数变量center,记录字符串中最长回文子串的中心位置,初始值为0 - //定义整数变量right,记录最长回文子串的右侧边界,初始值为0 - int center = 0, right = 0; - //从下标1开始遍历数组Z,因为第一个字符'@'作为下界,不用考虑 - for (int i = 1; i < Z.length - 1; ++i) { - //当中心i小于最长回文子串的半径右边界right时 - //说明当前中心处于已经计算过的回文子串范围内 - //那么以i为中心的回文半径可以直接获取 - if (i < right) { - // 2 * center - i = center - ( i - center) - // 得到中心i相对于最长回文中心center,在数组Z上的对称位置 - // 即以i为中心,或者以 2 * center - i 为中心, - // 以 (right-i)为半径,两个对称中心点的回文子串数量是相同的 - // 而以i为中心,目前能获得的最长回文子串半径不能超出右边界right - // 所以需要从right - i和Z[2 * center - i]中取较小值 - Z[i] = Math.min(right - i, Z[2 * center - i]); - } - //A[i + Z[i] + 1] == A[i - Z[i] - 1] - //这行代码表示以i为中心,比较i两侧对称位置的字符是否相等 - //其中 i + Z[i] + 1 表示以i为中心,半径的右侧边界所在位置 - //因为Z[i]记录了i位置上已存在的回文半径,比如aba,其回文半径为1 - // i + 已有半径 + 1 表示在已知半径递增1位后,测试是否仍然是回文 - //同理 i - Z[i] - 1 表示以i为中心,半径的左边界所在位置 - while (A[i + Z[i] + 1] == A[i - Z[i] - 1]) { - //如果中心i向左右两侧各延伸1位后,所在位置字符仍然相等 - //则Z[i]++表示以i为中心的回文半径长度递增1位 - Z[i]++; - } - //经过上述处理,i + Z[i] 表示以i为中心,最新的半径右边界 - //如果更新后的半径右边界比已知的最长回文半径右边界right更大 - if (i + Z[i] > right) { - //更新最长回文子串中心center的值 - center = i; - //更新最长回文子串的右侧边界right的值 - right = i + Z[i]; - } - } - //定义整数变量ans记录最长回文的总数 - int ans = 0; - //遍历数组Z - for (int v : Z) { - //v记录了当前位置回文子串的半径 - //即当前位置回文子串的总数 - //因为原字符串被前后插入了'#' - //所以回文子串的半径长度是实际的2倍 - //所以需要 (v + 1) / 2 进行减半处理 - //ans需要累加所有中心点的回文子串数量 - ans += (v + 1) / 2; - } - //返回最终结果 - return ans; - } - - -``` - -**复杂度分析** - -时间复杂度:O(n), -代码中总共有2个独立的for循环, -和1个for循环嵌套while循环, -独立的for循环分别遍历了字符串S一次,数组Z一次, -两次遍历的时间复杂度都是2N, -嵌套循环中,外循环遍历数组Z, -而内循环while, -只有在中心两侧字符相等的情况下才会进入循环体, -即有多少个中心点,就有多少次进入循环体, -中心点的个数是2*N-1, -所以外循环结束时, -while循环的最坏时间复杂度是2*N-1, -外循环for的时间复杂度是2N, -再加上另外两个独立的for循环, -总的时间复杂度是6N-1, -约去常数系数6和常数项1, -最终时间复杂度是O(N) - -空间复杂度:O(n), -创建了数组A和数组Z, -A和Z的大小都是2n+3, -所以总的空间复杂度最终为4n+6, -去掉常数项6和n的常数项系数4, -最终的空间复杂度是O(n) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) diff --git a/_site/leetcode/647-PalindromicSubstrings/official.md b/_site/leetcode/647-PalindromicSubstrings/official.md deleted file mode 100644 index 0c0833a..0000000 --- a/_site/leetcode/647-PalindromicSubstrings/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**647. 回文子串** ---- -[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) diff --git a/_site/leetcode/650-2KeysKeyboard/mahone.md b/_site/leetcode/650-2KeysKeyboard/mahone.md deleted file mode 100644 index 0432822..0000000 --- a/_site/leetcode/650-2KeysKeyboard/mahone.md +++ /dev/null @@ -1,34 +0,0 @@ -**650. 只有两个键的键盘** ---- -[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) - - -解决方案 -**思路** -思路1: 将n分解为m个数字的乘积并且m个数字的和最小,即把一个数分解为n个质数的和 - -``` -public int minStep(int n){ - int result = 0; - int d = 2; - while (n >1){ - //继续将剩下的进行分解 - while (n % d == 0 ){ - //加上次数 - result += d; - //计算剩下的n - n =n / d; - } - d++; - } - return result; - } -``` - -**复杂度分析** -时间复杂度:O(√n),当n是素数平方时,我们的循环耗时O(√n) -空间复杂度:O(1),空间只使用了result和d - -**参考资料** -* 本题leetCode英文官方题解: -[https://leetcode.com/problems/2-keys-keyboard/solution/](https://leetcode.com/problems/2-keys-keyboard/solution/) \ No newline at end of file diff --git a/_site/leetcode/650-2KeysKeyboard/official.md b/_site/leetcode/650-2KeysKeyboard/official.md deleted file mode 100644 index 7b54765..0000000 --- a/_site/leetcode/650-2KeysKeyboard/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**650. 只有两个键的键盘** ---- -[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) diff --git a/_site/leetcode/664-StrangePrinter/official.md b/_site/leetcode/664-StrangePrinter/official.md deleted file mode 100644 index bb8c3dc..0000000 --- a/_site/leetcode/664-StrangePrinter/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**664. 奇怪的打印机** ---- -[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) diff --git a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md deleted file mode 100644 index 6cb4130..0000000 --- a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md +++ /dev/null @@ -1,95 +0,0 @@ -**673. 最长递增子序列的个数** ---- -[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) - -* 英文官方题解1:暴力法 - -```java - - /** - * https://leetcode.com/articles/number-of-longest-increasing-subsequence/ - * 英文官方题解1,暴力法 - * - * @param nums - * @return - */ - public int findNumberOfLIS(int[] nums) { - //获取nums的长度N - int N = nums.length; - //如果N不大于1,直接返回N - if (N <= 1) return N; - //lengths用于记录以数字nums[i]结尾的子序列长度 - int[] lengths = new int[N]; //lengths[i] = length of longest ending in nums[i] - //counts用于记录以数字nums[i]结尾的子序列总共有多少个 - int[] counts = new int[N]; //count[i] = number of longest ending in nums[i] - // 用数字1填充lengths和counts数组 - // 即默认情况下,数组nums中每个元素都可以组成一个子序列 - // 每个子序列只有一个元素,序列长度为1,序列的个数为1 - Arrays.fill(lengths, 1); - Arrays.fill(counts, 1); - - //外循环迭代次数是数组nums的长度N - for (int j = 0; j < N; ++j) { - //内循环迭代次数是外循环的控制变量j - for (int i = 0; i < j; ++i) { - //因为是递增子序列,只针对nums[i] < nums[j]的情况进行操作 - if (nums[i] < nums[j]) { - //lengths[i]和lengths[j]分别表示以nums[i]和nums[j]结尾的子序列的长度 - if (lengths[i] >= lengths[j]) { - //因为nums[i]比nums[j]小,所以lengths[i]应该小于lengths[j] - //lengths[i] >= lengths[j]需要对lengths[j]的值进行更新 - //以nums[j]结尾的递增子序列,包含了以nums[i]结尾的子序列的所有元素,并至少多出一个元素nums[j] - //所以lengths[i] + 1表示在nums[i]结尾的子序列后面添加一个元素nums[j] - lengths[j] = lengths[i] + 1; - //counts[i]和counts[j]分别代表以nums[i]和nums[j]结尾的子序列个数 - //在所有以nums[i]结尾的子序列后面都可以添加元素nums[j]组成新的递增子序列 - //将counts[i]赋值给counts[j],counts[j]表示在nums[i]基础上以nums[j]结尾的子序列的数目 - counts[j] = counts[i]; - } else if (lengths[i] + 1 == lengths[j]) { - //如果lengths[i] + 1 == lengths[j] - //则所有以nums[i]结尾的子序列再加上一个元素nums[j] - //可以组成一批新的子序列,这批子序列都以nums[j]结尾,个数为counts[i] - //当前以num[j]结尾,长度为lengths[j]的子序列的个数为counts[j] - //在counts[j]的基础上,加上counts[i] - //即counts[j] += counts[i]得到最新的以nums[j]结尾的子序列的个数 - counts[j] += counts[i]; - } - } - } - } - //定义一个整数longest用于存储最长子序列的个数 - //定义一个整数ans作为最终结果返回 - int longest = 0, ans = 0; - //遍历所有子序列长度值 - for (int length : lengths) { - //找出其中最大的子序列长度,赋值给longest - longest = Math.max(longest, length); - } - //迭代N次,N为数组nums长度 - for (int i = 0; i < N; ++i) { - //如果以nums[i]结尾的子序列长度与最长长度相等 - if (lengths[i] == longest) { - //将以nums[i]结尾的子序列的总数存入ans - ans += counts[i]; - } - } - //返回最终结果 - return ans; - } - -``` - -**复杂度分析** - -时间复杂度:O(N^2), -嵌套for循环,最差情况迭代 N^2次 - -空间复杂度:O(N), -新建数组lengths和counts,占用空间都是N - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md b/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md deleted file mode 100644 index f4ecc23..0000000 --- a/_site/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**673. 最长递增子序列的个数** ---- -[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/688-KnightProbabilityInChessboard/passself.md b/_site/leetcode/688-KnightProbabilityInChessboard/passself.md deleted file mode 100644 index 4faba33..0000000 --- a/_site/leetcode/688-KnightProbabilityInChessboard/passself.md +++ /dev/null @@ -1,70 +0,0 @@ -#688. “马”在棋盘上的概率 - -Leetcode 地址 [https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) - -**思路:** - -1.国际象棋“马”的走法类似中国象棋的**马走日字**走法,也就是说可以走八个方向,即可推出已知8个方向走法常量{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1} - -2.从K位置向后递推还在棋盘上的概率,那么根据动态规划的思维反过来考虑的话就是在board上所有位置走完K步后能到初始位置(r,c)的数目和 - -3.把棋盘上所有位置上经过K步还留在棋盘上的走法总和都算出来,然后计算 - -**具体代码** - -``` -public static double knightProbability(int N, int K, int r, int c) { - int [][] moves = {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}}; - double [][] tempDp = new double[N][N]; - for(double [] row : tempDp){ - Arrays.fill(row, 1); - } - - for(int step = 0; step=0 && row=0 && col= N || c < 0 || c >= N) return 0.0; - if (k == 0) return 1.0; - if (dp[k][r][c] != 0.0) return dp[k][r][c]; - for (int i = 0; i < 8; i++) - dp[k][r][c] += helper(dp, N, k-1, r+moves[i][0], c+moves[i][1]); - return dp[k][r][c]; - } -``` -参考了leet上star比较认可的解法 [具体地址](https://leetcode.com/problems/knight-probability-in-chessboard/discuss/108187/cjava-dp-concise-solution) - - diff --git a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md deleted file mode 100644 index f549bbe..0000000 --- a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md +++ /dev/null @@ -1,130 +0,0 @@ -**689. 三个无重叠子数组的最大和** ---- -[https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) - -```java - - public int[] maxSumOfThreeSubarrays(int[] nums, int K) { - // W是由数组nums中每K个元素的和组成的整数数组 - // 把间隔K看成滑动窗口的长度 - // 窗口在nums数组上从第1个元素开始滑动 - // 窗口每滑动一次,就计算一次窗口内所有元素的和,放入数组W - // 滑动窗口到nums的第nums.length - K个元素时,共计算了nums.length - K次 - // 此时nums数组中还剩K个元素,可以计算最后一次 - // 所以W的长度是nums.length - K + 1 - int[] W = new int[nums.length - K + 1]; - //定义一个整数sum用于存储每K个元素的和 - int sum = 0; - //遍历数组nums并求得W数组的所有值 - for (int i = 0; i < nums.length; i++) { - //用+=对nums中连续的元素累加求和 - sum += nums[i]; - // 如果i>=K,说明前K个元素的值已经累加完毕,窗口开始向右滑动 - // 从K个元素之后,每次滑动1个元素 - // 需要从sum里减去上一次滑动窗口的首个元素nums[i - K] - // sum -= nums[i - K]得到从第[i-K+1]个元素起到第i个元素为止的K个元素之和 - if (i >= K) sum -= nums[i - K]; - // 第一组K个元素在nums中的下标从0到K-1 - // 所以W的第一个元素是 W[i-K+1] = W[(K-1)-K+1] = W[0] - if (i >= K - 1) W[i - K + 1] = sum; - } - - // 首先需要明白本解法中nums、W和left(或right)这三个数组索引的对应关系 - // - // 先看W[i]和nums[i]的关系: - // 在前一个给W赋值的for循环代码中可以看出,W[i]对应着nums中从nums[i]算起,到nums[i+K-1],共K个元素的和 - // 如题目示例,nums=[1,2,1,2,6,7,5,1],K=2,W=[3,3,3,8,13,12,6] - // W[0]=nums[0]+nums[1]=1+2=3,即W[0]等于nums[0]到nums[0+2-1]=nums[1],共2个元素的和 - // - // 再看left[i]和W[i]的关系: - // 给left[i](或right[i])赋值时,需要找到从W[0]到W[i]为止,元素值且索引最小那个元素 - // 然后将W中这个元素的索引赋给left[i] - // 即给left[0]赋值时,比较W[0]到W[0]共1个元素, - // 给left[1]赋值时,比较W[0]到W[1]共2个元素, - // 给left[2]赋值时,比较W[0]到W[2]共3个元素...以此类推 - // 因为W[0]=w[1]=W[2]=3,而W[0]、W[1]、W[2]三个元素中W[0]的索引最小 - // 所以left[0]=left[1]=left[2]=0,都取最小的那个索引0 - // - // 同时,由于到nums[nums.length - K + 1]为止,W和nums中的索引是一一对应的 - // 而left[i]记录的又是W中的索引,所以left[i]与nums中的元素索引一一对应 - // 索引的对应关系清楚了,下面关于left和right的代码就容易理解了 - - //题目要求返回nums中和最大的3个子序列的起始索引 - //我们将这3个子序列中的第1个子序列的可能索引都存入一个整数数组left - int[] left = new int[W.length]; - //定义一个整数best,记录每次迭代时,从数组W中获取到的相对最大值在W中的索引 - //best默认值为0 - int best = 0; - //按索引从小到大遍历数组W - for (int i = 0; i < W.length; i++) { - //W[i] > W[best]表示当前第i个元素W[i],大于W中已知的最大元素W[best] - //将索引i赋值给best - if (W[i] > W[best]) best = i; - //将当前为止W中最大值的索引best赋给left[i] - left[i] = best; - } - - //题目要求返回nums中和最大的3个子序列的起始索引 - //我们将这3个子序列中的第3个子序列的可能索引都存入一个整数数组right - int[] right = new int[W.length]; - //best默认值为W数组的末尾索引 - best = W.length - 1; - //按索引从大到小遍历数组W - for (int i = W.length - 1; i >= 0; i--) { - //W[i] > W[best]表示当前第i个元素W[i],大于等于W中已知的最大元素W[best] - //将索引i赋值给best - if (W[i] >= W[best]) best = i; - //将当前为止W中最大值的索引best赋给right[i] - right[i] = best; - } - - // 定义一个整数数组ans用于返回最终结果,即3个子序列的初始索引 - int[] ans = new int[]{-1, -1, -1}; - // for循环的控制变量j在循环体中要进行j-K和j + K的操作 - // j-K要大于等于0,j+K要小于W.length - // 所以j的初始值为K,j的上限值W.length - K - for (int j = K; j < W.length - K; j++) { - // 定义3个子序列的中间序列的索引为j - // 那么W[j]等于nums[j]到nums[j+K-1]共K个元素的和 - // 因为3个子序列不重叠,所以: - // 第1个序列的索引应该小于或等于j-K - // 第3个序列的索引应该大于或等于j+K - // left[j - K]记录了到从nums[0]到nums[j-K]为止,子序列和最大初始索引最小的那个索引 - // right[j - K]记录了到nums[nums.length]到nums[j+K]为止,子序列和最大初始索引最小的那个索引 - int i = left[j - K], k = right[j + K]; - //当ans[0] == -1时,ans还没有赋值 - //当W[i] + W[j] + W[k] > W[ans[0]] + W[ans[1]] + W[ans[2]]时 - //说明找到了更大的3个子序列之和 - //满足上述两个条件之一,即对ans[0]、ans[1]、ans[2]重新赋值 - if (ans[0] == -1 || W[i] + W[j] + W[k] > - W[ans[0]] + W[ans[1]] + W[ans[2]]) { - //分别将初始索引i、j、k赋值给ans[0]、ans[1]、ans[2] - ans[0] = i; - ans[1] = j; - ans[2] = k; - } - } - //返回最终结果 - return ans; - } - -``` - -**复杂度分析** - -时间复杂度:O(N), -方法中使用了4个for循环,迭代次数都在nums的长度范围内, -所以时间复杂度为4N,消去常数项,时间复杂度为O(N) - -空间复杂度:O(N), -定义了3个整数数组W、left、right, -占用空间都在nums数组的长度范围内, -还定义了一个数组ans,长度为常数3, -所以空间复杂度是3N+3,消去常数项最终空间复杂度为O(N) - ---- - -**参考资料** - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/maximum-sum-of-3-non-overlapping-intervals/](https://leetcode.com/articles/maximum-sum-of-3-non-overlapping-intervals/) diff --git a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md b/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md deleted file mode 100644 index 1c6cd74..0000000 --- a/_site/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**689. 三个无重叠子数组的最大和** ---- -[https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) diff --git a/_site/leetcode/691-StickersToSpellWord/official.md b/_site/leetcode/691-StickersToSpellWord/official.md deleted file mode 100644 index fa024ea..0000000 --- a/_site/leetcode/691-StickersToSpellWord/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**691. 贴纸拼词** ---- -[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) diff --git a/_site/leetcode/692-TopKFrequentWords/bigablecat.md b/_site/leetcode/692-TopKFrequentWords/bigablecat.md deleted file mode 100644 index 2bf2ace..0000000 --- a/_site/leetcode/692-TopKFrequentWords/bigablecat.md +++ /dev/null @@ -1,66 +0,0 @@ -**692. 前K个高频单词** ---- -[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) - - -```java - - public List topKFrequent(String[] words, int k) { - //定义一个HashSet用来存储出现过的单词和计数 - Map count = new HashMap(); - //遍历数组 - for (String word : words) { - //count.getOrDefault(word, 0)获取set中已经存在的key为word的值 - //如果存在获取其计数,如果不存在给出默认值0 - //count.getOrDefault(word, 0) + 1 当前单词每出现一次计数加1 - count.put(word, count.getOrDefault(word, 0) + 1); - } - //提取set的所有key值,即words数组的全部元素,传入新建的List - List candidates = new ArrayList(count.keySet()); - - //调用Collections自带的sort方法,该方法又调用List的sort方法,并最终使用了合并排序 - //第一个参数是实现了List接口的结合candidates - //第二个参数是一个Comparator对象,在调用sort方法的同时,使用自定义的排序规则 - //(w1, w2) -> 使用了lambda表达式的写法 - /** - Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1)); - 等价于 - Collections.sort(candidates, new Comparator() { - @Override - public int compare(String w1, String w2) { - int result = count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1); - return result; - } - }); - * - */ - // count.get(w1).equals(count.get(w2)) ? w1.compareTo(w2) : count.get(w2) - count.get(w1); - // count.get(w1).equals(count.get(w2)) 首先比较两个单词的出现次数是否相等 - // w1.compareTo(w2) 如果w1和w2的计数相等,调用w1的compareTo方法,会给出两个单词的字母顺序比对结果 - // count.get(w2) - count.get(w1) 如果w1和w2的计数不相等,那么返回两个字符串出现次数的差值 - Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ? - w1.compareTo(w2) : count.get(w2) - count.get(w1)); - //candidates.subList(0, k)截取最终结果的前k个并返回 - return candidates.subList(0, k); - } - -``` - -**复杂度分析** - -时间复杂度: -O(NlogN),N是单词数组的长度,计算每个单词出现的频率耗费O(n)的时间复杂度,对单词排序耗费O(NlogN)的时间复杂度 - -空间复杂度: -O(N), 使用了List存储n个单词 - ---- - - -**参考资料** - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) - -* Collections.sort()的用法和要点: -[https://blog.csdn.net/wsll581/article/details/79953589](https://blog.csdn.net/wsll581/article/details/79953589) diff --git a/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md b/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md deleted file mode 100644 index d9fcbf9..0000000 --- a/_site/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md +++ /dev/null @@ -1,54 +0,0 @@ -**698. 划分为k个相等的子集** ---- -[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) - -解决方案 -**思路** -先求出平均数avg,假如平均数avg不为整数,也就是说数组的数字总和不能平均的分为k份,那么直接返回false。 -创建一个布尔数组flag,来记录nums数组中数字的状态(已用还是未用),temp初始为avg,temp的作用为记录当前子集的数字总和, -当temp=0的时候,也就是新一个子集求解完,那么继续求解下一个子集,k-1,temp重新置为avg;当temp!=0时,就是子集还未求解完, -那么继续求解子集,继续从数组中取数字,递归求解 -``` -class Solution { - public boolean canPartitionKSubsets(int[] nums, int k) { - //定义临时变量,求出当前数组的和 - int sum = 0; - //当前数组的长度 - int len = nums.length; - //对数组进行遍历,拿到当前的数组元素的和 - for (int i = 0; i < len; i++) - sum += nums[i]; - //如果数组的的综合不能均分则返回false - if(sum % k != 0 ) return false; - //初始化tmp为avg,用来记录当前子集的数字总和 - int avg = sum / k; - //可以均分的时候,定义布尔数组的flag,来记录nums数组中的状态 - boolean[] flag = new boolean[len]; - //index是为了在遍历数组的位置起始位置,放置前面的数字重新计算 - return help(nums,flag,avg,k,avg,0); - } - public static boolean help(int[] nums, boolean[] flag, int avg, int k, int temp, int index ){ - if (k == 0 ) return true; - //当前avg为0的时候,子集就已经确定了 - if (temp == 0) - return help(nums,flag,avg,k-1,avg,0); - for (int i = index; i < nums.length; i++) { - //如果数组状态为true的时候,继续 - if (flag[i] == true) continue; - flag[i] = true; - //对比子集的总和当前数组的元素的大小,从数组继续取数字,给index值加1,放置重新计算 - if(temp-nums[i] >= 0 && help(nums,flag,avg,k,temp-nums[i],index+1)){ - return true; - } - flag[i] = false; - } - return false; - } -} -``` -**复杂度分析** -平均时间复杂度:O(nlogn) -空间复杂度:O(n) - -**参考资料** - [https://blog.csdn.net/qq_38595487/article/details/81535891](https://blog.csdn.net/qq_38595487/article/details/81535891) \ No newline at end of file diff --git a/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md b/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md deleted file mode 100644 index 45d2743..0000000 --- a/_site/leetcode/698-PartitionToKEqualSumSubsets/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**698. 划分为k个相等的子集** ---- -[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) diff --git a/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md b/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md deleted file mode 100644 index 52d9ad1..0000000 --- a/_site/leetcode/703-KthLargestElementInAStream/BambooYH.md +++ /dev/null @@ -1,47 +0,0 @@ -**703. 数据流中的第K大元素** ---- -[https://leetcode.com/problems/kth-largest-element-in-a-stream/](https://leetcode.com/problems/kth-largest-element-in-a-stream/) -**解决方案** -方法一:**堆** -**思路** -这个题跟其他两题有点类似,一个是找给定数组中的第K大元素,一个是找数据流的中位数。我们分别讨论一下: -数组中的第K大元素,这个我们一般用快排来找,因为首先数组元素的个数是固定的,而快排每趟都能确定一个数的最终位置,所以在给数组排序的过程中,就可以找到第K大的数。 -数据流中的第K大元素,因为是数据流,所以数据的个数是不固定的,这时候用快排就不合适了,因为最坏的情况下,第K大的元素一直在变,每次都需要重新排序。而且占用的空间也越来越大,这时候的空间复杂度和时间复杂度都是不能接受的。所以用最小堆是最合适的,我们只要保证最小堆的大小是K,那么堆顶的元素,肯定就是第K大的元素。同理可以用最大堆来找第K小元素 -数据流的中位数,这个题跟上一个还不一样,不但数据个数是不固定的,找的“第K大元素”也一直在变化。但因为每次找的都是中位数,所以我们可以用两个堆来实现,一个最大堆,一个最小堆。用两个堆来“平分”数据流 -**算法** -创建一个最小堆,在将数据加入堆的过程中,如果待加入元素大于堆顶元素,则弹出堆顶元素,将待加入元素放入堆中,保证堆的大小是K,这样堆顶的元素就是我们要找的第K大的元素 -``` - class KthLargest { - //优先队列是用堆实现的 - final PriorityQueue q; - final int k; - - public KthLargest(int k, int[] a) { - //初始化k和优先队列 - this.k = k; - q = new PriorityQueue<>(k); - for (int n : a) - add(n); - } - - public int add(int n) { - //如果当前堆的元素个数小于K,则直接放入 - if (q.size() < k) - q.offer(n); - //如果待加入元素n大于堆顶元素,则弹出堆顶元素,将n放入堆中 - else if (q.peek() < n) { - q.poll(); - q.offer(n); - } - //返回堆顶元素 - return q.peek(); - } - } -``` -**复杂度分析** -空间复杂度:O(K) -时间复杂度:O(n),n为数据流的长度 - -**参考资料** -leetCode Discuss - [https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) diff --git a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md deleted file mode 100644 index 8a77e9c..0000000 --- a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md +++ /dev/null @@ -1,43 +0,0 @@ -**712 最小的删除和** -[https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) -方法一:**动态规划** -**思路** -首先,这个题最暴力的解法是将所有的情况都考虑一遍,然后选出最小值。但是这种做法的时间复杂度是不能接受的。我们可以仔细分析一下这个题。假设有字符串A和字符串B,在寻找的过程中,我们最多有三种情况 -- 当前字符a和字符b相等,这种情况,无需处理,接着遍历即可 -- 删除字符a,用字符a的下一个字符跟字符b比较 -- 删除字符b,用字符b的下一个字符跟字符a比较 - -根据上面分析的情况,我们可以用动态规划来处理。我们用dp[i][j]表示A[i:]和B[j:]的最小删除和,所以我们最后要求的值就是dp[0][0]. -**算法** -根据上面的分析,我们用公式来表示上述的三种情况,因为最终要求的是dp[0][0],所以我们应该从后向前遍历。假设我们要求dp[i][j],如果`s1[i] == s2[j]`,那么很明显不用删除,此时`dp[i][j] == dp[i+1][j+1]`.如果`s1[i] != s2[j]`,我们就要删除一个字符,要么删除s1[i],要么删除s2[j],此时该如何决定呢?根据题意,我们应该选择值小的那个,也就是`dp[i][j] = Math.min(s1[i]+dp[i+1][j],s2[j]+dp[i][j+1])`。 -**代码** -``` -class Solution { - public int minimumDeleteSum(String s1, String s2) { - //获取两个字符串的长度 - int m = s1.length(), n = s2.length(), MAX = Integer.MAX_VALUE; - //将字符串转换成字符数组,数组更好处理一些,直接用字符串进行处理,会更麻烦一些,但是也可以。 - char[] a = s1.toCharArray(), b = s2.toCharArray(); - //初始化辅助数组 - int[][] dp = new int[m + 1][n + 1]; - //从后向前遍历 - for (int i = m; i >= 0; i--) { - for (int j = n; j >= 0; j--) { - //当i==m或者j==n的时候,不用处理,因为s1[m]和s2[n]字符不存在。 - if (i < m || j < n) - //下面这个公式,就是算法部分说明的公式,只不过将他们写在一起,需要注意的是,要注意边界条件,因为上面if的条件是 ||,所以下面还要检测一下。 - dp[i][j] = i < m && j < n && a[i] == b[j] ? - dp[i + 1][j + 1] : Math.min((i < m ? a[i] + dp[i + 1][j] : MAX), (j < n ? b[j] + dp[i][j + 1] : MAX)); - } - } - return dp[0][0]; - } -} -``` -复杂度分析: -假设字符串的长度分别为M,N -空间复杂度:O(M*N),辅助数组 -时间复杂度:O(M*N),两重循环 - -参考资料: -[LeetCode Discuss](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/discuss/108814/JavaC%2B%2B-Clean-Code) \ No newline at end of file diff --git a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md b/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md deleted file mode 100644 index 50251d0..0000000 --- a/_site/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**712. 两个字符串的最小ASCII删除和** ---- -[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) diff --git a/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md b/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md deleted file mode 100644 index 014fd54..0000000 --- a/_site/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md +++ /dev/null @@ -1,57 +0,0 @@ -**714. 买卖股票的最佳时机含手续费** ---- -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) - -* 选择的关键是找到一个最大后是不是能够卖掉stock,重新开始寻找买入机会。 -比如序列1 3 2 8,如果发现2小于3就完成交易买1卖3,此时由于fee=2,(3-1-fee)+(8-2-fee)<(8-1-fee), -所以说明卖早了,令max是当前最大price,当(max-price[i]>=fee)时可以在max处卖出,且不会存在卖早的情况, -再从i开始重新寻找买入机会 -贪心解法: -```java -public class Solution { - public static int maxProfit(int[] prices, int fee) { - int n = prices.length; - if (n <= 1) { - return 0; - } - int p = 0, curP = 0; - int minP = prices[0], maxP = prices[0]; - for (int i = 1; i < n; i++) { - minP = Math.min(minP, prices[i]); - maxP = Math.max(maxP, prices[i]); - curP = Math.max(curP, prices[i] - minP - fee); - if (maxP - prices[i] >= fee) { - p += curP; - curP = 0; - maxP = prices[i]; - minP = prices[i]; - } - } - return p + curP; - } -} -``` -* 动态转移点:手上有没有股票 进行DP。对于第i天的最大收益,应分成两种情况,一是该天结束后手里没有stock, -可能是保持前一天的状态也可能是今天卖出了,此时令收益为cash;二是该天结束后手中有一个stock, -可能是保持前一天的状态,也可能是今天买入了。由于第i天的情况只和i-1天有关,所以用两个变量cash和buy就可以, -不需要用数组 - -```java -class Solution { - public int maxProfit(int[] prices, int fee) { - int n=prices.length; - if(n<=1) - return 0; - int buy=-prices[0]; - int cash=0; - for(int i=1;i 0) { // 表示此处存在值序列 - if (i - 1 == maxValueIndex) { // 最优解所对应的最大Index与插入值序列的值num相邻 - // 先求出第二大的值与插入的值序列求和值 - int temp = secondMax + count[i] * i; - // 与之前的值序列集合最大值进行比较 - if (temp > firstMax) { - // 若新插入的值使得firstMax变化,则firstMax变为第二大值 - // 第一大值改变,索引也需要改变 - secondMax = firstMax; - firstMax = temp; - maxValueIndex = i; - } else { - // 若新插入的值使得firstMax没有变化,则仅仅修改第二大值 - secondMax = temp; - } - } else { - // 最优解所对应的最大Index与插入值序列的值num不相邻 - // 则直接拿来相加,并修改对应索引 - secondMax = firstMax; - firstMax = i * count[i] + firstMax; - maxValueIndex = i; - } - } - } - - // 返回最大值 - return firstMax; - } -} -``` - ---- - - -**参考资料** - -* 官方题解: -[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) diff --git a/_site/leetcode/740-DeleteAndEarn/official.md b/_site/leetcode/740-DeleteAndEarn/official.md deleted file mode 100644 index 4133181..0000000 --- a/_site/leetcode/740-DeleteAndEarn/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**740. 删除与获得点数** ---- -[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) diff --git a/_site/leetcode/746-minCostClimbingStairs/bigablecat.md b/_site/leetcode/746-minCostClimbingStairs/bigablecat.md deleted file mode 100644 index 634690d..0000000 --- a/_site/leetcode/746-minCostClimbingStairs/bigablecat.md +++ /dev/null @@ -1,61 +0,0 @@ -**746. 使用最小花费爬楼梯** ---- -[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) - -```java - - /** - * https://leetcode.com/articles/min-cost-climbing-stairs/ - *

- * 英文官方题解 - * - * @param cost - * @return - */ - public static int minCostClimbingStairs(int[] cost) { - //根据题意,爬楼可以走一个台阶或者两个台阶 - //定义两个变量f1,f2分别记录走一个台阶和两个台阶的花费 - int f1 = 0, f2 = 0; - //从尾向头方向遍历数组元素 - for (int i = cost.length - 1; i >= 0; --i) { - //cost[i]获取在第i个阶梯时的花费 - //根据题意,有走一个台阶和两个台阶两种走法 - //f1表示走到第i+1个台阶的花费 - //f2表示走到第i+2个台阶的花费 - //Math.min(f1, f2);从两种走法中获取花费较小的一种 - //f0得到从第i个阶梯继续向上走到楼顶的所有花费 - //从最后一个台阶开始计算时 - //不存在第i+1和第i+2个台阶,f1和f2初始值为0,对结果没有影响 - int f0 = cost[i] + Math.min(f1, f2); - //下一轮将计算第i-1个台阶到楼顶的花费 - //在本轮中, - //f0、f1、f2分别代表第i个、第i+1个和第i+2个台阶到楼顶的费用 - //那么下一轮,计算第i-1个台阶到楼顶的费用时,需要知道第i个,第i+1个台阶的费用 - //为下一轮的备选答案赋值 - //f1为第i+1个台阶到楼顶的花费,赋值给f2,即为下一轮走2个台阶方案的花费 - f2 = f1; - //f0位第i个台阶到楼顶的花费,赋值给f1,即为下一轮走1个台阶方案的花费 - f1 = f0; - } - //遍历完数组时 - // f1为从cost[0]开始向上到楼顶的花费 - // f2为从cost[1]开始向上到楼顶的花费 - return Math.min(f1, f2); - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -遍历长度为n的数组一次 - -空间复杂度:O(1), -f1和f2使用了常数空间 - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) diff --git a/_site/leetcode/746-minCostClimbingStairs/official.md b/_site/leetcode/746-minCostClimbingStairs/official.md deleted file mode 100644 index 92d26ec..0000000 --- a/_site/leetcode/746-minCostClimbingStairs/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**746. 使用最小花费爬楼梯** ---- -[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) diff --git a/_site/leetcode/764-LargestPlusSign/SpecialYang.md b/_site/leetcode/764-LargestPlusSign/SpecialYang.md deleted file mode 100644 index 5b0de24..0000000 --- a/_site/leetcode/764-LargestPlusSign/SpecialYang.md +++ /dev/null @@ -1,145 +0,0 @@ -**764.最大加号标志** ---- -https://leetcode.com/problems/largest-plus-sign/ - -题目意思是给一个`$N \times N$`的矩阵,然后再告诉你其中某些单元格的值为0。让你求出值可以为1的单元格为中心,它的四臂上,下,左,右都要为1,组成加号标志,四个方向同时都要全部为1,这样的情况下,加号的长度最大为多少。显然加号的最大的长度取决于四个方向最短全为1。其实就是**木桶效应**了。 - - - 加号中心要为1 - - 加号的四臂都要为1,且长度要一致,显然由最短的决定整体的长度 - -### 思路一 -暴力法。遍历所有的单元格,以所有的可以为1的单元格为中心,一步一步同时向四周扩散,直到某个臂为0为止,继续对下一个可以为1的单元格作同样的处理,期间维护一个最大臂长即可。 - -```java - /** - * 暴力解法 - * @param N - * @param mines - * @return - */ - public int orderOfLargestPlusSign1(int N, int[][] mines) { - int[][] dp = new int[N][N]; - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - dp[i][j] = N; - } - } - for (int[] mine : mines) { - dp[mine[0]][mine[1]] = 0; - } - int max = 0; - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - int k = 0; - while (i - k >= 0 && i + k < N && j - k >= 0 && j + k < N - && dp[i - k][j] == 1 - && dp[i + k][j] == 1 - && dp[i][j - k] == 1 - && dp[i][j + k] == 1) { - k++; - } - max = Math.max(max, k); - } - } - return max; - } -``` -#### 复杂度 -- 时间复杂度:O(n^3) -- 空间复杂度:O(n^2) - -### 思路二动态规划 -我们发现第i个单元格的左臂长度其实不用在重头开始计算,利用第i-1个单元格的值就可以确定第i个单元格的左臂长度。 -```math -left[i] = Math.min(left[i], left[i] == 0 ? 0 : left[i - 1] + 1) -``` -如果是这样的思路岂不是再申请3个其他方向的数组,显然不太合理,好在我们只需对每个单元格求四个方向中最短的那一长度,这就可以重用了啊,我们先求左,然后统一求右,再上,下,每次都要求最小即可,最后必然是四个方向的重叠的最小结果。 - -那就有了下面的这个代码: -```java - //以行单位 - for (int i = 0; i < N; i++) { - //求该行中所有单元格的最大左臂长 - for (int j=0, l=0; j < N; j++) { - // j is a column index, iterate from left to right - // every time check how far left it can reach. - // if grid[i][j] is 0, l needs to start over from 0 again, otherwise increment - grid[i][j] = Math.min(grid[i][j], l = (grid[i][j] == 0 ? 0 : l + 1)); - } - //求该行中所有单元格的最大右臂长 - for (int k = N-1, r=0; k >= 0; k--) { - // k is a column index, iterate from right to left - // every time check how far right it can reach. - // if grid[i][k] is 0, r needs to start over from 0 again, otherwise increment - grid[i][k] = Math.min(grid[i][k], r = (grid[i][k] == 0 ? 0 : r + 1)); - } - //求该行中所有单元格的最大上臂长 - for (int j = 0, u=0; j < N; j++) { - // j is a row index, iterate from top to bottom - // every time check how far up it can reach. - // if grid[j][i] is 0, u needs to start over from 0 again, otherwise increment - grid[j][i] = Math.min(grid[j][i], u = (grid[j][i] == 0 ? 0 : u + 1)); - } - //求该行中所有单元格的最大下臂长 - for (int k = N-1, d=0; k >= 0; k--) { - // k is a row index, iterate from bottom to top - // every time check how far down it can reach. - // if grid[k][i] is 0, d needs to start over from 0 again, otherwise increment - grid[k][i] = Math.min(grid[k][i], d = (grid[k][i] == 0 ? 0 : d + 1)); - } - - // after four loops each time taking Math.min over the grid value itself - // all grid values will eventually take the min of the 4 direcitons. - } -``` - -很显然我们可以合并这个loop,那么就有了下面的代码: -```java - /** - * 动态规划 - * - * 对每个方向都取最小,那么最终以这个为中心的就是最小长度 - * @param N - * @param mines - * @return - */ - public int orderOfLargestPlusSign2(int N, int[][] mines) { - int[][] dp = new int[N][N]; - //初始化大于等于N就行,因为我们每次求的是4臂的最小值 - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - dp[i][j] = N; - } - } - for (int[] mine : mines) { - dp[mine[0]][mine[1]] = 0; - } - for (int i = 0; i < N; i++) { - //充分利用了j, k的值 - for (int j = 0, k = N - 1, l = 0, r = 0, u = 0, d = 0; j < N; j++, k--) { - //左 - dp[i][j] = Math.min(dp[i][j], l = (dp[i][j] == 0 ? 0 : l + 1)); - //右 - dp[i][k] = Math.min(dp[i][k], r = (dp[i][k] == 0 ? 0 : r + 1)); - //上 - dp[j][i] = Math.min(dp[j][i], u = (dp[j][i] == 0 ? 0 : u + 1)); - //下 - dp[k][i] = Math.min(dp[k][i], d = (dp[k][j] == 0 ? 0 : d + 1)); - } - } - int max = 0; - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - max = Math.max(0, dp[i][j]); - } - } - return max; - } -``` -#### 复杂度 -- 时间复杂度:O(n^2) -- 空间复杂度:O(n^2) - -参考: -- https://leetcode.com/problems/largest-plus-sign/discuss/113314/JavaC%2B%2BPython-O(N2)-solution-using-only-one-grid-matrix -- https://leetcode.com/problems/largest-plus-sign/solution/ \ No newline at end of file diff --git a/_site/leetcode/764-LargestPlusSign/official.md b/_site/leetcode/764-LargestPlusSign/official.md deleted file mode 100644 index 5ddaa33..0000000 --- a/_site/leetcode/764-LargestPlusSign/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**764. 最大加号标志** ---- -[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) diff --git a/_site/leetcode/787-CheapestFlightsWithinKStops/official.md b/_site/leetcode/787-CheapestFlightsWithinKStops/official.md deleted file mode 100644 index f83e072..0000000 --- a/_site/leetcode/787-CheapestFlightsWithinKStops/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**787. K 站中转内最便宜的航班** ---- -[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) diff --git a/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md b/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md deleted file mode 100644 index f90a41c..0000000 --- a/_site/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md +++ /dev/null @@ -1,84 +0,0 @@ -https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/ - -787. K 站中转内最便宜的航班 - -思路: - -**动态规划思想** - -1.状态转移方程: - -ans = min(ans, costs[k] + prices[k][dst]) - -其中costs[k]表示到达位置k时的最小花费,prices[k][dst]表示从k到达dst的航班价格。 - -``` -class Solution: - def findCheapestPrice(self, n, flights, src, dst, K): - """ - :type n: int - :type flights: List[List[int]] - :type src: int - :type dst: int - :type K: int - :rtype: int - """ - INF = 0x7FFFFFFF - prices = collections.defaultdict(lambda: collections.defaultdict(int)) #内置collection得到数组 - for s, t, p in flights: - prices[s][t] = p - ans = prices[src][dst] or INF #从src到dst的prices - queue = [src] #src的队列列表 - costs = {src : 0} #费用的字典 key:src,value:数字 - for x in range(K + 1): - nset = set() #一个集合 - for loc in queue: #在当前的位置 - ans = min(ans, costs[loc] + (prices[loc][dst] or INF)) - for next in prices[loc]: #下一段转的航班需要花费的费用 - costs[next] = min(costs.get(next, INF), costs[loc] + (prices[loc][next] or INF)) - nset.add(next) #next为prices的一维数组,加入集合当中 - queue = list(nset) #最后我们可以得到一个队列,存着每一个出发点,也就是航班 - return ans if ans < INF else -1 - -``` -时间复杂度是O(K * s * n) - -2.另一种动态规划的思路 - -用一个二维的dp数组,dp[i][j]表示在不超过i次转机的情况下,从j到达dst的最少费用。dp[i][j]=min(dp[i−1][k]+Pk−>j,Pk−>j) - -(从自己到自己为0,Pk−>k=0,若是没有这个线路则Pk−>j=inf) - -``` -class Solution(object): - def findCheapestPrice(self, n, flights, src, dst, K): - """ - :type n: int - :type flights: List[List[int]] - :type src: int - :type dst: int - :type K: int - :rtype: int - 176ms dp - """ - import collections - # 记录同一个终点的不同起点和价格 - flights_dict_end = collections.defaultdict(list) - for flight in flights: - flights_dict_end[flight[1]].append([flight[0], flight[2]]) - # 用来记录各种情况,n个站点,还剩K次,到达目的地最少价格 - dp = [[float('inf') for i in range(n)] for i in range(K + 1)] - # 初始化能直达的 - for i in flights_dict_end[dst]: - dp[0][i[0]] = i[1] - # 反向推回去 - for k in range(1, K + 1): - for pos in range(n): - for before in flights_dict_end[pos]: #遍历整个线路 - dp[k][before[0]] = min(dp[k][before[0]], dp[k-1][pos] + before[1]) #把转航班的加上去 - dp[k][pos] = min(dp[k][pos], dp[k-1][pos]) #状态转移方程 - ans = dp[K][src] - return ans if ans != float('inf') else -1 - -``` -时间复杂度是O(n * K * d) diff --git a/_site/leetcode/790-DominoAndTrominoTiling/mahone.md b/_site/leetcode/790-DominoAndTrominoTiling/mahone.md deleted file mode 100644 index e864018..0000000 --- a/_site/leetcode/790-DominoAndTrominoTiling/mahone.md +++ /dev/null @@ -1,44 +0,0 @@ -**790. 多米诺和托米诺平铺** ---- -[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) - -解决方案 -**思路** -思路1:此道题目根据相关数据来推到结论,得到计算每一个的公式,在根据公式来计算相应的结果。 -公式推到如下: -dp[n]=dp[n-1]+dp[n-2]+ 2*(dp[n-3]+...+d[0]) - =dp[n-1]+dp[n-2]+dp[n-3]+dp[n-3]+2*(dp[n-4]+...+d[0]) - =dp[n-1]+dp[n-3]+(dp[n-2]+dp[n-3]+2*(dp[n-4]+...+d[0])) - =dp[n-1]+dp[n-3]+dp[n-1] - =2*dp[n-1]+dp[n-3] - -``` - public int numTilings(int N){ - //result: dp[i] = 2*dp[i-1] + dp[i-3]; - int md = 1000000007; - //map to save value - Map valueMap = new HashMap<>(1001); - valueMap.put(1,1L); - valueMap.put(2,2L); - valueMap.put(3,5L); - if (N <=3){ - return valueMap.get(N).intValue(); - } - for (int i = 4; i <= N;++i) { - //根据来计算值 - Long tmp = 2 * valueMap.get(i - 1) + valueMap.get(i - 3); - //取余 - Long value = tmp % md; - valueMap.put(i,Long.valueOf(value)); - } - return valueMap.get(N).intValue(); - } -``` - -**复杂度分析** -时间复杂度:O(N) ,由于计算N的值需要得到之前的数据,因此循环计算,时间复杂度位o(N) -空间复杂度:O(M*N),空间使用dp - - -**参考资料** -[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) \ No newline at end of file diff --git a/_site/leetcode/790-DominoAndTrominoTiling/official.md b/_site/leetcode/790-DominoAndTrominoTiling/official.md deleted file mode 100644 index 5b01baa..0000000 --- a/_site/leetcode/790-DominoAndTrominoTiling/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**790. 多米诺和托米诺平铺** ---- -[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) diff --git a/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md b/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md deleted file mode 100644 index 0fa084f..0000000 --- a/_site/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**801. 使序列递增的最小交换次数** ---- -[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) diff --git a/_site/leetcode/808-SoupServings/official.md b/_site/leetcode/808-SoupServings/official.md deleted file mode 100644 index 44ac270..0000000 --- a/_site/leetcode/808-SoupServings/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**808. 分汤** ---- -[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) diff --git a/_site/leetcode/813-LargestSumOfAverages/melody-l.md b/_site/leetcode/813-LargestSumOfAverages/melody-l.md deleted file mode 100644 index a7dd15f..0000000 --- a/_site/leetcode/813-LargestSumOfAverages/melody-l.md +++ /dev/null @@ -1,59 +0,0 @@ -**813.LargestSumOfAverage** ---- -[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) - -方法一:动态规划 -本题的dp思路是:设result[i][k]表示序列A[0]到A[i]分成k份的最优解。假设,现在需要划分最后一组,则设第k-1份的终点为j(即第k份是从A[j]到A[i])。此时`result[i][k]=result[j-1][k-1]+{sum(j...i)/(i-j+1)}`。 -因此,算法思路为:固定i,固定k,判断此时j最合适的位置。然后扩大i,判断不同的i的时候j最适合的位置。最后扩大k。这样递推式所需要的前项结果是能够提供的。 -下面代码优化的点为:提前前i项的和sum[i]求出,这样在计算从j到i的和的平均值为:`(sum[i]-sum[j])/(i-j+1)`。对于sum[i],i表示的是序列的长度,非索引。 - -```java -class Solution { - public double largestSumOfAverages(int[] A, int K) { - int N = A.length; - - // sum[i]表示前i项的和,i表示的是序列的长度,非索引 - // sum[0]没有使用,所以长度为N+1 - double[] sum = new double[N + 1]; - for (int i = 0; i < N; i++) { - sum[i + 1] = sum[i] + A[i]; - } - - // result[i][j]保存长度为i+1的序列,分割为j份的结果 - double[][] result = new double[A.length][K+1]; - for (int k = 1; k <= K; k++) {// 将序列分成k份,k取值为1到K - for (int i = 0; i < N; i++) { // 序列从i开始遍历 - if (k == 1) { - // 只分割为1份,因此直接求平均值 - result[i][k] = sum[i + 1] / (double) (i + 1); - } else if (k > i + 1) { - // 如果要分割的份数比此时的序列长度还大, - // 就不进行计算 - continue; - } else { - // 对于固定的i(此时序列长度为i+1), - // 如果要分割为固定的k份, - // 现在,需要知道第k-1份的终止点为哪里时,效果最好, - // 因此,遍历所有的j,最大值的点即是k-1份的终止点 - for (int j = k - 1; j <= i; j++) {// 从k-1开始遍历(前面至少要有k-1份能够被平分,不然没必要遍历),遍历到i为止(此时序列长度为i+1) - double temp = (sum[i+1] - sum[j]) / (i - j + 1) + result[j - 1][k - 1];// 若k-1份的终止点为j,则根据递推式求出当前值temp - result[i][k] = Math.max(result[i][k], temp);// 比较temp选最大 - } - } - } - } - - return result[N - 1][K]; //返回长度为N,分割为K份的值 - } -} -``` - ---- - - -**参考资料** - -* 官方题解: -[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) -* 网友题解: -[https://blog.csdn.net/magicbean2/article/details/79893634](https://blog.csdn.net/magicbean2/article/details/79893634) diff --git a/_site/leetcode/813-LargestSumOfAverages/official.md b/_site/leetcode/813-LargestSumOfAverages/official.md deleted file mode 100644 index 65ee94b..0000000 --- a/_site/leetcode/813-LargestSumOfAverages/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**813. 最大平均值和的分组** ---- -[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) diff --git a/_site/leetcode/837-New21Game/official.md b/_site/leetcode/837-New21Game/official.md deleted file mode 100644 index 5900ca8..0000000 --- a/_site/leetcode/837-New21Game/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**837. 新21点** ---- -[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) diff --git a/_site/leetcode/838-PushDominoes/official.md b/_site/leetcode/838-PushDominoes/official.md deleted file mode 100644 index 9d82382..0000000 --- a/_site/leetcode/838-PushDominoes/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**838. 推多米诺** ---- -[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) diff --git a/_site/leetcode/844-BackspaceStringCompare/BambooYH.md b/_site/leetcode/844-BackspaceStringCompare/BambooYH.md deleted file mode 100644 index 2edc5b8..0000000 --- a/_site/leetcode/844-BackspaceStringCompare/BambooYH.md +++ /dev/null @@ -1,89 +0,0 @@ -**844 比较含退格的字符串** ---- -[https://leetcode.com/problems/backspace-string-compare/](https://leetcode.com/problems/backspace-string-compare/) - -解决方案 -方法一:栈 -**思路** -根据题意的描述,我们很容易的会想到最简单直接的方法,就是模拟退格操作,然后得到处理后的字符串,最后比较两个字符串是否相等。用栈来模拟退格操作是合适的,当然也可以用StringBuilder等方法,只要能模拟这个操作就可以,这里我们选用栈来实现 -**算法** -从左到右遍历字符串,遇到字母,直接压入栈;如果遇到“#”,若当前栈非空,则弹出栈顶元素。 -**代码** -``` -class Solution { - public boolean backspaceCompare(String S, String T) { - Stack stack1 = new Stack(); - //比较两个字符串是否相等 - return help(S,stack1).equals(help(T,stack1)); - } - public static String help(String S,Stack stack) { - //清空一下栈,防止受到上一次运行结果的影响 - stack.clear(); - for(int i = 0; i < S.length(); i++) { - //如果遇到“#”,当前栈非空,则弹出栈顶元素,既模拟退格操作 - if(S.charAt(i) == '#') { - if(!stack.empty()) { - stack.pop(); - } - //如果遇到字母,则压栈 - }else { - stack.push(S.charAt(i)); - } - } - return String.valueOf(stack); - } -} -``` -**复杂度分析** -设M是字符串S的长度,N是字符串T的长度 -时间复杂度:O(M+N) 既O(Max(M,N)),需要将两个字符串都遍历一遍 -空间复杂度:O(M+N) 既O(Max(M,N)),最多可以添加Max(M,N)个元素到栈里 - -方法二:双指针 -**思路** -前一个方法是从左到右遍历,当我们遍历到一个字符的时候,我们并不能确定它最终是否存在,因为这取决于后面有多少个“#”。但是如果我们倒过来看,从右向左遍历,在遍历到某个字符的时候,我们就可以确定它最终是否存在。 -**算法** -从右向左,同时遍历两个字符串,当各自确定了一个字符一定会存在的时候,比较两个字符是否相同。如果都相同,则继续遍历,如果不同,则返回false。在处理的过程中,要注意边界条件。 -**代码** -``` -class Solution { - public boolean backspaceCompare(String S, String T) { - int i = S.length() - 1, j = T.length() - 1; - int skipS = 0, skipT = 0;//用来记录字符串S和T分别有多少个“#” - - while (i >= 0 || j >= 0) { - //找到S中下一个最终会存在的字符 - while (i >= 0) { - if (S.charAt(i) == '#') {skipS++; i--;} - //如果当前字符是字母,并且有剩余的“#”,则跳过当前字符 - else if (skipS > 0) {skipS--; i--;} - else break; - } - //找到T中下一个最终会存在的字符 - while (j >= 0) { - if (T.charAt(j) == '#') {skipT++; j--;} - else if (skipT > 0) {skipT--; j--;} - else break; - } - //如果两个字符不相同,则返回false - if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) - return false; - //如果一个字符串中找到了一个字符,但是另一个字符串已经遍历完了,则返回false - if ((i >= 0) != (j >= 0)) - return false; - i--; j--; - } - return true; - } -} -``` - -**复杂度分析**: -设M是字符串S的长度,N是字符串T的长度 -空间复杂度:O(1) -时间复杂度:O(M+N) -**注意:本题的解法都没考虑字符串为null的情况,因为题目限定了字符串长度大于等于1,如果没有限定条件,还要考虑字符串为null的情况** - -**参考资料** -- 本题leetCode官方题解 - [https://leetcode.com/problems/backspace-string-compare/solution/](https://leetcode.com/problems/backspace-string-compare/solution/) \ No newline at end of file diff --git a/_site/leetcode/844-BackspaceStringCompare/bigablecat.md b/_site/leetcode/844-BackspaceStringCompare/bigablecat.md deleted file mode 100644 index 174ed0d..0000000 --- a/_site/leetcode/844-BackspaceStringCompare/bigablecat.md +++ /dev/null @@ -1,64 +0,0 @@ -**844. 比较含退格的字符串** ---- -[https://leetcode-cn.com/problems/backspace-string-compare/submissions/](https://leetcode-cn.com/problems/backspace-string-compare/submissions/) - -* 官方题解方法2 - -```java - /** - * 从后往前反向遍历字符串中的字符,跳过要删除的字符,比较最终结果会出现的有效字符 - * - * @param S - * @param T - * @return - */ - public boolean backspaceCompare(String S, String T) { - //i和j是循环次数上界 - int i = S.length() - 1, j = T.length() - 1; - //skipS和skipT是计数器,统计循环时跳过的字符个数 - int skipS = 0, skipT = 0; - //遍历两个字符串中的字符,依次对有效字符进行对比 - while (i >= 0 || j >= 0) { - //遍历字符串S中的字符 - while (i >= 0) { // Find position of next possible char in build(S) - //如果当前位置字符是'#'退格符号,计数器skipS递增1 - if (S.charAt(i) == '#') {skipS++; i--;} - //如果当前位置不是退格键且计数器值大于零,让计数器skipS递减1 - else if (skipS > 0) {skipS--; i--;} - else break; - } - //对字符串T做同样的操作 - while (j >= 0) { - if (T.charAt(j) == '#') {skipT++; j--;} - else if (skipT > 0) {skipT--; j--;} - else break; - } - // 讲过上述语句的跳过退格符号和被退格删除的字符 - // 分别取出S和T在最终结果对等位置将出现的字符 - // 如果两个字符不相等,说明两个字符串的最终有效结果不等 - if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) - return false; - // i >= 0和j >= 0分别判断两个字符串是否遍历结束 - // 如果一个遍历结束两一个没有结束,说明没有结束的字符串包含的有效字符比另一个多 - if ((i >= 0) != (j >= 0)) - return false; - i--; j--; - } - return true; - } - -``` - -**复杂度分析** - -时间复杂度: O(M + N),M和N分别是字符串S和T的长度,遍历两个字符串的所有字符需要M+N次迭代 - -空间复杂度: O(1),没有使用额外的辅助空间,空间复杂度为O(1) - ---- - - -**参考资料** - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) diff --git a/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md b/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md deleted file mode 100644 index cbbad6b..0000000 --- a/_site/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md +++ /dev/null @@ -1,88 +0,0 @@ -**847. 访问所有节点的最短路径** ---- -[https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes/](https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes/) - - -```java - - public int shortestPathLength2(int[][] graph) { - //定义一个整数N,N是图graph节点的数目 - int N = graph.length; - // 1<= 1 && res[0] >= 1) { - res[1]--; - res[0]--; - }else if(res[1] == 0 && res[0]>= 3) { - res[0] -= 3; - }else { - return false; - } - } - } - return true; - } -} -``` -复杂度分析: -假设数组长度为n -时间复杂度:O(n) -空间复杂度:O(1) \ No newline at end of file diff --git a/_site/leetcode/860-lemonadeChange/SpecialYang.md b/_site/leetcode/860-lemonadeChange/SpecialYang.md deleted file mode 100644 index 18b25f3..0000000 --- a/_site/leetcode/860-lemonadeChange/SpecialYang.md +++ /dev/null @@ -1,79 +0,0 @@ -**柠檬水找零** ---- -https://leetcode.com/problems/lemonade-change/ -### 思路一 -这道题属于典型的贪心算法。贪心算法的思路就是优先给当前状态分配最优解。子问题最优,从而促进父问题也最优。 - -回归问题,有这么个几种情况: -1. 顾客有5元,那再好不过了 -2. 顾客有10元,那要看看你当前有没有5元,如果没有,gg了 -3. 顾客有20元,这时要优先给他10元。因为5元很宝贵啊,5元可以适用于10,20元的情况,而10元只能适用于20元情况。给顾客10元,从而节省更多的5元为后面10元的顾客找零,这就是贪心的体现,为当前分配最优解。 - -基于以上的讨论,我们只需两个计数器统计当前剩余的5元,10元即可。 -```java - /** - * 贪心做法 - * @param bills - * @return - */ - public boolean lemonadeChange1(int[] bills) { - int five = 0; - int ten = 0; - for (int i = 0; i < bills.length; i++) { - int value = bills[i]; - if (value == 5) { //5元,计数 - five++; - } else if (value == 10) { //10元,5减一,10加1 - if (five == 0) { - return false; - } - five--; - ten++; - } else if (value == 20) { - //有10元,先给10元 - if (ten != 0) { - ten--; - value = 10; - } - //尝试给5元 - while (value > 5 && five > 0) { - value -= 5; - five--; - } - //若最终无法减为5元,说明找不开,gg - if (value > 5) { - return false; - } - } - } - return true; - } -``` - -上面的代码太啰嗦了,简化以下,瞬间清爽。 -```java - public boolean lemonadeChange2(int[] bills) { - int five = 0; - int ten = 0; - for (int i = 0; i < bills.length; i++) { - int value = bills[i]; - if (value == 5) { - five++; - } else if (value == 10) { - five--; - ten++; - } else if (ten > 0) { - ten--; - five--; - } else { - five -= 3; - } - if (five < 0) { - return false; - } - } - return true; - } - -``` -参考:https://leetcode.com/problems/lemonade-change/discuss/143719/C%2B%2BJavaPython-Straight-Forward \ No newline at end of file diff --git a/_site/leetcode/860-lemonadeChange/official.md b/_site/leetcode/860-lemonadeChange/official.md deleted file mode 100644 index 7a100ec..0000000 --- a/_site/leetcode/860-lemonadeChange/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**860. 柠檬水找零** ---- -[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) - diff --git a/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md b/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md deleted file mode 100644 index 60bfb85..0000000 --- a/_site/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**873. 最长的斐波那契子序列的长度** ---- -[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) diff --git a/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md b/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md deleted file mode 100644 index e4d298b..0000000 --- a/_site/leetcode/874-walkingRobotSimulation/SpecialYang.md +++ /dev/null @@ -1,111 +0,0 @@ -**模拟机器人行走** ---- -https://leetcode.com/problems/walking-robot-simulation/ - -note: 这道题有个大坑:就是它要求机器人**最远走多远**,并不是你最终的位置。所以这道题才被标记为贪心,意思就是希望每走完一次,都要判以下最大值。一开始以为是我的程序的bug,废了我好长时间,真不值得。 - -### 思路一 -看题目标题,意思就是模拟机器人行走。 -要额外的处理就是方向问题,机器人最开始面向北方,不妨我们使用4个数来表示东南西北吧。 -- 0 : 北方,对应坐标轴,y++ -- 1 : 东方:对应坐标轴,x++ -- 2 : 南方:对应坐标轴,y-- -- 3 : 西方:对应坐标轴,x-- - -机器人收到指令,无非是转向和前进: -- 当收到小于0的指令,便是转向。我们可以对于当前方向值进行更改,若向左转,则方向值减1,若当前为0,则要更新为3。若向右转,则方向加1,若当前为3,则要更新为0。原因:方向是个circle。 -- 当收到大于0的指令,则是前进的指令。但是我们要一步一步走,因为中途可能碰到障碍。 - -另一个要解决的问题就是如何快速判断一个位置是否是障碍,O(1)的时间只能是**集合**了,又因为给定的是数组形式,所以我们自定义我们的hash函数为:`array[][0] + "-" + array[][1]`,如此便可以给每一个位置赋予唯一的key。 - -```java - /** - * 有点啰嗦的代码 - * @param commands - * @param obstacles - * @return - */ - public int robotSim1(int[] commands, int[][] obstacles) { - int x = 0, y = 0, direction = 0, maxDistance = 0; - Set obstaclesSet = new HashSet<>(); - for (int i = 0; i < obstacles.length; i++) { - String str = obstacles[i][0] + "-" + obstacles[i][1]; - obstaclesSet.add(str); - } - for (int i = 0; i < commands.length; i++) { - int value = commands[i]; - if (value > 0) { - while (value-- > 0) { - switch (direction) { - case 0: - y++;break; - case 1: - x++;break; - case 2: - y--;break; - case 3: - x--;break; - } - String pos = x + "-" + y; - //若是障碍,要恢复如初 - if (obstaclesSet.contains(pos)) { - switch (direction) { - case 0: - y--;break; - case 1: - x--;break; - case 2: - y++;break; - case 3: - x++;break; - } - //碰到障碍,即可立即结束此次指令 - break; - } - } - maxDistance = Math.max(maxDistance, (int) (Math.pow(x, 2) + Math.pow(y, 2))); - } else { - if (value == -2) { - direction = direction - 1 == -1 ? 3 : direction - 1; - } else { - direction = direction + 1 == 4 ? 0 : direction + 1; - } - } - } - return maxDistance; - } -``` -##### 简化 -以上是我第一次写的,可能有点啰嗦,所以主要对恢复现场那进行简化。我们用一个二维数组预设前进的步伐,这样就可以用通用的代码应付各种不同的情景。 -```java - /** - * 简洁的代码 - * @param commands - * @param obstacles - * @return - */ - public int robotSim2(int[] commands, int[][] obstacles) { - Set set = new HashSet<>(); - for (int[] obs : obstacles) { - set.add(obs[0] + "-" + obs[1]); - } - int[][] steps = new int[][]{{0,1}, {1, 0}, {0, -1}, {-1, 0}}; - int x = 0, y = 0, direction = 0, maxDistance = 0; - for (int cmd : commands) { - if (cmd == -2) { - direction = direction - 1 == -1 ? 3 : direction - 1; - } else if (cmd == -1) { - direction =direction + 1 == 4 ? 0 : direction + 1; - } else { - while (cmd-- > 0 && !set.contains((x + steps[direction][0]) - + "-" + (y + steps[direction][1]))) { - x += steps[direction][0]; - y += steps[direction][1]; - } - maxDistance = Math.max(maxDistance, (int) (Math.pow(x, 2) + Math.pow(y, 2))); - } - } - return maxDi -``` - -参考:https://leetcode.com/problems/walking-robot-simulation/discuss/152322/Maximum!-This-is-crazy! \ No newline at end of file diff --git a/_site/leetcode/874-walkingRobotSimulation/hatrick.md b/_site/leetcode/874-walkingRobotSimulation/hatrick.md deleted file mode 100644 index 4d2dddf..0000000 --- a/_site/leetcode/874-walkingRobotSimulation/hatrick.md +++ /dev/null @@ -1,57 +0,0 @@ -**874.模拟机器人行走** ---- -[https://leetcode.com/problems/walking-robot-simulation/](https://leetcode.com/problems/walking-robot-simulation/) - -解决方案 -**思路** -机器人在(0,0)点开始行走,如果(0,0)点有障碍怎么办,这种情况是不管它,开始下一步行走,一旦机器人离开(0,0)点,这个点的障碍物才生效, -后面如果回到此点则不能跨过此障碍.也就是说我们需要先走一步,再去判断这一步是否有效,有效则更新坐标,否则原地不动,继续下一次动作. -至于右转和左转实际就是改变机器人的朝向,起初机器人向北,右转则朝向东,左转则朝向西.不同的朝向,意味着向前一步改变的坐标形式不一样, -如果朝北,则x不动,y递增;如果朝南,则x不动,y递减;如果朝西,则x递减,y不动;如果朝东,则x递增,y不动;也就是在每次实施除了左转右转的动作 -(调整朝向)之外的移动操作时,需要知道机器人的朝向.知道了朝向就往前走呗,遇到了前方障碍物则不要往前,结束此次动作,开始下一次动作. - -在方向的表示层面,用坐标来表示方向不仅可以很好的确定方向之间的关系,而且还能确定此方向上的增量.考虑[0,1],[1,0],[0,-1],[-1,0]分别代表北,东,南,西. -可以看到每个坐标的左边就是它的左转方向,右边的就是它的右边方向,也就是说,给一个方向i(方向向量的索引),则左转的方向是i-1,右转的方向是i+1.等等,那两头呢, -开始的位置不能减1,末端的位置不能加1.把首和尾连接器起来就好了,因此要进行取余操作,长度为4.当然了(0-1)%4没意义,因此改写成((0-1)+4)%4,即左转为(i+3)%4, -这样对中间位置和起始位置都适用.方向确定好了,那坐标增量呢,注意到某一方向上行进一步的增量恰好就是该方向的坐标.以北为例,y方向增量是1,x方向增量是0,也就是(0,1). - -``` -class Solution { - public int robotSim(int[] commands, int[][] obstacles) { - int max = 0; - int[][] dx = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; - int k = 0; - Map map = new HashMap<>(); - for (int i = 0; i < obstacles.length; i++) { - map.put(obstacles[i][0] + "," + obstacles[i][1], true); - } - int p = 0, q = 0; - for (int command : commands) { - if (command == -1) { - k = (k + 1) % 4; - } else if (command == -2) { - k = (k + 4 - 1) % 4; - } else { - int cur[] = dx[k]; - for (int i = 0; i < command; i++) { - if (map.containsKey((p + cur[0]) + "," + (q + cur[1]))) { - break; - } - p += cur[0]; - q += cur[1]; - } - max = Math.max(max, p * p + q * q); - } - } - return max; - } -} - -``` -**复杂度分析** -时间复杂度:O(N+M) N和M分别是两个数组的长度 -空间复杂度:O(N) 使用map所占用的空间 - -**参考资料** - [https://blog.csdn.net/qq_37976559/article/details/82228460](https://blog.csdn.net/qq_37976559/article/details/82228460) - [https://blog.csdn.net/Jeff_Winger/article/details/81544085](https://blog.csdn.net/Jeff_Winger/article/details/81544085) \ No newline at end of file diff --git a/_site/leetcode/874-walkingRobotSimulation/official.md b/_site/leetcode/874-walkingRobotSimulation/official.md deleted file mode 100644 index abb1575..0000000 --- a/_site/leetcode/874-walkingRobotSimulation/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**874. 模拟行走机器人** ---- - -[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) diff --git a/_site/leetcode/875-KokoEatingBananas/sandao.md b/_site/leetcode/875-KokoEatingBananas/sandao.md deleted file mode 100644 index b24609d..0000000 --- a/_site/leetcode/875-KokoEatingBananas/sandao.md +++ /dev/null @@ -1,45 +0,0 @@ -## **875. Koko吃香蕉** - -https://leetcode.com/problems/koko-eating-bananas/ - -解决方案 -**思路** - -假设piles为[A,B,C,D....],最终求出来的值为K,我们可以得出下列公式: -$$ -Math.ceil({A \over K})+Math.ceil({B \over K})+Math.ceil({C \over K})+...<=H -$$ -可以简略为 -$$ -{A \over K}+{B \over K}+{C \over K}+...<=H -$$ -此时我们能大致得出K=(A+B+C+……)/H - -此时的出来的K应该是小于我们的最终值的,递增套入公式,求出消耗时间小于H的K的最大值 - -```java -public static int minEatingSpeed(int[] piles, int H) { - //step1:求出相近值 - double sum = 0; - for (int i: piles){ - sum += (double)i/H; - } - int k = (int)sum; - //step2:从相似值开始往上找,套入公式 - for (;;k++){ - int h = 0; - for (int i: piles){ - double s = Math.ceil((double)i/k); - h += s; - } - //求出了当前情况下需要消耗的时间h,这个时间必须小于规定的H - if (h <= H ){ - return k; - } - } - } -``` - -**参考资料** - -无 \ No newline at end of file diff --git a/_site/leetcode/877-stoneGame/melody-l.md b/_site/leetcode/877-stoneGame/melody-l.md deleted file mode 100644 index c6865ac..0000000 --- a/_site/leetcode/877-stoneGame/melody-l.md +++ /dev/null @@ -1,72 +0,0 @@ -**877. stoneGame** ---- -[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) - -方法一:数学知识 - -因为总堆数是偶数,所以对于先手,其总能保证自己的选择是最优的。所以亚历克斯总是能够赢得比赛。 - -```java -class Solution { - public boolean stoneGame(int[] piles) { - return true; - } -} -``` - -方法二:动态规划 - -从动态规划的角度看问题。 -设stone[i][j]表示从石子堆第i堆到石子堆第j堆,最终亚力克斯比李多出的石子数。由于只能取piles[i]或者piles[j],所以有如下两种情况: -1. 若此时轮到亚力克斯取石子,则此时stone[i][j] = Max{piles[i]+stone[i+1][j], piles[j]+stone[i][j-1]} -2. 若此时轮到李取石子,则此时stone[i][j] = Min{stone[i+1][j]-piles[i], stone[i][j-1]-piles[j]} - -即若(i, j)是亚力克斯,则采用方案1;若(i, j)是李,则采用方案2。 - -而亚力克斯和李是轮着来的,所以奇数轮是亚力克斯,偶数轮是李。根据题意分析可知,若总堆数为Num,则当前轮数为Num-(j-i+1)+1 = Num-j+i。我们可以根据Num-j+i来判断当前的轮数。 - -又,stone[i][j]的值是依赖与stone[i+1][j]或者stone[i][j-1]的,即大堆的计算是依赖于小堆的计算的。这里也可以理解为,初始状态堆的结果是依赖于最终状态堆的结果,所以需要倒着往前推理,先从最后取的那个堆开始计算。因此递推的算法思路是: -计算从size为1的堆数开始计算,按照以上递归式子计算小堆数的结果。然后不断的调高size值,直至size==num。 - -```java - -class Solution { - public boolean stoneGame(int[] piles) { - int num = piles.length; // 石子堆总数 - int[][] stone = new int[num][num]; // 存储从石子堆第i堆到石子堆第j堆,最终亚力克斯比李多出的石子数 - - // 从小堆开始计算,计算到最终大堆的size为止 - // 即计算最终堆数为1,然后到最终堆数为2,依次类推 - for (int size = 1; size <= num; size++) { - // 最终堆数一定的情况下, 从i=0开始,逐步计算所有的情况 - // 假设最终堆数为2,计算所有情况,即逐步计算(0,1),(1,2)... - for (int i = 0; i + size <= num; i++) { - int j = i + size - 1; // 根据当前的size求j所在位置 - if (size == 1) { // size为1特殊处理,条件也可以为i==j - // 特殊处理的原因是:size=1若采用递推式,则数组越界 - // 所以此处采用直接赋值 - // size为1,肯定是最后一轮,由李来取石子 - stone[i][j] = -piles[i]; - } else { - int parity = (num - j + i) % 2; // 求出当前的轮数 - if (parity == 1) {// 奇数轮,由亚力克斯取石子 - stone[i][j] = Math.max(piles[i] + stone[i + 1][j], piles[j] + stone[i][j - 1]); - } else {// 偶数轮,由李取石子 - stone[i][j] = Math.min(stone[i + 1][j] - piles[i], stone[i][j - 1] - piles[j]); - } - } - } - } - - // 判断第一堆到最后一堆,亚力克斯取出的石子数能否比李的多 - return stone[0][num - 1] > 0; - } -} - -``` - ---- - -**参考资料** -* 官方题解: -[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) diff --git a/_site/leetcode/877-stoneGame/official.md b/_site/leetcode/877-stoneGame/official.md deleted file mode 100644 index 7bf8fa0..0000000 --- a/_site/leetcode/877-stoneGame/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**877. 石子游戏** ---- -[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) diff --git a/_site/leetcode/898-BitwiseORsOfSubarrays/official.md b/_site/leetcode/898-BitwiseORsOfSubarrays/official.md deleted file mode 100644 index f3bf952..0000000 --- a/_site/leetcode/898-BitwiseORsOfSubarrays/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**898. 子数组按位或操作** ---- -[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) diff --git a/_site/leetcode/903-ValidPermutationsForDISequence/official.md b/_site/leetcode/903-ValidPermutationsForDISequence/official.md deleted file mode 100644 index 03ba849..0000000 --- a/_site/leetcode/903-ValidPermutationsForDISequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**903. DI 序列的有效排列** ---- -[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) diff --git a/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md b/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md deleted file mode 100644 index d8eb007..0000000 --- a/_site/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md +++ /dev/null @@ -1,57 +0,0 @@ -![903. DI 序列的有效排列](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) - -我们给出 S,一个源于 {'D', 'I'} 的长度为 n 的字符串 。(这些字母代表 “减少” 和 “增加”。) -有效排列 是对整数 {0, 1, ..., n} 的一个排列 P[0], P[1], ..., P[n],使得对所有的 i: - -如果 S[i] == 'D',那么 P[i] > P[i+1],以及; -如果 S[i] == 'I',那么 P[i] < P[i+1]。 -有多少个有效排列?因为答案可能很大,所以请返回你的答案模 10^9 + 7. - - - -示例: - -输入:"DID" -输出:5 -解释: -(0, 1, 2, 3) 的五个有效排列是: -(1, 0, 3, 2) -(2, 0, 3, 1) -(2, 1, 3, 0) -(3, 0, 2, 1) -(3, 1, 2, 0) - -思路: - -为了能进行状态转移,定义dp[i][j]表示:使用1-i这些数字的情况下,以j结尾的合理数组个数,计算dp[i][j]的过程如下: - -1. 如果s[i-2]=='D',说明第i-1位的数要比j大,第i-1位的数据范围是[j+1,i],j在第i位上,所以就把大于等于j的数都往左shift一位(这样2者是等价的,满足A一 -定满足B,满足B一定满足A),这样前i-1位就又是连续的[1,i-1],就可以继续用DP数组的含义。具体到代码就是,k的范围是range(j,i),而不是range(j+1,i) - -2. 如果s[i-2]=='I',数字i不在前i-1位,不用shift - -```py -class Solution: - def numPermsDISequence(self, S): - mod = 10**9 + 7 - n = len(S)+1 #n设置为字符数列长度加1 - dp = [[0 for _ in range(n+1)] for _ in range(n+1)] #设置状态定义 - dp[1][1]=1 - for i in range(2,n+1): - for j in range(1,i+1): - if S[i-2] == 'D': #对于D来说 - for k in range(j,i): #列出状态转移方程 - dp[i][j]+=dp[i-1][k] - dp[i][j]%=mod #得到最后结果 - else: #对于I来说 - for k in range(1,j): - dp[i][j]+=dp[i-1][k] #同样的操作 - dp[i][j]%=mod - return sum(dp[n])%mod -``` -时间复杂度:显然是O(N^3) - -空间复杂度:O(n) - - -![参考](https://blog.csdn.net/zjucor/article/details/82557070) diff --git a/_site/leetcode/920-NumberOfMusicPlaylists/passself.md b/_site/leetcode/920-NumberOfMusicPlaylists/passself.md deleted file mode 100644 index d016bdc..0000000 --- a/_site/leetcode/920-NumberOfMusicPlaylists/passself.md +++ /dev/null @@ -1,48 +0,0 @@ -#920. 播放列表的数量 - -Leetcode 地址 [https://leetcode-cn.com/problems/number-of-music-playlists/](https://leetcode-cn.com/problems/number-of-music-playlists/) - -**题目分析** - -你的音乐播放器里有 N 首不同的歌,在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复)。请你为她按如下规则创建一个播放列表,dp的方式[参考](https://blog.csdn.net/qq_17550379/article/details/82992083)。 - -**思路:** - -可以暴力枚举所有集合,然后对这些集合中相同元素的位置比较,如果 K){ - dp[i][j] = (dp[i][j] + (dp[i-1][j] * (j-K))%mod)%mod; - } - } - } - return (int)dp[L][N]; - } -} -``` -**时间复杂度** O(L*N) - -**空间复杂度** O(L*N) - - diff --git a/_site/leetcode/931-MinimumFallingPathSum/hatrick.md b/_site/leetcode/931-MinimumFallingPathSum/hatrick.md deleted file mode 100644 index 418ab8e..0000000 --- a/_site/leetcode/931-MinimumFallingPathSum/hatrick.md +++ /dev/null @@ -1,53 +0,0 @@ -**931. 下降路径最小和** ---- -[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) - -解决方案 -**思路** -开二维数组,存第一行的所有数,从第二行开始,找每个位置能从上一行哪些位置下降过来,将其中的最小值赋值就可以了。其实就是上面的图,将指向反过来看就可以了: -那么除了两端的特殊情况,其他都是能从3个位置下降过来,有状态转移方程: -dp[i][j] = A[i][j] + Min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]) -注意判定最左边和最右边两种情况就行了。另外,竟然破天荒给了数据范围,当n = 1的时候只有一个下降数组就是本身,这个判定一下就行。 -最终答案要for循环遍历一下最下面一层,看最小值是多少。最小值就是答案。 - -``` -class Solution { - public static int[][] dp; - - public static int Min(int a,int b){ - return a < b ? a : b; - } - - public int minFallingPathSum(int[][] A) { - int len = A[0].length; - if(len == 1) return A[0][0]; - dp = new int[len][len]; - for(int i = 0;i < len;i++){ - dp[0][i] = A[0][i]; - } - for(int i = 1;i < len;i++){ - for(int j = 0;j < len;j++){ - if(j == 0){ - dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j+1]); - }else{ - if(j == len-1){ - dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j-1]); - }else{ - dp[i][j] = A[i][j] + Min(Min(dp[i-1][j],dp[i-1][j+1]),dp[i-1][j-1]); - } - } - } - } - int ans = 20000; - for(int i = 0;i < len;i++){ - ans = Min(ans,dp[len-1][i]); - } - return ans; - } -} - -``` - - -**参考资料** -[https://www.itbox.info/p/139142/leetcode-minimum-falling-path-sum](https://www.itbox.info/p/139142/leetcode-minimum-falling-path-sum) \ No newline at end of file diff --git a/_site/leetcode/931-MinimumFallingPathSum/official.md b/_site/leetcode/931-MinimumFallingPathSum/official.md deleted file mode 100644 index 5dad821..0000000 --- a/_site/leetcode/931-MinimumFallingPathSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**931. 下降路径最小和** ---- -[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) diff --git a/_site/leetcode/935-KnightDialer/official.md b/_site/leetcode/935-KnightDialer/official.md deleted file mode 100644 index 564178f..0000000 --- a/_site/leetcode/935-KnightDialer/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**935. 骑士拨号器** ---- -[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) diff --git a/_site/leetcode/940-DistinctSubsequencesII/official.md b/_site/leetcode/940-DistinctSubsequencesII/official.md deleted file mode 100644 index 4516f1c..0000000 --- a/_site/leetcode/940-DistinctSubsequencesII/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**940. 不同的子序列 II** ---- - -[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) diff --git a/_site/leetcode/943-FindTheShortestSuperstring/official.md b/_site/leetcode/943-FindTheShortestSuperstring/official.md deleted file mode 100644 index e5de8c9..0000000 --- a/_site/leetcode/943-FindTheShortestSuperstring/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**943. 最短超级串** ---- -[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) diff --git a/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md b/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md deleted file mode 100644 index eeff370..0000000 --- a/_site/leetcode/954-ArrayOfDoubledPairs/bigablecat.md +++ /dev/null @@ -1,258 +0,0 @@ -**954. 二倍数对数组** ---- - -[https://leetcode-cn.com/problems/array-of-doubled-pairs/](https://leetcode-cn.com/problems/array-of-doubled-pairs/) - -* 方法1:官方题解(英文) ->排序 + HashMap - -```java - public static boolean canReorderDoubled(int[] A) { - //定义一个HashMap对象count,用于统计每个元素在数组中出现的次数 - Map count = new HashMap(); - //遍历数组A - for (int x : A) - //count.getOrDefault(x, 0) 在count中查找key为x的value - //如果不存在x,说明在count中只出现过一次,value用默认值0 - //取出的value就是元素x的数值在数组A中出现的次数 - //+1计数每次递增 - count.put(x, count.getOrDefault(x, 0) + 1); - - // B = A as Integer[], sorted by absolute value - //定义一个与数组A等长的数组B - Integer[] B = new Integer[A.length]; - //遍历数组A - for (int i = 0; i < A.length; ++i) - //将数组A中的元素依次赋予数组B - B[i] = A[i]; - //完成for循环后,B是数组A的一份拷贝 - //Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进,时间复杂度稳定为O(nlogn) - //第二个参数Comparator.comparingInt(Math::abs)是一个实现了Comparator接口的对象 - //Math::abs是lambda表达式的写法,不使用lambda的等价写法如下 - /** - * Comparator.comparingInt(new ToIntFunction() { - * @Override - * public int applyAsInt(Integer value) { - * return Math.abs(value); - * } - * }); - */ - //在ToIntFunction接口的applyAsInt方法中调用了Math.abs对数组B中的每一个元素取绝对值 - //将数组B的元素根据绝对值大小排序 - Arrays.sort(B, Comparator.comparingInt(Math::abs)); - - //遍历数组B中的元素 - for (int x : B) { - //count.get(x) == 0 乍看令人困惑,实际上需要结合后续代码来理解 - //count.get(x)获取了元素x在count中的计数 - //后续代码对符合题设条件的x进行了计数递减的操作后放回了count - //所以如果出现count.get(x)==0的情况,说明符合条件的x计数已经归零 - //continue继续循环 - if (count.get(x) == 0) continue; - //count.getOrDefault(2 * x, 0)查找2*x的计数 - //如果2*x的计数<= 0,说明数组B中不存在2*x - //数组中没有x的二倍数,不符合题设,返回false - if (count.getOrDefault(2 * x, 0) <= 0) return false; - - //运行到此处,说明数组中存在x的二倍数2*x - //分别将x和2*x在count中的计数递减一次 - count.put(x, count.get(x) - 1); - count.put(2 * x, count.get(2 * x) - 1); - } - // 所有元素的计数都消除为0 - // 说明数组正好可以按照题设将元素两两结合分配为二倍数对 - return true; - } - -``` - -**复杂度分析** - -时间复杂度:O(nlogn), -方法中对数组进行了三次遍历,时间复杂度为3n, -同时使用了一次Arrays.sort为数组排序, -Arrays.sort使用的DualPivotQuickSort在经典快排基础上改进, -时间复杂度稳定为O(nlogn), -总的时间复杂度为nlogn+3n,消去低阶项,最终时间复杂度为O(nlogn) - -空间复杂度:O(n), -Arrays.sort排序方法的空间复杂度是O(n), -使用了HashMap存储数组中所有对象,空间复杂度是O(n), -最终的空间复杂度是O(n) - ---- - -* 方法2:递归 ->递归+HashMap - -```java - - public boolean canReorderDoubled(int[] A) { - //定义一个HashMap对象count,用于统计每个元素在数组中出现的次数 - Map count = new HashMap(); - //遍历数组A - for (int x : A) - //count.getOrDefault(x, 0) 在count中查找key为x的value - //如果不存在x,说明在count中只出现过一次,value用默认值0 - //取出的value就是元素x的数值在数组A中出现的次数 - //+1计数每次递增 - count.put(x, count.getOrDefault(x, 0) + 1); - - //首先对数组中的0进行处理 - //如果数组中0出现的次数不是偶数,说明0无法两两配成对 - //0不能与其他元素结合成符合题设的数对,所以返回false - if (count.getOrDefault(0, 0) % 2 != 0) { - return false; - } else { - //如果0出现偶数次,所有0可以成功配对,直接将0的计数消去 - count.put(0, 0); - } - - //遍历数组A - for (int x : A) { - //如果当前元素计数已经消去,继续循环 - if (count.get(x) == 0) continue; - //将当前元素和存放计数的HashMap对象count传入递归函数findHalfNum - //findHalfNum的作用是向下溯源,为所有小于等于当前元素值的数字配对 - findHalfNum(x, count); - } - - //再次遍历数组 - for (int x : A) { - //如果数组A符合题设,所有元素完成配对,所有计数都应消去为0 - //如果存在计数大于0的元素,说明有不符合题设的元素存在,返回false - if (count.get(x) > 0) { - return false; - } - } - //满足所有条件,返回true - return true; - } - - /** - * 递归函数,找到小于等于参数x的所有二倍数进行配对 - * 对完成配对的元素,消去相应的计数 - * - * @param x - * @param count - * @return - */ - public int findHalfNum(int x, Map count) { - //x % 2 == 0 如果x不能被2整除,说明x不是其他数字的二倍数,直接返回 - //count.getOrDefault(x / 2, 0) > 0 说明存在一个元素,x是这个元素的二倍数 - if (x % 2 == 0 && count.getOrDefault(x / 2, 0) > 0) { - //递归调用当前方法,找到能够与x/2配对的更小元素 - if (findHalfNum(x / 2, count) > 0) { - //count.get(x) - count.get(x / 2)用于判断x和x/2哪个出现的次数更少 - //pairsNum得到的是x和x/2中较少的计数,也就是x和x/2最多能配成几对二倍数 - int pairsNum = (count.get(x) - count.get(x / 2)) < 0 ? (count.get(x)) : count.get(x / 2); - //分别将x和x/2配对,消去公共计数,比如pairsNum是2,说明x和x/2可以配成2对 - count.put(x, count.get(x) - pairsNum); - count.put(x / 2, count.get(x / 2) - pairsNum); - } - } - //最后返回x剩余的计数到调用递归的上一级 - //如果x的计数仍有结余,x可以和x*2继续配对 - return count.get(x); - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -方法中对数组进行了三次遍历,时间复杂度为3n, -方法中使用的递归方法取决于数组的长度,时间复杂度为n, -总的时间复杂度为4n, -最终时间复杂度为O(n) - -空间复杂度:O(n) -本方法中递归的深度取决于数组的长度n, -所以空间复杂度是O(n) - ---- - -* 方法3:网友高效数组方法 ->整数数组 - -```java - - public static boolean canReorderDoubled(int[] A) { - //根据题意,-100000 <= A[i] <= 100000 - //分别创建两个整数数组pos和neg - //pos和neg的长度100001是数组A中可能出现的最大绝对值 - //pos和neg用于计数 - int[] pos = new int[100001]; - int[] neg = new int[100001]; - //遍历数组 - for (int i : A) { - //如果数组i中的元素大于0,对pos进行操作 - //pos[i]找到pos中第i个元素的值,对其做++递增操作 - //因为数组pos中所有元素的初始值都为0 - //所以pos[i]++实际上是对i进行了计数 - if (i > 0) pos[i]++; - //同理,当i<0时,取其正值-i,对neg数组进行操作 - else neg[-i]++; - } - //上述遍历结束后,pos保存了A中所有正值元素的计数,neg保存了A中所有负值元素的计数 - //分别检查pos和neg中的元素是否符合题意 - if (!checkDoublePair(pos)) return false; - if (!checkDoublePair(neg)) return false; - //原数组A中的元素都符合题意,返回true - return true; - } - - public static boolean checkDoublePair(int[] arr) { - //从大到小遍历用于计数的数组 - //在这个数组中,数组下标i对应数组A中的一个元素绝对值 - //arr[i]是i这个值在数组A中出现的次数 - for (int i = arr.length - 1; i >= 0; i--) { - //如果arr[i]>0说明i对应的计数还没有消除为0 - while (arr[i] > 0) { - //i % 2 == 1说明i是奇数,在之前的操作中没有被消除 - //因为数组是从大到小遍历的,i是奇数,只能跟更大的数值配对 - //i是数组A中不符合题意的元素,返回false - if (i % 2 == 1) return false; - //如果i是偶数,该偶数可以与i/2配对 - //arr[i]--将i对应的计数减1 - arr[i]--; - //查看与i配对的i/2的计数 - //arr[i / 2] == 0表示没有i/2与i组成数对 - //所以i不符合题意,返回false - if (arr[i / 2] == 0) return false; - //i/2可以和i配对,将其计数减1 - arr[i / 2]--; - } - } - //数组所有元素遍历完成,都符合题意,返回true - return true; - } - -``` - -**复杂度分析** - -时间复杂度:O(n), -忽略数组A的元素取值范围和数组长度限制, -对数组A一次遍历时间复杂度为n, -用于统计数组A中正数和负数的两个数组pos和neg, -两个数组的长度之和约等于数组A的长度n, -遍历pos和neg的方法虽然用了嵌套循环, -但是遍历过的元素不会重复操作, -所以对数组pos和neg遍历的时间复杂度仍然是O(n), -综上所述,总的时间复杂度是O(n) - -空间复杂度:O(n), -创建了两个数组,虽然根据题意有固定长度, -实际上可以假设这两个数组随着数组A的长度变化, -所以空间复杂度为O(n) - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode.com/problems/array-of-doubled-pairs/solution/](https://leetcode.com/problems/array-of-doubled-pairs/solution/) - -* 网友高效数组方法: -[https://leetcode-cn.com/submissions/api/detail/991/java/27](https://leetcode-cn.com/submissions/api/detail/991/java/27) diff --git a/_site/leetcode/956-TallestBillboard/official.md b/_site/leetcode/956-TallestBillboard/official.md deleted file mode 100644 index d012226..0000000 --- a/_site/leetcode/956-TallestBillboard/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**956. 最高的广告牌** ---- -[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) diff --git a/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md b/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md deleted file mode 100644 index 11a9258..0000000 --- a/_site/leetcode/964-LeastOperatorsToExpressNumber/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**964. 表示数字的最少运算符** ---- -[https://leetcode-cn.com/problems/least-operators-to-express-number/](https://leetcode-cn.com/problems/least-operators-to-express-number/) diff --git a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md deleted file mode 100644 index 1240017..0000000 --- a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md +++ /dev/null @@ -1,89 +0,0 @@ -**967. 连续差相同的数字** ---- -[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) - -* 官方DP题解 - -```java - - /** - * https://leetcode-cn.com/articles/numbers-with-same-consecutive-differences/ - * 官方题解 - * - * @param N - * @param K - * @return - */ - public static int[] numsSameConsecDiff(int N, int K) { - //新建一个HashSet对象cur,用于存储数字1到9 - Set cur = new HashSet(); - //根据题意1 <= N <= 9 - //将数字1到9存入HashSet对象cur中 - for (int i = 1; i <= 9; ++i) - cur.add(i); - - //对1到N-1的每一个数字进行相同的操作 - for (int steps = 1; steps <= N - 1; ++steps) { - //另新建一个HashSet对象cur2,用于存储最新结果并排重 - Set cur2 = new HashSet(); - //遍历cur中的元素 - for (int x : cur) { - // x % 10 得到 x的个位数字d - int d = x % 10; - - //根据题意,d与下一位数字的差的绝对值为K - //那么有两种情况: - // 如果d比下一位数字大,有d - K >= 0 - // 如果d比下一位数字小,有d + K <= 9 - - //d - K >= 0表示d比下一位数字大的情况 - if (d - K >= 0) { - // (d - K)得到下一位数字 - // 10 * x 将x扩大一个10进制,(d - K)作为10 * x的个位,相加后得到新数字 - cur2.add(10 * x + (d - K)); - } - - //d + K <= 9表示d比下一位数字小的情况 - if (d + K <= 9) { - // 10 * x 将x扩大一个10进制,(d + K)作为10 * x的个位,相加后得到新数字 - cur2.add(10 * x + (d + K)); - } - } - //将cur指向最新结果cur2 - cur = cur2; - } - //如果N为1,根据题意,单独一个数字0是有效的 - if (N == 1) - //将0加入HashSet对象cur - cur.add(0); - //创建一个与HashSet对象cur同样大小的int数组 - int[] ans = new int[cur.size()]; - //定义一个整数t作为数组ans下标 - int t = 0; - //遍历cur中的元素 - for (int x : cur) - //将cur的值存入数组ans - ans[t++] = x; - //返回数组ans - return ans; - } - -``` - - -**复杂度分析** - -时间复杂度:O(2^N) -每一位数字都有2种可能,N个数字有2^N种可能 - -空间复杂度:O(2^N) -用HashSet开辟了额外的空间, -每一位数字都有2种可能, -HashSet对象的空间最大为2^N - ---- - -**参考资料** - -* 英文官方题解: -[https://leetcode-cn.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) diff --git a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md b/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md deleted file mode 100644 index ff1d89a..0000000 --- a/_site/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**967. 连续差相同的数字** ---- -[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) diff --git a/_site/leetcode/968-BinaryTreeCameras/official.md b/_site/leetcode/968-BinaryTreeCameras/official.md deleted file mode 100644 index 89ff0ee..0000000 --- a/_site/leetcode/968-BinaryTreeCameras/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**968. 监控二叉树** ---- -[https://leetcode-cn.com/problems/binary-tree-cameras/](https://leetcode-cn.com/problems/binary-tree-cameras/) diff --git a/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md b/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md deleted file mode 100644 index 1a4e5c3..0000000 --- a/_site/leetcode/968-BinaryTreeCameras/zengdiqing1994.md +++ /dev/null @@ -1,55 +0,0 @@ -**968. Binary Tree Cameras** - -[Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/) - -**思路:** - -最小点覆盖和最大独立集都比较简单,只有2个状态,分别是标记和不标记 - -对于最小支配集,每个子树3个状态: - -状态0:根被标记,整个子树都被覆盖的最小标记数目 - -状态1:根未被标记,整个子树被覆盖,且至少有一个子节点被标记 - -状态2:根未被标记,整个子树被覆盖,且没有子节点被标记 - -每个状态如何递归: - -1.状态0:每个子树的3个状态的最小值之和+1: - -dp[root][0] = min(dp[root.left])+min(dp[root.right])+1 - -2.状态1:【如果根没有孩子,dp[root][1]为INF】根未被标记时子树不可以是状态3。所以是前两个状态取最小值之和。但是如果每个子节点的最小值都是状态1,那么就 -和根是状态1的假设矛盾了。所以要挑一个节点取状态0,这必然会使结果增加,那么选增加得最少的那个,即dp[u][0]-dp[u][1]最小的那个指定为状态0。 - -不可能是状态3是因为如果根没有标记,儿子没有标记,根还被覆盖了,可能是根的父亲标记了,但是如果孙子也没有标记,那么儿子就不可能被标记,矛盾。 - -2.状态2:此时子树只可能是状态1。 - -dp[root][2] = dp[root.left][1]+dp[root.right][1] - -最后取根节点的状态1和状态0里最小的那个 - -```py -class Solution: - def minCameraCover(self, root: TreeNode) -> int: - INF = 0x7fffffff - def solve(root): - if root.left and root.right: - left = solve(root.left) #左右子树递归 - right = solve(root.right) - return min(left)+min(right)+1, min(left[0]+min(right[:-1]), min(left[:-1])+right[0]),left[1]+right[1] - res = None - if root.left: #求解满足状态0,1的情况 - res = solve(root.left) - elif root.right: - res = solve(root.right) - if res!=None: - return min(res)+1, res[0], res[1] - return 1, INF, 0 - return min(solve(root)[:-1]) -``` -时间复杂度是O(nlogn) - -[参考](https://blog.csdn.net/lemonmillie/article/details/87825550) diff --git a/_site/leetcode/975-OddEvenJump/official.md b/_site/leetcode/975-OddEvenJump/official.md deleted file mode 100644 index 571d86a..0000000 --- a/_site/leetcode/975-OddEvenJump/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**975. 奇偶跳** ---- -[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) diff --git a/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md b/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md deleted file mode 100644 index 2df8fdd..0000000 --- a/_site/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**982. 按位与为零的三元组** ---- -[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) diff --git a/_site/leetcode/sample/concise.md b/_site/leetcode/sample/concise.md deleted file mode 100644 index b73fe5a..0000000 --- a/_site/leetcode/sample/concise.md +++ /dev/null @@ -1,40 +0,0 @@ ->精简版答案示例,摘自本题的leetCode官方题解 - -**141. 环形链表** ---- -[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) - -方法一:哈希表 -```java - -public boolean hasCycle(ListNode head) { - //新建一个set用于存储从链表中遍历出的结点 - Set nodesSeen = new HashSet<>(); - //如果当前结点不为空,循环继续 - while (head != null) { - //set中如果已经存在当前结点,说明该链表是环形链表,返回true - if (nodesSeen.contains(head)) { - return true; - } else { - //否则将当前结点添加到set - nodesSeen.add(head); - } - //将下一个结点赋值给结点缓存head - head = head.next; - } - //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false - return false; -} - -``` - ---- - - -**参考资料** - -* 本题leetCode官方题解: -[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/sample/concise.png b/_site/leetcode/sample/concise.png deleted file mode 100644 index d584666634ff45e555643b44aa878badc3058cf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85605 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 N@>7i`rH`y${|`S@`7r详尽版答案示例,摘自本题的leetCode官方题解 - -**141. 环形链表** ---- -[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) - -摘要 - -本文适用于初学者。 - -它涉及了以下几个概念:链表,哈希表和双指针。 - -解决方案 - -方法一:哈希表 - -思路 - -我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。 - -常用的方法是使用哈希表。 - -算法 - -我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。 - -如果当前结点为空结点 null(即已检测到链表尾部的下一个结点),那么我们已经遍历完整个链表,并且该链表不是环形链表。 - -如果当前结点的引用已经存在于哈希表中,那么返回 true(即该链表为环形链表)。 - - -```java - -public boolean hasCycle(ListNode head) { - //新建一个set用于存储从链表中遍历出的结点 - Set nodesSeen = new HashSet<>(); - //如果当前结点不为空,循环继续 - while (head != null) { - //set中如果已经存在当前结点,说明该链表是环形链表,返回true - if (nodesSeen.contains(head)) { - return true; - } else { - //否则将当前结点添加到set - nodesSeen.add(head); - } - //将下一个结点赋值给结点缓存head - head = head.next; - } - //链表所有结点遍历结束没有在set里找到重复结点,说明当前链表没有环,返回false - return false; -} - -``` - -**复杂度分析** - -时间复杂度: -O(n), 对于含有 n个元素的链表,我们访问每个元素最多一次。 添加一个结点到哈希表中只需要花费 O(1) 的时间。 - -空间复杂度: -O(n), 空间取决于添加到哈希表中的元素数目,最多可以添加 n 个元素。 - ---- - - -**参考资料** - -* 本题leetCode官方题解: -[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) - -* 本题leetCode英文官方题解: -[https://leetcode.com/articles/linked-list-cycle/](https://leetcode.com/articles/linked-list-cycle/) \ No newline at end of file diff --git a/_site/leetcode/sample/full.png b/_site/leetcode/sample/full.png deleted file mode 100644 index abee59c76548793d7b3e85c02813f5639ffb5d39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166160 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

N{JVp7wyk%=XLIZ!tey*=Z)dk5 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

>+CNIzWj=%kC&7^YYw*DJ!qVEUG zh=Eee#?Oe?jdL8#&xCw*azyNKJcYs0S6WW%BF_Cimpy`;YiRRnp>Du8-&?TDgfw4K zskEs`f^knA=5ok~JPq3&7W4`8z}e-O^m;Y*eqsan|3vLxHQ&ncb#r=C&3UiVVrF}v zetcy?Va=D~R=J{_g|GH?oje{+J&%Yj`gqQu(zD^{QF7~_!#f8PWx?#rL#9nf8bf>^KCM5%vS-Q;nqpo> zQxMj^7*g(&?fIS=bg}2i6YHut7NXx+m){R~*8#nsf^WEC_`E-qoVXU_389rBf4hu$ z*-Sp`Z|g3Q?pjmWu;e5KPGfssYxBvz&5*xnS9Bt_MGAT(k7Bfw7}W#?f7i*gb#Us4 zQ(!meuREDC&xotEx3#Q9qMVKoHpn_-tzXot3r`!=Z&b+-U%1Wpi#s^<^O16?Cd|v^ zc6rT{!wi+XlRkTocD?Y+1&aj-yB7&w;qpgU$Vacsf8>|@#y(_!kn>F#kHz1=!s58> zPSh8!K7E7ENpk)Zr|R% zL{&X5iFPH1`IFrQ(Z3^)BG(X}y-SUcN4_-U?(jDVF8dB+oCzF{zx>4m=Czl7Zk^O- zxRFuJ93>m&q_WG%h2ptb)!9(CR%3#ilx3=&v|?TT2w4q@yq9-yR@2Q+Z& zCF^bpD`}Iu6fT$21Z=vTd6rUj!S-N1Zcd?{X2XCGw(Vh-?MWf-XFgFfxZ;V$ev$3L z$-2#M8x-_Hx<{+MDBAa8TB*WH&URq&LDKl&K|@G^0%11YY77>OTkeBu-a(Dixun7c zT0dkuI6a#VspmpIp#>~nCXe`8w>Y<75w;>XgZ7$3m41X8}KqyvbMqoyr`+ueMXhBW>_WyW{>q4uu(vXg=B zi<4kQo$l7fQtzqJ z1{1q>J;+!;bIg7sw$5()Vc67=2a_uJE2%Sn@X^C?lOys1(&C7mzm_-ESwZgSV$w!0^07MI0U9@OLEeQQJBe{YhA!AgdHO82ecu&?li-+vhz zvEnvy2ujKcD76;zYFoEI4gADa^DOKO+9lxDaQmluvUa?7y%H1u->qTma6zoV4@F-p7PoOV4gZjZosw}2u9!n_o0MAi z@8%b|eZ&KDa!HxlKM`C(aiydJs4~pMbZ*3c*{o+&OKTQ@IZTFqa4T(y-7m0C6OVIg zS(*jUa)I$5*#&;6HJ$>G5ege5I4l5o_#Cq&PBSG80*D`Sr32B;;Nm6@m3%mr}bZH4Ayf--8h8}5S+`=V0+4jGZ;9cQpe{5_P1}hV4a&WRZOijc> z6nF<6(Q!u#rZ2t?q7+YKO7ZsIg%I^`H+W*Nfs?2`QcXo%vyc2)%!<-rz*c@B-j+#;x8IHWP;V1#zA9KP^Hb_51 zwLaDX^Rn1)3^VS3n&qp!mwA;HB>KA4y8q;%ABJ^DSN=qmvX6dV4=1_jZI@!_V6VCk zVIH>VCgo!&J*MVX_0bs!!y6Nh-Ak)}_LlKR`7Q@?-5k}qLbAk6g*oeBf`X4`hNI1b z+P;$5tt>;aHu17jVH>iThy6_TQr?VD{LABGTjS!0fpH^Ade&Y_X+gB&-D`-|+i&lA z7YZgghProZ=u7qOc?57*#H2Awgtn2=&gviX_k{JXFSf^z)y4xZj0N;) zAW)$nPX6K1^y%s1I{|!l(`Qrf<9GV?OGJ<8L4PL2Cvy%0AwhGvi$@B}*~4}5k=we1 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 Date: Sun, 24 Mar 2019 21:57:56 +0800 Subject: [PATCH 19/66] update --- leetcode/075-SortColors/bigablecat.md | 2 +- leetcode/167-TwoSumII/README.md | 2 +- leetcode/167-TwoSumII/bigablecat.md | 3 +- .../215-KthLargestElementInAnArray/README.md | 2 +- .../bigablecat.md | 2 +- leetcode/347-TopKFrequentElements/README.md | 80 +++---------------- .../347-TopKFrequentElements/bigablecat.md | 80 ++++++++++++++++--- 7 files changed, 85 insertions(+), 86 deletions(-) diff --git a/leetcode/075-SortColors/bigablecat.md b/leetcode/075-SortColors/bigablecat.md index 1daac68..3314af2 100644 --- a/leetcode/075-SortColors/bigablecat.md +++ b/leetcode/075-SortColors/bigablecat.md @@ -59,7 +59,7 @@ **复杂度分析** 空间复杂度:O(1), -只定义了3个整型变量,没有使用更多额外空间,空间复杂读是O(1) +只定义了3个整型变量,没有使用更多额外空间,空间复杂度是O(1) **参考资料** diff --git a/leetcode/167-TwoSumII/README.md b/leetcode/167-TwoSumII/README.md index 4650775..af55370 100644 --- a/leetcode/167-TwoSumII/README.md +++ b/leetcode/167-TwoSumII/README.md @@ -1,7 +1,7 @@ **167. 两数之和 II - 输入有序数组** --- -[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 diff --git a/leetcode/167-TwoSumII/bigablecat.md b/leetcode/167-TwoSumII/bigablecat.md index 8565565..edda8a8 100644 --- a/leetcode/167-TwoSumII/bigablecat.md +++ b/leetcode/167-TwoSumII/bigablecat.md @@ -1,8 +1,7 @@ **167. 两数之和 II - 输入有序数组** --- -[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/) - +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) * 双指针法 diff --git a/leetcode/215-KthLargestElementInAnArray/README.md b/leetcode/215-KthLargestElementInAnArray/README.md index a879f7d..98539c3 100644 --- a/leetcode/215-KthLargestElementInAnArray/README.md +++ b/leetcode/215-KthLargestElementInAnArray/README.md @@ -1,4 +1,4 @@ -**找数组中第K大的数** +**215. 找数组中第K大的数** --- [https://leetcode-cn.com/problems/kth-largest-element-in-an-array/](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) diff --git a/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/leetcode/215-KthLargestElementInAnArray/bigablecat.md index 1202190..217ec4c 100644 --- a/leetcode/215-KthLargestElementInAnArray/bigablecat.md +++ b/leetcode/215-KthLargestElementInAnArray/bigablecat.md @@ -1,4 +1,4 @@ -**找数组中第K大的数** +**215. 找数组中第K大的数** --- [https://leetcode-cn.com/problems/kth-largest-element-in-an-array/](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) diff --git a/leetcode/347-TopKFrequentElements/README.md b/leetcode/347-TopKFrequentElements/README.md index 20bece1..5935865 100644 --- a/leetcode/347-TopKFrequentElements/README.md +++ b/leetcode/347-TopKFrequentElements/README.md @@ -1,77 +1,19 @@ -**前K个高频元素** +**347. 前K个高频元素** --- [https://leetcode-cn.com/problems/top-k-frequent-elements/](https://leetcode-cn.com/problems/top-k-frequent-elements/) -* 网友高票答案(桶排序) +给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 -```java - /** - * https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort - * 网友高票答案:桶排序 - * - * @param nums - * @param k - * @return - */ - public static List topKFrequent(int[] nums, int k) { - //定义一个整型列表的数组bucket,长度是数组nums长度+1 - //下面会解释为什么bucket的长度要在nums.length的基础上加1 - List[] bucket = new List[nums.length + 1]; - //定义一个map用于存储数组中元素出现的频率 - Map frequencyMap = new HashMap<>(); - // 遍历数组nums - for (int n : nums) { - //将每个数字出现的频率存入map - //frequencyMap.getOrDefault(n, 0)表示通过当前整数n,从frequencyMap中value,如果value为空就使用默认值0 - //frequencyMap.getOrDefault(n, 0)+1表示当前元素n每出现一次,在现有频率的基础上加1 - frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); - } +**示例 1:** - //遍历frequencyMap的所有键值 - //这个键值包括了nums中的所有元素,其中重复的元素都合并为一个值 - for (int key : frequencyMap.keySet()) { - //获取当前键值key对应的频率frequency - int frequency = frequencyMap.get(key); - //获取bucket中frequency对应位置的分桶 - if (bucket[frequency] == null) { - //如果当前位置的分桶为空,新建一个ArrayList对象 - bucket[frequency] = new ArrayList<>(); - } - // 向当前分桶添加Map中的key值 - // key对应nums中的元素,且经过map过滤,key是去重的 - // frequency对应key在nums中出现的频率 - // 如key=2,frequency=3,即nums中的元素2,总共出现了3次 - // 在bucket[frequency]这个分桶中,保存了所有频率为frequency的key值 - bucket[frequency].add(key); - } - - //新建一个整型列表res用于存储返回结果 - List res = new ArrayList<>(); - - //从大往小遍历bucket - //res.size() < k限制了出现频率前k高的元素 - for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { - //从bucket的当前位置pos取出分桶 - if (bucket[pos] != null) { - //bucket[pos]得到一个由nums中所有频率为pos的元素组成的列表 - //res.addAll将列表中的所有元素加入res中 - res.addAll(bucket[pos]); - } - } - //返回最终结果 - return res; - } +``` +输入: nums = [1,1,1,2,2,3], k = 2 +输出: [1,2] ``` -**复杂度分析** - -时间复杂度:O(n), -方法内的三个循环都在n的复杂度内 - -空间复杂度:O(n), -建立了一个桶,占用空间为n+1 - -**参考资料** +**示例 2:** -* 网友高效答案: -[https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort](https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort) +``` +输入: nums = [1], k = 1 +输出: [1] +``` diff --git a/leetcode/347-TopKFrequentElements/bigablecat.md b/leetcode/347-TopKFrequentElements/bigablecat.md index 85b087e..8f17cd1 100644 --- a/leetcode/347-TopKFrequentElements/bigablecat.md +++ b/leetcode/347-TopKFrequentElements/bigablecat.md @@ -1,19 +1,77 @@ -**前K个高频元素** +**347. 前K个高频元素** --- [https://leetcode-cn.com/problems/top-k-frequent-elements/](https://leetcode-cn.com/problems/top-k-frequent-elements/) -给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 +* 网友高票答案(桶排序) -**示例 1:** +```java + /** + * https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort + * 网友高票答案:桶排序 + * + * @param nums + * @param k + * @return + */ + public static List topKFrequent(int[] nums, int k) { + //定义一个整型列表的数组bucket,长度是数组nums长度+1 + //下面会解释为什么bucket的长度要在nums.length的基础上加1 + List[] bucket = new List[nums.length + 1]; + //定义一个map用于存储数组中元素出现的频率 + Map frequencyMap = new HashMap<>(); + // 遍历数组nums + for (int n : nums) { + //将每个数字出现的频率存入map + //frequencyMap.getOrDefault(n, 0)表示通过当前整数n,从frequencyMap中value,如果value为空就使用默认值0 + //frequencyMap.getOrDefault(n, 0)+1表示当前元素n每出现一次,在现有频率的基础上加1 + frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); + } -``` -输入: nums = [1,1,1,2,2,3], k = 2 -输出: [1,2] -``` + //遍历frequencyMap的所有键值 + //这个键值包括了nums中的所有元素,其中重复的元素都合并为一个值 + for (int key : frequencyMap.keySet()) { + //获取当前键值key对应的频率frequency + int frequency = frequencyMap.get(key); + //获取bucket中frequency对应位置的分桶 + if (bucket[frequency] == null) { + //如果当前位置的分桶为空,新建一个ArrayList对象 + bucket[frequency] = new ArrayList<>(); + } + // 向当前分桶添加Map中的key值 + // key对应nums中的元素,且经过map过滤,key是去重的 + // frequency对应key在nums中出现的频率 + // 如key=2,frequency=3,即nums中的元素2,总共出现了3次 + // 在bucket[frequency]这个分桶中,保存了所有频率为frequency的key值 + bucket[frequency].add(key); + } -**示例 2:** + //新建一个整型列表res用于存储返回结果 + List res = new ArrayList<>(); + //从大往小遍历bucket + //res.size() < k限制了出现频率前k高的元素 + for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { + //从bucket的当前位置pos取出分桶 + if (bucket[pos] != null) { + //bucket[pos]得到一个由nums中所有频率为pos的元素组成的列表 + //res.addAll将列表中的所有元素加入res中 + res.addAll(bucket[pos]); + } + } + //返回最终结果 + return res; + } ``` -输入: nums = [1], k = 1 -输出: [1] -``` + +**复杂度分析** + +时间复杂度:O(n), +方法内的三个循环都在n的复杂度内 + +空间复杂度:O(n), +建立了一个桶,占用空间为n+1 + +**参考资料** + +* 网友高效答案: +[https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort](https://leetcode.com/problems/top-k-frequent-elements/discuss/81602/Java-O(n)-Solution-Bucket-Sort) From a7241f6b5fb1f259b05636a0a28571a78b02e04d Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 24 Mar 2019 22:00:42 +0800 Subject: [PATCH 20/66] update --- leetcode/167-TwoSumII/README.md | 2 +- leetcode/215-KthLargestElementInAnArray/bigablecat.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/leetcode/167-TwoSumII/README.md b/leetcode/167-TwoSumII/README.md index af55370..b8d50eb 100644 --- a/leetcode/167-TwoSumII/README.md +++ b/leetcode/167-TwoSumII/README.md @@ -1,7 +1,7 @@ **167. 两数之和 II - 输入有序数组** --- -[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) +[https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 diff --git a/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/leetcode/215-KthLargestElementInAnArray/bigablecat.md index 217ec4c..6d6a52c 100644 --- a/leetcode/215-KthLargestElementInAnArray/bigablecat.md +++ b/leetcode/215-KthLargestElementInAnArray/bigablecat.md @@ -132,7 +132,7 @@ **复杂度分析** 空间复杂度:O(1), -没有使用额外空间,空间复杂读是O(1) +没有使用额外空间,空间复杂度是O(1) **参考资料** From 019f2a2b6b191c3f92e4475e4f5d9717f8e95982 Mon Sep 17 00:00:00 2001 From: maoyanting Date: Mon, 25 Mar 2019 14:51:32 +0800 Subject: [PATCH 21/66] sandao --- leetcode/091-DecodeWays/sandao.md | 88 +++++++++++++ .../sandao.md | 118 ++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 leetcode/091-DecodeWays/sandao.md create mode 100644 leetcode/557-Reverse Words in a String III/sandao.md diff --git a/leetcode/091-DecodeWays/sandao.md b/leetcode/091-DecodeWays/sandao.md new file mode 100644 index 0000000..caea69f --- /dev/null +++ b/leetcode/091-DecodeWays/sandao.md @@ -0,0 +1,88 @@ +## **91. Decode Ways** + +https://leetcode.com/problems/decode-ways/ + + + +思路:这个边界条件比较多,然后需要储存已经计算过的值。 + +```java +class Solution { + public int numDecodings(String s) { + if (s.startsWith("0") || s.length() == 0) { + return 0; + } + //用于储存已算出值的数组。 + int[] cc = new int[s.length()+1]; + //先填充 + Arrays.fill(cc, -1); + return numDecodings2(s,cc); + } + private static int numDecodings2(String s,int[] cc) { + //首先查询这个值是否算出 + if (cc[s.length()] != -1) { + return cc[s.length()]; + } + int length = s.length(); + if (length == 2) { + //拼接剩下的两位数 + if (Integer.valueOf(s) > 26) { + //大于26,且个位数为0,则没有对应的字母,拆开来也没有,就返回0 + if (0 == Integer.valueOf(s.substring(1,2))) { + return 0; + } + //大于26,个位数不为0,则虽然没有对应的字母,但是可以拆开来当作两个一位数字,返回1 + return 1; + } + //小于26,但是个位数为0,则有对应的字母,但是不可以拆开来当作两个一位数字,返回1 + if (0 == Integer.valueOf(s.substring(1,2))) { + return 1; + } + //小于26,个位数不为0,则有对应的字母,也可以拆开来当作两个一位数字,返回2 + return 2; + } + if (length == 1) { + //只剩下一个数字,如果是0则返回0; + if ("0".equals(s)) { + return 0; + } + return 1; + } + //对于字符串"123456",可以分成两种情况 + //R["123456"] = R["12345"]* R["6"] +R["1234"]*R["56"] + String sDel1 = s.substring(0,length-1); + String sDel2 = sDel1.substring(0,sDel1.length()-1); + //取两位数的情况(注意这里的两位数是不可拆的来计算) + int count2 = 1; + String sum = s.substring(length-2); + if (Integer.valueOf(sum) > 26) { + count2 = 0; + } + if (0 == Integer.valueOf(s.substring(length-2,length-1))) { + count2 = 0; + } + //取一位数的情况 + int count1 = 1; + if ("0".equals(s.substring(length-1))) { + count1 = 0; + } + //向下计算 + int sDel2Count; + if (cc[length-2] != -1) { + sDel2Count = cc[length-2]; + } else { + sDel2Count = numDecodings2(sDel2,cc); + cc[length-2] = sDel2Count; + } + int sDel1Count = numDecodings2(sDel1,cc); + + return sDel1Count * count1 + count2 * sDel2Count; + } +} +``` + + + +**参考资料** + +无 \ No newline at end of file diff --git a/leetcode/557-Reverse Words in a String III/sandao.md b/leetcode/557-Reverse Words in a String III/sandao.md new file mode 100644 index 0000000..367bb1b --- /dev/null +++ b/leetcode/557-Reverse Words in a String III/sandao.md @@ -0,0 +1,118 @@ +## **557. Reverse Words in a String III** + +https://leetcode.com/problems/reverse-words-in-a-string-iii/ + + + +方法一:字符串按照空格分成数组,然后对每个数组内的字符串反向,最后再拼成一个字符串 + +```java +class Solution { + public String reverseWords(String s) { + String[] sList = s.split(" "); + StringBuilder sb = new StringBuilder(); + for (String ss : sList) { + sb.append(getFan(ss)).append(" "); + } + return sb.toString().substring(0,sb.length()-1); + } + //获取反向的字符串 + private static String getFan(String a) { + String[] s = a.split(""); + StringBuilder sb = new StringBuilder(); + for (int i = s.length - 1; i > -1; i--) { + sb.append(s[i]); + } + return sb.toString(); + } +} +``` + +方法二: + +依旧先对字符串按照空格分成数组,然后从头开始算,指针指向第一个字符串的尾部,往前遍历直到这个字符串的头部,然后指针再指向第二个字符串的尾部,再往前便利,依此循环,直到遍历完全部的字符串。 + +```java +class Solution { + public String reverseWords(String s) { + if (s.length() == 0){ + return s; + } + //首先分组 + String[] sList = s.split(" "); + StringBuilder sb = new StringBuilder(); + //指针的位置 + int count = sList[0].length(); + //此时为第一个单词 + int currentStringNum = 0; + //第一个单词的长度 + int currentStringLength = count; + for (int i = 0;;i++){ + //i增加,指针count-i-1则在往前移动 + sb.append(s.charAt(count-i-1)); + if (currentStringLength-1 == i){ + //一个单词的字符已经添加完毕 + currentStringNum++; + if (currentStringNum == sList.length){ + return sb.toString(); + } + //获取当前单词的长度 + currentStringLength = sList[currentStringNum].length(); + //补上空格 + sb.append(" "); + //加上之前已有的长度,和空格的一个长度,指针指向当前单词的最后一个值 + count+=(currentStringLength+1); + //i重置 + i = -1; + } + } + } +} +``` + +方法三: + +在之前的基础上优化,其实分组就是为了获取每个空格之间的长度,使用indexOf也可以达到这种效果 + +```java +class Solution { + public String reverseWords(String s) { + if (s.length() == 0){ + return s; + } + StringBuilder sb = new StringBuilder(); + //indexOf如果没有对应的字符串的时候会返回-1 + int count = s.indexOf(" "); + if (count < 0){ + count = s.length(); + } + //当前单词的长度 + int currentStringLength = count; + for (int i = 0;;i++){ + sb.append(s.charAt(count-i-1)); + if (currentStringLength-1 == i){ + if (count == s.length()){ + return sb.toString(); + } + //查找下一个空格所在的位置 + int newCount=s.indexOf(" ",count+1); + if (newCount < 0){ + newCount = s.length(); + } + //下一个单词的长度 + currentStringLength = newCount-count-1; + //移动指针 + count = newCount; + //添加空格 + sb.append(" "); + i = -1; + }} + } +} +``` + + + +**参考资料** + +无 \ No newline at end of file From 473fef9fa07e468f5f42ab76cf93d11bcc8d1f86 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 26 Mar 2019 22:17:50 +0800 Subject: [PATCH 22/66] Create zengdiqing1994.md --- .../260-SingleNumberIII/zengdiqing1994.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 leetcode/260-SingleNumberIII/zengdiqing1994.md diff --git a/leetcode/260-SingleNumberIII/zengdiqing1994.md b/leetcode/260-SingleNumberIII/zengdiqing1994.md new file mode 100644 index 0000000..5ada2b5 --- /dev/null +++ b/leetcode/260-SingleNumberIII/zengdiqing1994.md @@ -0,0 +1,49 @@ +给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。 + +示例 : + +输入: [1,2,1,3,2,5] +输出: [3,5] + +思路: + +如果使用O(1)的空间复杂度要怎么做呢?我们很快想到通过位运算。直接对每个nums的元素做xor,最后我们得到的结果就是两个单一元素a和b的xor。因为a和b不相同, +所以它们之间必定会存在至少一个bit不同,也就是说a xor b的结果中至少有一个bit是1。我们从这么多的bit中挑选出一个,然后其余位置为0,那我们就构成了这样的 +一种mask。例如00...100 + +这样的mask和a和b中元素与元素的话,必定有一个结果是0,另外一个结果是mask,这样我们就将a和b给分开了。那么问题就变成了,怎么构建这样的mask?我们使用一个 +简单的策略就是a xor b的最右边的1作为flag。那要怎么得到最右边的1呢?这就涉及到补码的概念,我们知道负数在计算机中使用补码表示的,也就是反码加1。 + +num:5 +原码:0101 +反码:1010 +--------- +num:-5 +补码:1011 + +那么我们通过num&-num就可以取出最右边的1了。现在我们就可以遍历nums然后,通过mask就可以判断nums中的那些元素的右边第一位是1(根据上面例子),我们将这些数 +分成一类,将右边第一位是1的数分成为另外一类,并且我们的a和b也就被分到不同的组中。这两组数字的个数不一定相同,但是最后一定是可以相互通过xor消除,最后只剩 +a和b。 + +```py +from operator import xor +class Solution(object): + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + mask = 0 + for i in nums: #遍历整个数组,求xor的结果 + mask ^= i + mask &= -mask #取出最右的1 + result = [0]*2 + for num in nums: + if num & mask: #开始遍历得到需要的结果 + result[0] ^= num + else: + result[1] ^= num + return result +``` +时间复杂度O(n) +空间复杂度O(1) From c619e9117d7ae11a7e55ec1f79e6bacedfe557d5 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Wed, 27 Mar 2019 09:18:58 +0800 Subject: [PATCH 23/66] Create zengdiqing1994.md --- leetcode/504-Base7/zengdiqing1994.md | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 leetcode/504-Base7/zengdiqing1994.md diff --git a/leetcode/504-Base7/zengdiqing1994.md b/leetcode/504-Base7/zengdiqing1994.md new file mode 100644 index 0000000..667b89c --- /dev/null +++ b/leetcode/504-Base7/zengdiqing1994.md @@ -0,0 +1,35 @@ +给定一个整数,将其转化为7进制,并以字符串形式输出。 + +示例 1: + +输入: 100 +输出: "202" +示例 2: + +输入: -7 +输出: "-10" +注意: 输入范围是 [-1e7, 1e7] 。 + +思路: + +直接把获取到的数据的模对7取余,再加在后面成为字符串。每次取余之后都要除以7.注意最后要判断正负 + +```py +class Solution(object): + def convertToBase7(self, num): + """ + :type num: int + :rtype: str + """ + if num == 0: + return "0" + else: + res = str() + n = abs(num) + while n: + res = str(n%7) + res + n = n//7 + return res if num>0 else '-'+res +``` +时间复杂度:O(n) +空间复杂度:O(n) From 582f9a11c0e0785485f70cb2de1589c593356500 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Wed, 27 Mar 2019 09:46:25 +0800 Subject: [PATCH 24/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md diff --git a/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md b/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md new file mode 100644 index 0000000..c6caa9e --- /dev/null +++ b/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md @@ -0,0 +1,43 @@ +给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。 + +例如: + +输入: +[1,2,3] + +输出: +2 + +说明: +只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1): + +[1,2,3] => [2,2,3] => [2,2,2] + +思路: + +本题主要是通过查找中间位置的数,然后进行移动步数,最后将移动步数全部求和.先排序,把中间位置的数拿出来,然后计算数组中每个数字与中间数的差值的绝对值 +相加即可 + +```py +class Solution(object): + def minMoves2(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + temp = [] + nums.sort() + mid = len(nums)/2 #二分 + mid_num = nums[mid] #取出中间的数 + nums.remove(nums[mid]) + for i in nums: + if mid_num >= i: #数组中每个数字与中间数的差值 + step = mid_num - i + temp.append(step) + else: + step = i - mid_num + temp.append(step) + return sum(temp) +``` +时间复杂度:O(nlogn) +空间复杂度:O(n) From 9f338b625a22ee17d3a88193b84d274f8b085dba Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Wed, 27 Mar 2019 10:16:33 +0800 Subject: [PATCH 25/66] Create zengdiqing1994.md --- .../169-majorityElement/zengdiqing1994.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 leetcode/169-majorityElement/zengdiqing1994.md diff --git a/leetcode/169-majorityElement/zengdiqing1994.md b/leetcode/169-majorityElement/zengdiqing1994.md new file mode 100644 index 0000000..0d61574 --- /dev/null +++ b/leetcode/169-majorityElement/zengdiqing1994.md @@ -0,0 +1,58 @@ +给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 + +你可以假设数组是非空的,并且给定的数组总是存在众数。 + +示例 1: + +输入: [3,2,3] +输出: 3 +示例 2: + +输入: [2,2,1,1,1,2,2] +输出: 2 + +思路: + +1.最容易想到的就是众数的定义,先排序,然后取出中间的数,那个数一定是众数。 + +```py +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + return nums[len(nums)//2] +``` +时间复杂度:O(nlogn) +空间复杂度:O(1) + +2.摩尔投票法 + +我们先将数组中的第一个数假设为众数,然后进行统计其出现的次数,如果遇到同样的数,则计数器自动加一,否则计数器减一,如果计数器减到了0,则更换下一个数字为 +候选者。一定会有超过半数的数字存在,如果计数器减到0之后,说明目前不是候选数字的个数已经跟候选者的出现个数相同了,那么这个候选者已经很weak,不一定能出现 +超过半数,但是如果后面又大量出现之前的候选者的话,又会被重新变为候选者,直到最终验证为正确的众数。 + +```py +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + res = cnt = 0 + for num in nums: + if cnt == 0: + res = num + cnt += 1 + elif res == num: + cnt += 1 + else: + cnt -= 1 + return res +``` +时间复杂度:O(n) +空间复杂度:O(1) + + From 5b2b102d96db976bfa422636d694f7c3f4b8c624 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Fri, 29 Mar 2019 16:51:49 +0800 Subject: [PATCH 26/66] update questions --- images/160_example_1.png | Bin 0 -> 18949 bytes images/160_example_2.png | Bin 0 -> 16652 bytes images/160_example_3.png | Bin 0 -> 11092 bytes images/160_statement.png | Bin 0 -> 19796 bytes leetcode/001-twoSum/README.md | 16 ++++++ leetcode/001-twoSum/official.md | 4 -- leetcode/069-SqrtX/README.md | 25 ++++++++++ leetcode/069-SqrtX/official.md | 4 -- .../README.md | 46 ++++++++++++++++++ .../232-implementQueueUsingStacks/README.md | 28 +++++++++++ .../232-implementQueueUsingStacks/official.md | 4 -- .../README.md | 27 ++++++++++ leetcode/242-ValidAnagram/README.md | 25 ++++++++++ 13 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 images/160_example_1.png create mode 100644 images/160_example_2.png create mode 100644 images/160_example_3.png create mode 100644 images/160_statement.png create mode 100644 leetcode/001-twoSum/README.md delete mode 100644 leetcode/001-twoSum/official.md create mode 100644 leetcode/069-SqrtX/README.md delete mode 100644 leetcode/069-SqrtX/official.md create mode 100644 leetcode/160-IntersectionOfTwoLinkedLists/README.md create mode 100644 leetcode/232-implementQueueUsingStacks/README.md delete mode 100644 leetcode/232-implementQueueUsingStacks/official.md create mode 100644 leetcode/241-DifferentWaysToAddParentheses/README.md create mode 100644 leetcode/242-ValidAnagram/README.md diff --git a/images/160_example_1.png b/images/160_example_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2021a524a2b782b81938c070f80b2e5f48b83c3d GIT binary patch literal 18949 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 I_1ORa08s1@6951J literal 0 HcmV?d00001 diff --git a/images/160_example_2.png b/images/160_example_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4432fec7ce769b36467bbeb9d8922edb09e64b63 GIT binary patch literal 16652 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 KT!pN8(EkBgj-tr` literal 0 HcmV?d00001 diff --git a/images/160_example_3.png b/images/160_example_3.png new file mode 100644 index 0000000000000000000000000000000000000000..eea06311932338f071c169cec958f12b8b469dcb GIT binary patch literal 11092 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 literal 0 HcmV?d00001 diff --git a/leetcode/001-twoSum/README.md b/leetcode/001-twoSum/README.md new file mode 100644 index 0000000..7ecda74 --- /dev/null +++ b/leetcode/001-twoSum/README.md @@ -0,0 +1,16 @@ +**1. 两数之和** +--- +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 + +你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 + +**示例:** + +``` +给定 nums = [2, 7, 11, 15], target = 9 + +因为 nums[0] + nums[1] = 2 + 7 = 9 +所以返回 [0, 1] +``` diff --git a/leetcode/001-twoSum/official.md b/leetcode/001-twoSum/official.md deleted file mode 100644 index 729d988..0000000 --- a/leetcode/001-twoSum/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**1. 两数之和** ---- -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - diff --git a/leetcode/069-SqrtX/README.md b/leetcode/069-SqrtX/README.md new file mode 100644 index 0000000..090507f --- /dev/null +++ b/leetcode/069-SqrtX/README.md @@ -0,0 +1,25 @@ +**69. x 的平方根** +--- +[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) + +实现 ```int sqrt(int x)``` 函数。 + +计算并返回 x 的平方根,其中 x 是非负整数。 + +由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 + +**示例 1:** + +``` +输入: 4 +输出: 2 +``` + +**示例 2:** + +``` +输入: 8 +输出: 2 +说明: 8 的平方根是 2.82842..., + 由于返回类型是整数,小数部分将被舍去。 +``` diff --git a/leetcode/069-SqrtX/official.md b/leetcode/069-SqrtX/official.md deleted file mode 100644 index b9d2b1f..0000000 --- a/leetcode/069-SqrtX/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**69. x 的平方根** ---- - -[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/README.md b/leetcode/160-IntersectionOfTwoLinkedLists/README.md new file mode 100644 index 0000000..c4011b5 --- /dev/null +++ b/leetcode/160-IntersectionOfTwoLinkedLists/README.md @@ -0,0 +1,46 @@ +**160. 相交链表** +--- +[https://leetcode-cn.com/problems/intersection-of-two-linked-lists/](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) + +编写一个程序,找到两个单链表相交的起始节点。 + +如下面的两个链表: +![160_statement](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_statement.png) + + +在节点 c1 开始相交。 + +**示例 1:** +![160_example_1](https://assets.leetcode.com/uploads/2018/12/13/160_example_1.png) + + +输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 +输出:Reference of the node with value = 8 +输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 + + +**示例 2:** +![160_example_2](https://assets.leetcode.com/uploads/2018/12/13/160_example_2.png) + +``` +输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 +输出:Reference of the node with value = 2 +输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。 +``` + +**示例 3:** +![160_example_3](https://assets.leetcode.com/uploads/2018/12/13/160_exmple_3.png) + +``` +输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 +输出:null +输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 +解释:这两个链表不相交,因此返回 null。 +``` + +**注意:** + +* 如果两个链表没有交点,返回 null. +* 在返回结果后,两个链表仍须保持原有的结构。 +* 可假定整个链表结构中没有循环。 +* 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。 diff --git a/leetcode/232-implementQueueUsingStacks/README.md b/leetcode/232-implementQueueUsingStacks/README.md new file mode 100644 index 0000000..8006676 --- /dev/null +++ b/leetcode/232-implementQueueUsingStacks/README.md @@ -0,0 +1,28 @@ +**232. 用栈实现队列** +--- +[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) + +使用栈实现队列的下列操作: + +* push(x) -- 将一个元素放入队列的尾部。 +* pop() -- 从队列首部移除元素。 +* peek() -- 返回队列首部的元素。 +* empty() -- 返回队列是否为空。 + +示例: + +``` +MyQueue queue = new MyQueue(); + +queue.push(1); +queue.push(2); +queue.peek(); // 返回 1 +queue.pop(); // 返回 1 +queue.empty(); // 返回 false +``` + +说明: + +* 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 +* 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。 +* 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。 diff --git a/leetcode/232-implementQueueUsingStacks/official.md b/leetcode/232-implementQueueUsingStacks/official.md deleted file mode 100644 index 98ac7a7..0000000 --- a/leetcode/232-implementQueueUsingStacks/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**232. 用栈实现队列** ---- -[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) - diff --git a/leetcode/241-DifferentWaysToAddParentheses/README.md b/leetcode/241-DifferentWaysToAddParentheses/README.md new file mode 100644 index 0000000..2bcb2bf --- /dev/null +++ b/leetcode/241-DifferentWaysToAddParentheses/README.md @@ -0,0 +1,27 @@ +**241. 为运算表达式设计优先级** +--- +[https://leetcode-cn.com/problems/different-ways-to-add-parentheses/](https://leetcode-cn.com/problems/different-ways-to-add-parentheses/) + +给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。 + +**示例 1:** +``` +输入: "2-1-1" +输出: [0, 2] +解释: +((2-1)-1) = 0 +(2-(1-1)) = 2 +``` + +**示例 2:** + +``` +输入: "2*3-4*5" +输出: [-34, -14, -10, -10, 10] +解释: +(2*(3-(4*5))) = -34 +((2*3)-(4*5)) = -14 +((2*(3-4))*5) = -10 +(2*((3-4)*5)) = -10 +(((2*3)-4)*5) = 10 +``` diff --git a/leetcode/242-ValidAnagram/README.md b/leetcode/242-ValidAnagram/README.md new file mode 100644 index 0000000..2640622 --- /dev/null +++ b/leetcode/242-ValidAnagram/README.md @@ -0,0 +1,25 @@ +**242. 有效的字母异位词** +--- +[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) + +给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。 + +**示例 1:** + +``` +输入: s = "anagram", t = "nagaram" +输出: true +``` + +**示例 2:** + +``` +输入: s = "rat", t = "car" +输出: false +``` + +**说明:** +你可以假设字符串只包含小写字母。 + +**进阶:** +如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况? From fd5c291bf23f2b1ff578cceb3cd61d99e6970d1d Mon Sep 17 00:00:00 2001 From: bigablecat Date: Fri, 29 Mar 2019 16:58:25 +0800 Subject: [PATCH 27/66] update questions --- leetcode/160-IntersectionOfTwoLinkedLists/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/README.md b/leetcode/160-IntersectionOfTwoLinkedLists/README.md index c4011b5..4cf2a0a 100644 --- a/leetcode/160-IntersectionOfTwoLinkedLists/README.md +++ b/leetcode/160-IntersectionOfTwoLinkedLists/README.md @@ -4,14 +4,14 @@ 编写一个程序,找到两个单链表相交的起始节点。 -如下面的两个链表: -![160_statement](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_statement.png) +如下面的两个链表: +![160_statement](https://raw.githubusercontent.com/hollischuang/algorithm/master/images/160_statement.png) 在节点 c1 开始相交。 **示例 1:** -![160_example_1](https://assets.leetcode.com/uploads/2018/12/13/160_example_1.png) +![160_example_1](https://raw.githubusercontent.com/hollischuang/algorithm/master/images/160_example_1.png) 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 @@ -20,7 +20,7 @@ **示例 2:** -![160_example_2](https://assets.leetcode.com/uploads/2018/12/13/160_example_2.png) +![160_example_2](https://raw.githubusercontent.com/hollischuang/algorithm/master/images/160_example_2.png) ``` 输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 @@ -29,7 +29,7 @@ ``` **示例 3:** -![160_example_3](https://assets.leetcode.com/uploads/2018/12/13/160_exmple_3.png) +![160_example_3](https://raw.githubusercontent.com/hollischuang/algorithm/master/images/160_example_3.png) ``` 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 From 213db512f81091b0a9ee3e78f305c0d5ed4b8705 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Mon, 1 Apr 2019 22:24:04 +0800 Subject: [PATCH 28/66] update --- images/160_example_1.png | Bin 18949 -> 15178 bytes images/160_example_2.png | Bin 16652 -> 13635 bytes images/160_example_3.png | Bin 11092 -> 9245 bytes images/160_statement.png | Bin 19796 -> 16045 bytes leetcode/069-SqrtX/bigablecat.md | 54 ++++++++++++ .../bigablecat.md | 79 ++++++++++++++++++ .../bigablecat.md | 73 ++++++++++++++++ 7 files changed, 206 insertions(+) create mode 100644 leetcode/069-SqrtX/bigablecat.md create mode 100644 leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md create mode 100644 leetcode/241-DifferentWaysToAddParentheses/bigablecat.md diff --git a/images/160_example_1.png b/images/160_example_1.png index 2021a524a2b782b81938c070f80b2e5f48b83c3d..dc204822458401081327041ccbad903b38249916 100644 GIT binary patch literal 15178 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%0DmPF^m>`)O#I`zuys>MQ2A{?&-jDS7($~XT~ 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 T%9#o0Uk@oNsLJQcn)&`8z&!7c literal 18949 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 I_1ORa08s1@6951J diff --git a/images/160_example_2.png b/images/160_example_2.png index 4432fec7ce769b36467bbeb9d8922edb09e64b63..8a57d6ce139ec4315acc357fabaa0fc2b9800dae 100644 GIT binary patch literal 13635 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 KT!pN8(EkBgj-tr` diff --git a/images/160_example_3.png b/images/160_example_3.png index eea06311932338f071c169cec958f12b8b469dcb..6f8e524d3e9677604f9d68753f17c5095e2be151 100644 GIT binary patch literal 9245 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 LQB};7H-7gYG9M3t literal 11092 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 diff --git a/leetcode/069-SqrtX/bigablecat.md b/leetcode/069-SqrtX/bigablecat.md new file mode 100644 index 0000000..ecbcc42 --- /dev/null +++ b/leetcode/069-SqrtX/bigablecat.md @@ -0,0 +1,54 @@ +**69. x 的平方根** +--- +[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) + +* 网友高票Java题解: + +```java + /** + * https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution + * 网友高票答案 + * + * @param x + * @return + */ + public static int mySqrt(int x) { + //如果x是0,平方根为0 + if (x == 0){ + //直接返回结果0 + return 0; + } + //分别设定左右边界left和right + //left从非负整数1开始,right到java运行的整数最大值上限Integer.MAX_VALUE为止 + int left = 1, right = x; + //while (true) 进行一个无限循环,只能在方法体内结束循环 + while (true) { + // 通过二分法不断缩小取值范围 + // 目标是找到一个中间值mid,如果x介于mid²和(mid+1)²之间 + // 那么mid就是x平方根的整数部分 + int mid = left + (right - left) / 2; + // mid > x/mid 等价于 mid² > x + // 说明mid本身比x的平方根大 + if (mid > x / mid) { + //将mid-1赋值给右边界right,在小于mid的范围内继续寻找x的平方根 + right = mid - 1; + } else { + // mid + 1 > x/(mid + 1) 等价于 (mid + 1)² > x + // 说明 (mid + 1) 比 x 的平方根大 + if (mid + 1 > x / (mid + 1)) + // mid 小于或等于 x 的平方根 + // (mid + 1) 大于 x 的平方根 + // mid 即是要找的数字 + return mid; + //如果 (mid + 1)² < + left = mid + 1; + } + } + } + +``` + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md b/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md new file mode 100644 index 0000000..fc90eaf --- /dev/null +++ b/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md @@ -0,0 +1,79 @@ +**160. 相交链表** +--- +[https://leetcode-cn.com/problems/intersection-of-two-linked-lists/](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) + +* 网友高票java答案 + +```java + + /** + * https://leetcode.com/articles/intersection-of-two-linked-lists/ + * 官方题解3:双指针法 + * https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len! + * 网友高票答案 + * + * 时间复杂度:O(m+n), + * while循环最差情况是完整遍历两个链表, + * 时间复杂度为 m+n + * + * 空间复杂度:O(1), + * 方法没有占用额外空间,所以空间复杂度为O(1) + * + * + * @param headA + * @param headB + * @return + */ + public static ListNode getIntersectionNode(ListNode headA, ListNode headB) { + //检查边界条件 + if(headA == null || headB == null) return null; + + //定义指针a和b分别指向headA和headB + ListNode a = headA; + ListNode b = headB; + + //检查a和b是否有相同结点,如果没有则继续循环 + while( a != b){ + //for the end of first iteration, we just reset the pointer to the head of another linkedlist + //(a == null)检查headA是否到达了链表结尾 + //当a为null时,headA遍历结束,将a指向链表headB的头结点 + //如果a不为空,则a指向后继结点 + a = (a == null)? headB : a.next; + //同理,对b和headB做相同的操作 + b = (b == null)? headA : b.next; + + //上述代码的逻辑简书如下 + //在while循环中,每个链表遍历结束时都指向另一个链表 + //假设 headA 的长度为 lenA,headB 的长度为 lenB,且lenB >= lenA + //int x = lenB - lenA; + //当指针a在headA上走完lenA步的时候,指针b离headB的尾结点还有x步 + //接着a指向headB,两个指针同时继续前进 + //当b走完x步来到headB的尾结点,a在headB上也从头结点前行了x步 + //此时b来到headA的头结点,距离headA的尾结点还有lenA步 + //而a在headB的第x个结点,距离headB的尾结点还有lenB-x = lenA步 + //所以当循环到较长的链表headB时,两个链表上的指针剩余的长度是一样的 + //此时继续遍历,当a==b,且都不为null + //即指针a和指针b指向相同的结点时,这个结点就是两个链表的交点 + //当a和b同时为null,说明指针在第二轮同时走到终点也没有交点 + } + + return a; + } + +``` + +时间复杂度:O(m+n), +while循环最差情况是完整遍历两个链表, +时间复杂度为 m+n + +空间复杂度:O(1), +方法没有占用额外空间,所以空间复杂度为O(1) + +**参考资料** + + +* 官方题解3:双指针法 +[https://leetcode.com/articles/intersection-of-two-linked-lists/](https://leetcode.com/articles/intersection-of-two-linked-lists/) + +* 网友高票Java答案: +[https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!](https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!) diff --git a/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md b/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md new file mode 100644 index 0000000..ba8e680 --- /dev/null +++ b/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md @@ -0,0 +1,73 @@ +**241. 为运算表达式设计优先级** +--- +[https://leetcode-cn.com/problems/different-ways-to-add-parentheses/](https://leetcode-cn.com/problems/different-ways-to-add-parentheses/) + +* 网友高票Java答案: + +```java + /** + * https://leetcode.com/problems/different-ways-to-add-parentheses/discuss/66328/A-recursive-Java-solution-(284-ms) + * 网友高票答案:分治 + * + * + * @param input + * @return + */ + public static List diffWaysToCompute(String input) { + //创建一个链表ret用于存储当前input经过运算后所有可能的结果 + List ret = new LinkedList<>(); + //遍历输入字符串的每个字符 + for (int i = 0; i < input.length(); i++) { + //如果当前字符为运算符 + if (input.charAt(i) == '-' || + input.charAt(i) == '*' || + input.charAt(i) == '+') { + //将字符串拆分为两部分 + //part1截取自input起始位置到当前位置i + String part1 = input.substring(0, i); + //part2从input第i+1个位置到input末尾 + String part2 = input.substring(i + 1); + //递归调用diffWaysToCompute方法 + //分别得到part1和part2中所有的运算结果part1Ret和part2Ret + List part1Ret = diffWaysToCompute(part1); + List part2Ret = diffWaysToCompute(part2); + //分别遍历part1Ret和part2Ret + for (Integer p1 : part1Ret) { + for (Integer p2 : part2Ret) { + //定义一个整数变量c用于存储p1和p2的运算结果 + //c的初始值为0 + int c = 0; + //判断当前运算符号 + //根据运算符号进行不同的运算 + switch (input.charAt(i)) { + case '+': + c = p1 + p2; + break; + case '-': + c = p1 - p2; + break; + case '*': + c = p1 * p2; + break; + } + //将运算结果c存入最终结果ret中 + ret.add(c); + } + } + } + } + //如果ret.size() == 0表示input中没有运算符号 + if (ret.size() == 0) { + //将不包含运算符的input转为整数后存入ret + ret.add(Integer.valueOf(input)); + } + //返回最终结果ret + return ret; + } + +``` + +**参考资料** + +* 网友高票Java答案: +[https://leetcode.com/problems/different-ways-to-add-parentheses/discuss/66328/A-recursive-Java-solution-(284-ms)](https://leetcode.com/problems/different-ways-to-add-parentheses/discuss/66328/A-recursive-Java-solution-(284-ms)) From eff0c41ce5e538acfc226cdcaf136081ec637fc6 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 2 Apr 2019 09:39:57 +0800 Subject: [PATCH 29/66] update --- leetcode/110-BalancedBinaryTree/README.md | 42 ++++++++++++++++++ .../144-BinaryTreePreorderTraversal/README.md | 18 ++++++++ leetcode/207-CourseSchedule/README.md | 38 ++++++++++++++++ .../208-implementTriePrefixTree/README.md | 24 +++++++++++ .../208-implementTriePrefixTree/official.md | 4 -- .../230-KthSmallestElementInABST/README.md | 36 ++++++++++++++++ .../513-FindBottomLeftTreeValue/README.md | 39 +++++++++++++++++ leetcode/684-RedundantConnection/README.md | 43 +++++++++++++++++++ leetcode/785-IsGraphBipartite/README.md | 42 ++++++++++++++++++ 9 files changed, 282 insertions(+), 4 deletions(-) create mode 100644 leetcode/110-BalancedBinaryTree/README.md create mode 100644 leetcode/144-BinaryTreePreorderTraversal/README.md create mode 100644 leetcode/207-CourseSchedule/README.md create mode 100644 leetcode/208-implementTriePrefixTree/README.md delete mode 100644 leetcode/208-implementTriePrefixTree/official.md create mode 100644 leetcode/230-KthSmallestElementInABST/README.md create mode 100644 leetcode/513-FindBottomLeftTreeValue/README.md create mode 100644 leetcode/684-RedundantConnection/README.md create mode 100644 leetcode/785-IsGraphBipartite/README.md diff --git a/leetcode/110-BalancedBinaryTree/README.md b/leetcode/110-BalancedBinaryTree/README.md new file mode 100644 index 0000000..d66a4ef --- /dev/null +++ b/leetcode/110-BalancedBinaryTree/README.md @@ -0,0 +1,42 @@ +**110. 平衡二叉树** +--- +[https://leetcode-cn.com/problems/balanced-binary-tree/](https://leetcode-cn.com/problems/balanced-binary-tree/) + +给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 + +你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 + +给定一个二叉树,判断它是否是高度平衡的二叉树。 + +本题中,一棵高度平衡二叉树定义为: + +>一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 + +**示例 1:** + +``` +给定二叉树 [3,9,20,null,null,15,7] + + 3 + / \ + 9 20 + / \ + 15 7 +返回 true 。 +``` + +**示例 2:** + +``` +给定二叉树 [1,2,2,3,3,null,null,4,4] + + 1 + / \ + 2 2 + / \ + 3 3 + / \ + 4 4 +返回 false 。 +``` + diff --git a/leetcode/144-BinaryTreePreorderTraversal/README.md b/leetcode/144-BinaryTreePreorderTraversal/README.md new file mode 100644 index 0000000..91dc5eb --- /dev/null +++ b/leetcode/144-BinaryTreePreorderTraversal/README.md @@ -0,0 +1,18 @@ +**144. 二叉树的前序遍历** +--- +[https://leetcode-cn.com/problems/binary-tree-preorder-traversal/](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/) + +给定一个二叉树,返回它的 前序 遍历。 + +**示例:** + +``` +输入: [1,null,2,3] + 1 + \ + 2 + / + 3 + +输出: [1,2,3] +``` diff --git a/leetcode/207-CourseSchedule/README.md b/leetcode/207-CourseSchedule/README.md new file mode 100644 index 0000000..609afac --- /dev/null +++ b/leetcode/207-CourseSchedule/README.md @@ -0,0 +1,38 @@ +**207. 课程表** +--- +[https://leetcode-cn.com/problems/course-schedule/](https://leetcode-cn.com/problems/course-schedule/) + +现在你总共有 n 门课需要选,记为 0 到 n-1。 + +在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] + +给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习? + +**示例 1:** + +``` +输入: 2, [[1,0]] +输出: true +解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。 +``` + +**示例 2:** + +``` +输入: 2, [[1,0],[0,1]] +输出: false +解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。 +``` + +**说明:** + +1. 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。 +2. 你可以假定输入的先决条件中没有重复的边。 + +**提示:** + +1. 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。 +2. 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。 +3. 拓扑排序也可以通过 BFS 完成。 + + diff --git a/leetcode/208-implementTriePrefixTree/README.md b/leetcode/208-implementTriePrefixTree/README.md new file mode 100644 index 0000000..c3e7c52 --- /dev/null +++ b/leetcode/208-implementTriePrefixTree/README.md @@ -0,0 +1,24 @@ +**208. 实现 Trie (前缀树)** +--- +[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) + +实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。 + +**示例:** + +``` +Trie trie = new Trie(); + +trie.insert("apple"); +trie.search("apple"); // 返回 true +trie.search("app"); // 返回 false +trie.startsWith("app"); // 返回 true +trie.insert("app"); +trie.search("app"); // 返回 true +``` + +**说明:** + +* 你可以假设所有的输入都是由小写字母 a-z 构成的。 +* 保证所有输入均为非空字符串。 + diff --git a/leetcode/208-implementTriePrefixTree/official.md b/leetcode/208-implementTriePrefixTree/official.md deleted file mode 100644 index e8c050d..0000000 --- a/leetcode/208-implementTriePrefixTree/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**208. 实现 Trie (前缀树)** ---- -[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) - diff --git a/leetcode/230-KthSmallestElementInABST/README.md b/leetcode/230-KthSmallestElementInABST/README.md new file mode 100644 index 0000000..e394b47 --- /dev/null +++ b/leetcode/230-KthSmallestElementInABST/README.md @@ -0,0 +1,36 @@ +**230. 二叉搜索树中第K小的元素** +--- +[https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/](https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/) + +给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。 + +**说明:** +你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。 + +**示例 1:** + +``` +输入: root = [3,1,4,null,2], k = 1 + 3 + / \ + 1 4 + \ + 2 +输出: 1 +``` + +**示例 2:** + +``` +输入: root = [5,3,6,2,4,null,null,1], k = 3 + 5 + / \ + 3 6 + / \ + 2 4 + / + 1 +输出: 3 +进阶: +如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数? +``` diff --git a/leetcode/513-FindBottomLeftTreeValue/README.md b/leetcode/513-FindBottomLeftTreeValue/README.md new file mode 100644 index 0000000..5693742 --- /dev/null +++ b/leetcode/513-FindBottomLeftTreeValue/README.md @@ -0,0 +1,39 @@ +**513. 找树左下角的值** +--- +[https://leetcode-cn.com/problems/find-bottom-left-tree-value/](https://leetcode-cn.com/problems/find-bottom-left-tree-value/) + +给定一个二叉树,在树的最后一行找到最左边的值。 + +**示例 1:** + +``` +输入: + + 2 + / \ + 1 3 + +输出: +1 +``` + +**示例 2:** + +``` +输入: + + 1 + / \ + 2 3 + / / \ + 4 5 6 + / + 7 + +输出: +7 +``` + + +注意: 您可以假设树(即给定的根节点)不为 NULL。 + diff --git a/leetcode/684-RedundantConnection/README.md b/leetcode/684-RedundantConnection/README.md new file mode 100644 index 0000000..e5b1d14 --- /dev/null +++ b/leetcode/684-RedundantConnection/README.md @@ -0,0 +1,43 @@ +**684. 冗余连接** +--- +[https://leetcode-cn.com/problems/redundant-connection/](https://leetcode-cn.com/problems/redundant-connection/) + +在本问题中, 树指的是一个连通且无环的无向图。 + +输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。 + +结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。 + +返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。 + +**示例 1:** + +``` +输入: [[1,2], [1,3], [2,3]] +输出: [2,3] +解释: 给定的无向图为: + 1 + / \ +2 - 3 +``` + +**示例 2:** + +``` +输入: [[1,2], [2,3], [3,4], [1,4], [1,5]] +输出: [1,4] +解释: 给定的无向图为: +5 - 1 - 2 + | | + 4 - 3 +``` + +**注意:** + +* 输入的二维数组大小在 3 到 1000。 +* 二维数组中的整数在1到N之间,其中N是输入数组的大小。 + +**更新(2017-09-26):** +LeetCode已经重新检查了问题描述及测试用例,明确图是**无向图**。 +对于有向图详见[冗余连接II](https://leetcode-cn.com/problems/redundant-connection-ii/) + diff --git a/leetcode/785-IsGraphBipartite/README.md b/leetcode/785-IsGraphBipartite/README.md new file mode 100644 index 0000000..3a29435 --- /dev/null +++ b/leetcode/785-IsGraphBipartite/README.md @@ -0,0 +1,42 @@ +**785. 判断二分图** +--- +[https://leetcode-cn.com/problems/is-graph-bipartite/](https://leetcode-cn.com/problems/is-graph-bipartite/) + +给定一个无向图graph,当这个图为二分图时返回true。 + +如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。 + +graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。 + +``` +示例 1: +输入: [[1,3], [0,2], [1,3], [0,2]] +输出: true +解释: +无向图如下: +0----1 +| | +| | +3----2 +我们可以将节点分成两组: {0, 2} 和 {1, 3}。 +``` + +``` +示例 2: +输入: [[1,2,3], [0,2], [0,1,3], [0,2]] +输出: false +解释: +无向图如下: +0----1 +| \ | +| \ | +3----2 +我们不能将节点分割成两个独立的子集。 +``` + +**注意:** + +* graph 的长度范围为 [1, 100]。 +* graph[i] 中的元素的范围为 [0, graph.length - 1]。 +* graph[i] 不会包含 i 或者有重复的值。 +* 图是无向的: 如果j 在 graph[i]里边, 那么 i 也会在 graph[j]里边。 From d8d4df6464615476fd6eb9023e256858bd6fd23d Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 2 Apr 2019 09:45:16 +0800 Subject: [PATCH 30/66] update --- leetcode/230-KthSmallestElementInABST/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/leetcode/230-KthSmallestElementInABST/README.md b/leetcode/230-KthSmallestElementInABST/README.md index e394b47..a2e5aae 100644 --- a/leetcode/230-KthSmallestElementInABST/README.md +++ b/leetcode/230-KthSmallestElementInABST/README.md @@ -31,6 +31,7 @@ / 1 输出: 3 -进阶: -如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数? ``` + +**进阶:** +如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数? From 07326efaa963140e00225bb0222e350b474114a7 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 2 Apr 2019 17:32:20 +0800 Subject: [PATCH 31/66] Create zengdiqing1994.md --- .../110-BalancedBinaryTree/zengdiqing1994.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 leetcode/110-BalancedBinaryTree/zengdiqing1994.md diff --git a/leetcode/110-BalancedBinaryTree/zengdiqing1994.md b/leetcode/110-BalancedBinaryTree/zengdiqing1994.md new file mode 100644 index 0000000..f348f7a --- /dev/null +++ b/leetcode/110-BalancedBinaryTree/zengdiqing1994.md @@ -0,0 +1,51 @@ +110.给定一个二叉树,判断它是否是高度平衡的二叉树。 + +本题中,一棵高度平衡二叉树定义为: + +一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 + +示例 1: + +给定二叉树 [3,9,20,null,null,15,7] + + 3 + / \ + 9 20 + / \ + 15 7 +返回 true 。 + +示例 2: + +给定二叉树 [1,2,2,3,3,null,null,4,4] + + 1 + / \ + 2 2 + / \ + 3 3 + / \ + 4 4 +返回 false 。 + +思路:递归,判断左右子树最大高度差不超过1且左右子树均为平衡树 + +```py +class Solution(object): + def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + def getDepth(root): + if not root: + return 0 + return 1 + max(getDepth(root.left), getDepth(root.right)) #左右子树最大的深度,记住加一 + + if not root: + return True + if abs(getDepth(root.left) - getDepth(root.right))>1: #判断左右子树的最大深度差是否超过1 + return False + return self.isBalanced(root.left) and self.isBalanced(root.right) +``` +时间复杂度:O(n) From 23776db28bec631a63ea73027ec8fc44bd3e6683 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 2 Apr 2019 17:38:16 +0800 Subject: [PATCH 32/66] Create zengdiqing1994 --- .../zengdiqing1994 | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 diff --git a/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 b/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 new file mode 100644 index 0000000..1cbaf79 --- /dev/null +++ b/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 @@ -0,0 +1,51 @@ +513.给定一个二叉树,在树的最后一行找到最左边的值。 + +示例 1: + +输入: + + 2 + / \ + 1 3 + +输出: +1 + + +示例 2: + +输入: + + 1 + / \ + 2 3 + / / \ + 4 5 6 + / + 7 + +输出: +7 + + +注意: 您可以假设树(即给定的根节点)不为 NULL。 + +思路:可以用队列来层次遍历, + +```py +class Solution: + def findBottomLeftValue(self, root: TreeNode) -> int: + result, queue = [], [root] + while queue: + temp = [] + result = queue[0].val #取出每一层根的val + for node in queue: + if node.left: + temp.append(node.left) #层次遍历 + if node.right: + temp.append(node.right) + queue = temp + return result +``` +时间复杂度:O(n^2) +空间复杂度:O(n) From 1ca53d680ec20f7bc7b1b5a83da8960ab94a10e4 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 2 Apr 2019 23:04:10 +0800 Subject: [PATCH 33/66] update new questions --- leetcode/006-ZigZagConversion/README.md | 41 +++++++++++++++ leetcode/023-MergeKSortedLists/README.md | 17 +++++++ .../033-SearchInRotatedSortedArray/README.md | 27 ++++++++++ leetcode/048-RotateImage/README.md | 50 +++++++++++++++++++ leetcode/053-maximumSubarray/README.md | 13 +++++ leetcode/053-maximumSubarray/official.md | 3 -- leetcode/054-SpiralMatrix/README.md | 29 +++++++++++ leetcode/059-SpiralMatrixII/README.md | 18 +++++++ leetcode/152-MaximumProductSubarray/README.md | 22 ++++++++ .../152-MaximumProductSubarray/official.md | 4 -- .../README.md | 26 ++++++++++ 11 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 leetcode/006-ZigZagConversion/README.md create mode 100644 leetcode/023-MergeKSortedLists/README.md create mode 100644 leetcode/033-SearchInRotatedSortedArray/README.md create mode 100644 leetcode/048-RotateImage/README.md create mode 100644 leetcode/053-maximumSubarray/README.md delete mode 100644 leetcode/053-maximumSubarray/official.md create mode 100644 leetcode/054-SpiralMatrix/README.md create mode 100644 leetcode/059-SpiralMatrixII/README.md create mode 100644 leetcode/152-MaximumProductSubarray/README.md delete mode 100644 leetcode/152-MaximumProductSubarray/official.md create mode 100644 leetcode/153-FindMinimumInRotatedSortedArray/README.md diff --git a/leetcode/006-ZigZagConversion/README.md b/leetcode/006-ZigZagConversion/README.md new file mode 100644 index 0000000..3252cff --- /dev/null +++ b/leetcode/006-ZigZagConversion/README.md @@ -0,0 +1,41 @@ +**6. Z 字形变换** +--- +[https://leetcode-cn.com/problems/zigzag-conversion/](https://leetcode-cn.com/problems/zigzag-conversion/) + +将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 + +比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: + +``` +L C I R +E T O E S I I G +E D H N +``` + +之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。 + +请你实现这个将字符串进行指定行数变换的函数: + +``` +string convert(string s, int numRows); +``` + +**示例 1:** + +``` +输入: s = "LEETCODEISHIRING", numRows = 3 +输出: "LCIRETOESIIGEDHN" +``` + +**示例 2:** + +``` +输入: s = "LEETCODEISHIRING", numRows = 4 +输出: "LDREOEIIECIHNTSG" +解释: + +L D R +E O E I I +E C I H N +T S G +``` diff --git a/leetcode/023-MergeKSortedLists/README.md b/leetcode/023-MergeKSortedLists/README.md new file mode 100644 index 0000000..7ebf242 --- /dev/null +++ b/leetcode/023-MergeKSortedLists/README.md @@ -0,0 +1,17 @@ +**23. 合并K个排序链表** +--- +[https://leetcode-cn.com/problems/merge-k-sorted-lists/](https://leetcode-cn.com/problems/merge-k-sorted-lists/) + +合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 + +**示例:** + +``` +输入: +[ + 1->4->5, + 1->3->4, + 2->6 +] +输出: 1->1->2->3->4->4->5->6 +``` diff --git a/leetcode/033-SearchInRotatedSortedArray/README.md b/leetcode/033-SearchInRotatedSortedArray/README.md new file mode 100644 index 0000000..9c693c7 --- /dev/null +++ b/leetcode/033-SearchInRotatedSortedArray/README.md @@ -0,0 +1,27 @@ +**33. 搜索旋转排序数组** +--- +[https://leetcode-cn.com/problems/search-in-rotated-sorted-array/](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) + +假设按照升序排序的数组在预先未知的某个点上进行了旋转。 + +( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 + +搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 + +你可以假设数组中不存在重复的元素。 + +你的算法时间复杂度必须是 O(log n) 级别。 + +**示例 1:** + +``` +输入: nums = [4,5,6,7,0,1,2], target = 0 +输出: 4 +``` + +**示例 2:** + +``` +输入: nums = [4,5,6,7,0,1,2], target = 3 +输出: -1 +``` diff --git a/leetcode/048-RotateImage/README.md b/leetcode/048-RotateImage/README.md new file mode 100644 index 0000000..7b78dec --- /dev/null +++ b/leetcode/048-RotateImage/README.md @@ -0,0 +1,50 @@ +**48. 旋转图像** +--- +[https://leetcode-cn.com/problems/rotate-image/](https://leetcode-cn.com/problems/rotate-image/) + +给定一个 n × n 的二维矩阵表示一个图像。 + +将图像顺时针旋转 90 度。 + +**说明:** + +你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。 +请**不要**使用另一个矩阵来旋转图像。 + +**示例 1:** + +``` +给定 matrix = +[ + [1,2,3], + [4,5,6], + [7,8,9] +], + +原地旋转输入矩阵,使其变为: +[ + [7,4,1], + [8,5,2], + [9,6,3] +] +``` + +**示例 2:** + +``` +给定 matrix = +[ + [ 5, 1, 9,11], + [ 2, 4, 8,10], + [13, 3, 6, 7], + [15,14,12,16] +], + +原地旋转输入矩阵,使其变为: +[ + [15,13, 2, 5], + [14, 3, 4, 1], + [12, 6, 8, 9], + [16, 7,10,11] +] +``` diff --git a/leetcode/053-maximumSubarray/README.md b/leetcode/053-maximumSubarray/README.md new file mode 100644 index 0000000..a4202df --- /dev/null +++ b/leetcode/053-maximumSubarray/README.md @@ -0,0 +1,13 @@ +**53. 最大子序和** +--- +[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) + +给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 + +**示例:** + +``` +输入: [-2,1,-3,4,-1,2,1,-5,4], +输出: 6 +解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 +``` diff --git a/leetcode/053-maximumSubarray/official.md b/leetcode/053-maximumSubarray/official.md deleted file mode 100644 index e50ab30..0000000 --- a/leetcode/053-maximumSubarray/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**53. 最大子序和** ---- -[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) diff --git a/leetcode/054-SpiralMatrix/README.md b/leetcode/054-SpiralMatrix/README.md new file mode 100644 index 0000000..3dbac1c --- /dev/null +++ b/leetcode/054-SpiralMatrix/README.md @@ -0,0 +1,29 @@ +**54. 螺旋矩阵** +--- +[https://leetcode-cn.com/problems/spiral-matrix/](https://leetcode-cn.com/problems/spiral-matrix/) + +给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 + +**示例 1:** + +``` +输入: +[ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] +输出: [1,2,3,6,9,8,7,4,5] +``` + +**示例 2:** + +``` +输入: +[ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9,10,11,12] +] +输出: [1,2,3,4,8,12,11,10,9,5,6,7] +``` diff --git a/leetcode/059-SpiralMatrixII/README.md b/leetcode/059-SpiralMatrixII/README.md new file mode 100644 index 0000000..15b513c --- /dev/null +++ b/leetcode/059-SpiralMatrixII/README.md @@ -0,0 +1,18 @@ +**59. 螺旋矩阵 II** +--- +[https://leetcode-cn.com/problems/spiral-matrix-ii/](https://leetcode-cn.com/problems/spiral-matrix-ii/) + +给定一个正整数 n,生成一个包含 1 到 n2 所有元素, +且元素按顺时针顺序螺旋排列的正方形矩阵。 + +**示例:** + +``` +输入: 3 +输出: +[ + [ 1, 2, 3 ], + [ 8, 9, 4 ], + [ 7, 6, 5 ] +] +``` diff --git a/leetcode/152-MaximumProductSubarray/README.md b/leetcode/152-MaximumProductSubarray/README.md new file mode 100644 index 0000000..88507a2 --- /dev/null +++ b/leetcode/152-MaximumProductSubarray/README.md @@ -0,0 +1,22 @@ +**152. 乘积最大子序列** +--- + +[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) + +给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。 + +**示例 1:** + +``` +输入: [2,3,-2,4] +输出: 6 +解释: 子数组 [2,3] 有最大乘积 6。 +``` + +**示例 2:** + +``` +输入: [-2,0,-1] +输出: 0 +解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。 +``` diff --git a/leetcode/152-MaximumProductSubarray/official.md b/leetcode/152-MaximumProductSubarray/official.md deleted file mode 100644 index d6f0978..0000000 --- a/leetcode/152-MaximumProductSubarray/official.md +++ /dev/null @@ -1,4 +0,0 @@ -**152. 乘积最大子序列** ---- - -[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) diff --git a/leetcode/153-FindMinimumInRotatedSortedArray/README.md b/leetcode/153-FindMinimumInRotatedSortedArray/README.md new file mode 100644 index 0000000..eed5305 --- /dev/null +++ b/leetcode/153-FindMinimumInRotatedSortedArray/README.md @@ -0,0 +1,26 @@ +**153. 寻找旋转排序数组中的最小值** +--- + +[https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/) + +假设按照升序排序的数组在预先未知的某个点上进行了旋转。 + +( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 + +请找出其中最小的元素。 + +你可以假设数组中不存在重复元素。 + +**示例 1:** + +``` +输入: [3,4,5,1,2] +输出: 1 +``` + +**示例 2:** + +``` +输入: [4,5,6,7,0,1,2] +输出: 0 +``` From 6507fc7aeb1cbb1d4cc0f40add1879ed13b11716 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 2 Apr 2019 23:08:41 +0800 Subject: [PATCH 34/66] modify --- leetcode/053-maximumSubarray/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leetcode/053-maximumSubarray/README.md b/leetcode/053-maximumSubarray/README.md index a4202df..9c320ca 100644 --- a/leetcode/053-maximumSubarray/README.md +++ b/leetcode/053-maximumSubarray/README.md @@ -1,6 +1,6 @@ **53. 最大子序和** --- -[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) +[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 From 564d152c5b87b99aedc233a5cd14b22e6d905016 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Sun, 7 Apr 2019 16:35:36 +0800 Subject: [PATCH 35/66] udpate new questions --- images/017_Telephone-keypad2.png | Bin 0 -> 25405 bytes .../README.md | 18 +++++++ leetcode/064-minimumPathSum/README.md | 20 ++++++++ leetcode/064-minimumPathSum/official.md | 3 -- leetcode/070-ClimbingStairs/README.md | 30 +++++++++++ leetcode/070-ClimbingStairs/official.md | 3 -- leetcode/279-PerfectSquares/README.md | 21 ++++++++ leetcode/279-PerfectSquares/official.md | 3 -- .../README.md | 22 ++++++++ .../official.md | 3 -- leetcode/303-rangeSumQueryImmutable/README.md | 20 ++++++++ .../303-rangeSumQueryImmutable/official.md | 3 -- .../README.md | 18 +++++++ leetcode/343-IntegerBreak/README.md | 24 +++++++++ leetcode/343-IntegerBreak/official.md | 3 -- leetcode/403-FrogJump/official.md | 47 ------------------ .../416-PartitionEqualSubsetSum/README.md | 30 +++++++++++ .../416-PartitionEqualSubsetSum/official.md | 3 -- .../README.md | 18 +++++++ .../{official.md => README.md} | 0 leetcode/695-MaxAreaOfIsland/README.md | 28 +++++++++++ 21 files changed, 249 insertions(+), 68 deletions(-) create mode 100644 images/017_Telephone-keypad2.png create mode 100644 leetcode/017-LetterCombinationsOfAPhoneNumber/README.md create mode 100644 leetcode/064-minimumPathSum/README.md delete mode 100644 leetcode/064-minimumPathSum/official.md create mode 100644 leetcode/070-ClimbingStairs/README.md delete mode 100644 leetcode/070-ClimbingStairs/official.md create mode 100644 leetcode/279-PerfectSquares/README.md delete mode 100644 leetcode/279-PerfectSquares/official.md create mode 100644 leetcode/300-LongestIncreasingSubsequence/README.md delete mode 100644 leetcode/300-LongestIncreasingSubsequence/official.md create mode 100644 leetcode/303-rangeSumQueryImmutable/README.md delete mode 100644 leetcode/303-rangeSumQueryImmutable/official.md create mode 100644 leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md create mode 100644 leetcode/343-IntegerBreak/README.md delete mode 100644 leetcode/343-IntegerBreak/official.md delete mode 100644 leetcode/403-FrogJump/official.md create mode 100644 leetcode/416-PartitionEqualSubsetSum/README.md delete mode 100644 leetcode/416-PartitionEqualSubsetSum/official.md create mode 100644 leetcode/583-DeleteOperationForTwoStrings/README.md rename leetcode/673-NumberOfLongestIncreasingSubsequence/{official.md => README.md} (100%) create mode 100644 leetcode/695-MaxAreaOfIsland/README.md diff --git a/images/017_Telephone-keypad2.png b/images/017_Telephone-keypad2.png new file mode 100644 index 0000000000000000000000000000000000000000..38764028d1835692e6aac845274e152b2106bae6 GIT binary patch literal 25405 zcmXV%1zZ%}`}S8lmhO-imhNt(K_sLR$)!tLx=Xs277$SBlJ1731Vowz=?3Zg&+~iV z&(7xT&dko7bD#UZuJ4J_)KJ2~qQnA$KsYMO^4h@jFmNxzKm#68ghPw|d$N&zBMSo6 zCSpIBqXO^gES0t2fIy#^L7?Dp5a}8Jvrto# z2R;9H`_fUC3Ved@q4Gun9f5&KKqqi%7L*GDS;(r$%f9njJj(O*HyLWV4stik(&t#< z8%}}4Yd8PUi{lDSeYH!8ENseM6)H)~`sIhsT9Rau{S`+5ry+(29S*J=ChZH&@W$&1 zqW6x(mUyfNjUm>e zmNd4+AeLXbmRQXV?Z4F%bOYKP0~B8kVoOBAh}CL|asGR`Ye53Mv`GTCumJ|v|NpOS zt?-0>ov~vg#I)k002Wtj^!%L{pcJMMd?b*WAt`ezCdXK>MQt~(j`EdFm9+QdgOhf7ad@%12FyZ1bLkG%Shyuz#( zyx$GM9HEIr7YY2?F;J)>DOV;oZq#N4f2!Yci_I?%`4lEF4vx92D}JFS#`kyje`$fT=s=`ZDy8D*x8-J_$|etuMU_jmZ@yF=Y(+@WD%s7l0TGco7qAJZ~2aE+&l zMwXYB;zB|~%(D*m_cgT)zw^E=ka|gzc-;U$^8t4RbciejYFi$koG3sdZPY-`^bX-o5)$)Q%*m^Vds=haZgc9pvu9t?{#|xT}jS3>lex_k=2A zVe4aId%M3jY$VTnmGzBP#O1$#bodxDC#@E%4`+u&vsE^Dh~ z;FO|hh0_uHkjkHiVrcm$lF4Hff$}#AFwmy`i!hb&Xyt8`#L+&roqrB7C;#s#fIal$ zYwY;GlpQYD zY-CW-lIKg7zlhoV({|6*bF5 zW6Ms_*RLo73L(E}P>AV4BY~#GTcbpcv8m^5%Ea=g_FH@Gx&mHI`D9ZIzF2-rTObe*<<+bdEk+_?#$Z>I)6Gg zJ#+0P(L!Tvjt>vv4mM3gVV(!V7Atp`r}vMHHl(u@9{%w6d1W;RmGf>tF27ksE^J(W z(lRs@ry5MO1hm-Hzl#J1@8Zax z8M>F5yZym>2WEC5CTuW_+Cgm)qV3CnSxrxXNzOLvC}cUB##+3J!`jag%dk(iv+--J zS`PRhhS1;MOj#{k{aS}BXOx7~>)|{@n{FPSo?GLTm-Rb{Ut?9&lJ(9!0zB9e?>B6wrd}t-78lSn?izdX&camxoeWE)i+2 zsiT9OU8=OKb$53Mh6{{uvK1-^{x|%R8v?W6&Ek+wuyzbfOR|P-I0^ zgnW(@r5vadHdXx6w9+kXv~9o<`ScXX$lqu27>Ql;@sbjzUcu*p@3j2|GXw>5$<&v^ z&+9~vhdg-cXmDT9q1Nk23}22p*AQR6KhhlN1cHKsmf0%15!hr>A{h!sK|#_O)4EuF z7JaulwYF#4zRUy)(fhVl@%y0<*<@3T%b(u{><3Cb&aTzEA}rJkM2V=mgEvK7CGZk- zXe97Vea9~(`1YTDX{cF-CrAA#F8N2zi|=UYQA*MUqZK!l2j$Gj70WB$v7xrDNC`o+ zdwj{92a6QOCWarLs8+EHCZl{W$hx;YHm|$xad2OXMbA0>rpUUDv8IWYPmaY4(favj zXdDi!IqOxcF+*5@RCk1Uu<_+zNJ>iHY)uA54h|{`2uz^S6Vn9Vu-Mv*C8U?nC&U|C zj@xV#Z>Pjkf)yChpeiXqm`AvZC`yMdd(6Bk&X)x)L4%GaXx)bz1SDs!x+`0rsjYEZb%56~D+#$rFeF*r6?!;ixJPpgW38$oAuhF1oGro%o zj`Yy{om$7aPaH;d{_^m;sPxCYBd5ydor$H>9HnP)!K5^}KH3!mZtF8N8&Y#V>6W4O zF%4fjnB+TvrhACRcer#Qxh8AzzE%FF!k0CRdpH}*QJo!&ik&Hw#)Pkxb|C*1WIfF! z8_uLfCy%5+AOO#gJCXipDbGl7N*$HWszV>mz%p8q^w|AhiAT=P%+C6-US zlyxC`bP7ts=IO7l{2rMgZWLLWqtAv04URaVg|19_OidHv*iznNH-d!Y1vG3m@NvqIx}MKIg&p+^fn21B$qyVM6vCKWm6@g9qjg|C|Em|JI2 zYfpqtYZvAbqJD#4?#>CnNZ8B^uZ?Y>B#l@;3w;%QI5C z?}P>QN*fNT*Izghp?!)*84h;7dSqXy!kC$mvCMbuM(XDr29)rk27&>ED-!7Ha5cj4 z5{D-XZiK3wf+DBla~lyvPmHy3d@qHBk5y|x9CY`{Xwdc~p`OEwP5dhKE%VvX+7opS zS0^}KR}deC02mCr`QJVfWWM)g#CR1_q<}ArqAA>$>=y_@16^pDm7eL);bnUFUNsW!i7*dKs>&b7p9GEkLv9AmRs*msRM~Fs zz$YSjUK2=nPOy*9+tahKRdH1rUx78z_d4OI`A|~0+p1O$Khoyvc5MBho{Ta$p*e3z zGAz0XLnQ^=HMMtD1XbmC2A>sSl6o20np|qJqEwshQT(rf< z0&iIPQAxQDNiP07@Mt{^5kKyG8~E@2vYQJdh63WlTVb7>T|Qh#vDBY2zfBKGA3jgafdqW1S$%gi&xRp_Ch-Mzg* zZrUeIsmBHGkRrR5dSybfRt-b}ux%u6v(Z_*KR!JJwoZ165bFNTAYbB;Zn`SJwaS`> zmw&E$>vs>1LYP!wT|TJxWs{*YF~M}C(0noEar9QR8Bbi#zcec1;>&^W=4TUPZ%fDu zl#Cttk;1}&a1bx7&KP*t-JsS=q~-1LBE91tJ=2} zCGKwurWSvNXFgpLb9Ek4@_-%8(2`eFvkYbCX0vR?XVK%T^5&9CRkCE6R7RJ$>c!vJ zEFPlKrfIXiq0)i`GZ15hY!HpkIM19F`%E^@hZRzci!fn|)VR>^maY5;0WP|huB3txuI%aumbBuL`qk(Pti^boA%uSy`j0L{pqysp zVu{t7Hmq<*Dk66t;_e;V8>Xs&lX!!cPw|5sDuku88hv@!{uo6N1UsHoFt+fA*xwn< z6$YNT85|$t8KZF58=bg&K4_!K;=8WIH@!}iwOxliTetZ-f@0B|#laG74H)FIxQI-0p z$kp?SK@w+V|2#a`AL6(bnE1lWU2cL0)jfc&AU6fGYnGJKtPoAK76=HO)=W*P&P)W6 z>*fL5X20mGi;bh_UWcfnD9n7Zr3734VoM;D$4GOOsTcvr7F`%b=E$CBE%5SQUtexK zC9X!f|90tqL)#3r02RWgiwAd+X%Dc#I2}z~2$Z~k)2+hDugc3PZ^Wu5XcBkX>sm=> zx?+$6qYk^s6D9#A!Wj6Rl~uaO&o{P~V!hga`SJ2Ie&XXT-pzSf!9a14FCpE6;DE!D z>EJ-730E~gE7m2B`})rK zr67hE^74Mh*gs9KXh7$^!h8ZKO+)NK@3TyEa&XNTKO35nQ-&&ol2gjw&t0yIYU0bx zIOenKeyjh>=f2nQbG-a+)yBeE%8k09^O><3F=*_%HFttaHxj2GaeLbHXzSoKC`tPO zLFxeoK5a(PsmPeQ%EXyUecS~B5#x1`i!c-B7Yap7G=g*-LhU3&VjoR>*_l%QgwpUN z|7~?NVg>di3F>-#o~a|65&j)tGLz5GzPoM8Ohm3Cx!EE87FxF``K1J4v>qO?NPgdg zf|}dK(e>_x64S#aUZUBY=*|f8jxx;mg+RYVhDwesmaYjOjRF&)teu_VL}>1=BKd-_ zt^^J~KDD$Liu(>HsBid~WL7~e7>G5ew`!-oUHJnMIo!w!BgPGhPun{{Sb@USp%_Ks z<<)JN($8ntu8(iLdp9q_isTy_1vW38xDln|QYe_9R}lWBx+KQX=$=kz19(M<0!|Ap zraK#rtQ92mS6wpi$?_Rm=iR{M#?#v%+=JgP@4Woe7PQTQ+5srg`Z^`s&PK<$Ef)V} zi7c!lo=v_w z>enS!`1*_0@qT`@Cg*E=-j5ki(ts$0FO81PL=P(2hfj*zHu;~ZyKWW|Pvc#lG2FMu zCxza<*uMIyhk|y`+fnr*g$`mo1I~UcAdBx~9jE(rC=*0$q#;lU9Tm7y9c!!yr5j4p z{(=?wQF~q7z#I;?5f5=(qMYsmgdqzSkpmXVOSvGI&L_6c)2z1}6MoX+7! zHhw8$A5*1n@J_XZT7tSew~j3ZVy8)UkN!r)=10H+m<&1_vNZ0(t{+?qO$%T zO~gad==Dw92EKvA@l(99au6sc9t({yAt$I%sLsWk7(K0h3}le7Ne9XE<@8&N%f(Bv z1I2_7Tm|vb7FP?dHD9syr-u0L&|@P{Q5W=A>Nj=6{j$yYvcQV@>daBrr4Tk3ae+KU z?baw2kLP}ad6swkEv3}QwIkP-6<4u%^mqIRl&43u4?gEGPpzr8HGfpZDik)(Xu~x- zvG+NcQ@@=|$Ds^w>|wI3p#Qq_k|a(4T`$75sJtB6v;dE``H?0!2$3=3Wb^W(O86;E zIjFoaZ%%n#>+*VxyUTx;We-}vFl7!Dvmmq_?l#h=6vEdf-|rD9pu)N~(GJP?rz!!y3Zs( z?mCNt+7b+jw{9AyX+Ec_ad&vA_r&5x^|`Jy#4?B^54P;M$Qt@aIQNuZs1*j~)syQ* zl8&r{462KPvLlxMyjGnG|z4PrA zf^7ID5=LwiSO~wU;{y3JVM&P#o_plxlxH1DzvxauFd6FFs8a%`nPZe+5n`aB;Zq()46`8I3;?zBvklpI zVl;GgrH(ka(wCBnL#aa?w7~=2Du-WrS%@%EkOIgl52J=(A>2rzH00#ujcS5~(1OWK z?@s)2zFJ!P7vjcp(+T`ZFJ2r*#{IpG;(qZWg21jV+u z&yK&xxoPLNBSs!bp2Gmy7goXKORUgyaM` zED4e3!!8%1Nz9}o6+^0E+A>3rgkolk1L?$H1Y3bvpl8+F z6T1kz14)Vi<;x4MH_5kPv^uxV!TS8wJba|M0i^OdEa0(z0i0po!=_bduN)`krAVxB z3WzwHNh4NCfbb41%1qsE)T?`2>TvlOO`3%NjxtYU%uZ#~txxxlw^;o+G;F~!P@gXq zhf0X}5)W_*B3a>9I~AOOM?eYK1!K>;$XSQr_5WD`R!Fg}B08ywTU=L=SnaBXUpHMA zvo;o`c1CUccR|*rK~1~`p2!Fh+z~56VA=C9N_|f?Cutt}Vytd)B6`j~V$MEbh*Bf@ zc4bVWu#h<-mPuuCweg3RckASj$^C<6SUv)5)K&8BxTh7kg+6tLv7&;)tI^RhY#x5)K_XO`ACCx6^wTO=|E3GxMRVVZyP5;nh8sGW1ylv3W^=J5-+ollL>g-TdpiMNUR{lR zeSe*wys&ezHK3AL>6I_+LbE+ykf_V9UsU(Q{x4iKRJ7Iy{2IZtXk_eq+8vnd=%6?> zA_UT=sqaHT$f<<5kSQi3SOZkbW-w5Ye9dW!Am&e@w+2nl$QjiJAwPbw)qpE=RO2x} zUoPS={JTo2+6ZrtB}O3_d55*~KJQQc0VlO+4OyXCP=56fuk08~JB`V9(81(Nu=QAm z1H29f@8>^Ry=6|IS&Y)8D=<6~NFC=;=?+E3cAdC$ul2vhdZ(wSLE~=2;&t+gND22? zRz$=gNmO{z2ad+~o4x7IP5|h6l=0iQvDjpsJuN#-&?Sb7xd& zgl^jCjPBP54#@ZGS1TAyGWZJr`AENAeNCK{8xzhjqME(U4dm67z5j%WH*Ceu(8X=I#ST zU6KGP)#=?a=8PFM(#nm$aeSc~Yz9*-ro#kpM&9^N?hL;G>J1-`$d@jTuV)Y)_%|M_ zjvHq_iXG|SR<*~hukOccZhxuOe!5)h;jm?N<)G}F5H{^OWAvjtH(4Ft_iAJL-14=7 z+L)__m|efxcj>=e5Gxz^Bx2a+9OmvKmoO?bm@)Dl>4<36s!h*>$@DB# z%TAV#q`kcxtPbyeD=M#!rxQ2+^1(tIQj{0iWZXmBm6;<|a2~k5`1R#AVm;(hxt|D9 z{jIxKAx?JYUo#9F=X06HPm7(aAVw15{Vs#b-@G_rkW5wkxvCupzY_hXL7hL2kf|## zJexzmsyQ}0CDj&_8mWiwxZ~c-!_#Ync2WYpZ05a8zFGnC_%{drZ^eHPNMfVGIEYI9 z0wp$5czJtr^bh5fa5Em;Xb6b{ftr5Bz~BY6^QsNTt;Z9##$>~TSY}N{h z08(coZ{K2FXo`GpG7WgKcZ0%TZ4&n;hYQIM4Vu4sS{xM^oN4M$qn5!HHejJ(?0`MW z&URK(?Z2|_{D#7wy^nxk_uERAFMagwMM}=5JvnVh((%u`Z1Zu0W`9Yqt~0{u zBtB|eYd#9t`1TB6d1q68i`yzgg;5(#d-rPzoH>;QTR%5WvbqaJb(GJBFN>hj-MKKD-g_>KHk2-S$Cr~SxYW+azr>*S z(@PXBIp#k4KI;Z)$o+bfhE0;HO_GXDl6uMM7PnM1Nx5EeMFlkuPJJ>k(gABHZacwc z5_}(R0&k_czf^98FSm%|Qcu#;#33Sro?bgYeEtzIWS1ARDayl)T{_2&!mS$F^`XOu zpSqrsvhbOvx(m#%R~beZYY4s63cj7{3H#<^E6^=Zd$di9Jv^i`g z@__K}Qj8q4<)BFD`|xziKG2+g{SG=Y4A16-nRa2cWAv?6uP)FeWNkJh!M6-L_o-j< zXZFGE;LrY76#ofQ$OV4*%=L5K>KM973x6hZLkzb@Y_`v(EcuMJjJrVXW{x(VJ5Bs}B)h z>_jU&AZ%n;tSVz+^28DJTKLnym&0|-=fkENa*sa{(;J4&?c}nI(SI9NL$aPq_yWO9 z*KOQAupgT_-1H6nGaa$xiwr2nur@PHYK@&}nB_D^Xb1>8CmdXwjxE<3zC!$J1pZEF zt8@-Jbcd581EI@O4>mW5E<%xu!N3CtTaTL=kjhUZC8wub`C{q1jdm|Dps`w7k)oLY zG5m^u0jM)d@P|Jip2C+-n#uIaJJvBj(QiA7kJYOPi8g+1tk2FB8&lsisE5x9&P>m* z;HL2I6UP>b{J5ymYBAU!`4)&hjc6#WD%6^Gq`TE|PWZ=9kCOOwr4Q)2J(-<%PE!IA zmO}~aiwA4y*`@R$NLt`5v-CD`M!UPFNecxb}ljZc6XYQCrkZi zP`@i2$k-Ma?V9(q4*;hgRV9tz?;Bh`tz;w{u)?i%aXyK)@i^V7*Kow?KV2|T?!c9X zM)YRK?T1I}Sh@b}!Pv`Y5wmWL_1~1y!TMmh9y-*%>*61rXVku{*J9&Xm9d|=PYY-l zxKY>w;}ASg)zs&=(+v!Ij9t&?T_5@#syjm`rEW-Sm`MTf0-=e)ZzE(|P(tz|H>&g5 ziNmCwT6oP%I6q)t1&E|{>8gmET1Ft=lKeFJL_+gCb|S+M_Uf#~@hT$%zaGQOelgBt zMsaKSEbRBV^@ThY(Sd;J>T*8z?Ok;vsPnTX%zqj=HSdJc_V`u#a#yw98HM-KFZ=CO z?jG%pTb9}anxN&<*mLCAR&NY&-Nc>H0-uK`5f}GbMtTWXKcTa8lNrT16wHZPto

d=eApjLq-=M5=}+q0J)B%)+8N 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 literal 0 HcmV?d00001 diff --git a/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md b/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md new file mode 100644 index 0000000..bcb6e78 --- /dev/null +++ b/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md @@ -0,0 +1,18 @@ +**17. 电话号码的字母组合** +--- +[https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/) + +给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 + +给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 +![017_Telephone-keypad2](https://raw.githubusercontent.com/hollischuang/algorithm/master/images/017_Telephone-keypad2.png) + +**示例:** + +``` +输入:"23" +输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. +``` + +**说明:** +尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 diff --git a/leetcode/064-minimumPathSum/README.md b/leetcode/064-minimumPathSum/README.md new file mode 100644 index 0000000..82630f9 --- /dev/null +++ b/leetcode/064-minimumPathSum/README.md @@ -0,0 +1,20 @@ +**64. 最小路径和** +--- +[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) + +给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 + +说明:每次只能向下或者向右移动一步。 + +**示例:** + +``` +输入: +[ + [1,3,1], + [1,5,1], + [4,2,1] +] +输出: 7 +解释: 因为路径 1→3→1→1→1 的总和最小。 +``` diff --git a/leetcode/064-minimumPathSum/official.md b/leetcode/064-minimumPathSum/official.md deleted file mode 100644 index ce1339d..0000000 --- a/leetcode/064-minimumPathSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**64. 最小路径和** ---- -[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) diff --git a/leetcode/070-ClimbingStairs/README.md b/leetcode/070-ClimbingStairs/README.md new file mode 100644 index 0000000..ae4b0e0 --- /dev/null +++ b/leetcode/070-ClimbingStairs/README.md @@ -0,0 +1,30 @@ +**70. 爬楼梯** +--- +[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) + +假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 + +每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? + +注意:给定 n 是一个正整数。 + +**示例 1:** + +``` +输入: 2 +输出: 2 +解释: 有两种方法可以爬到楼顶。 +1. 1 阶 + 1 阶 +2. 2 阶 +``` + +**示例 2:** + +``` +输入: 3 +输出: 3 +解释: 有三种方法可以爬到楼顶。 +1. 1 阶 + 1 阶 + 1 阶 +2. 1 阶 + 2 阶 +3. 2 阶 + 1 阶 +``` diff --git a/leetcode/070-ClimbingStairs/official.md b/leetcode/070-ClimbingStairs/official.md deleted file mode 100644 index 1d51693..0000000 --- a/leetcode/070-ClimbingStairs/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**70. 爬楼梯** ---- -[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) diff --git a/leetcode/279-PerfectSquares/README.md b/leetcode/279-PerfectSquares/README.md new file mode 100644 index 0000000..1131bfc --- /dev/null +++ b/leetcode/279-PerfectSquares/README.md @@ -0,0 +1,21 @@ +**279. 完全平方数** +--- +[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) + +给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 + +**示例 1:** + +``` +输入: n = 12 +输出: 3 +解释: 12 = 4 + 4 + 4. +``` + +**示例 2:** + +``` +输入: n = 13 +输出: 2 +解释: 13 = 4 + 9. +``` diff --git a/leetcode/279-PerfectSquares/official.md b/leetcode/279-PerfectSquares/official.md deleted file mode 100644 index f0a46e8..0000000 --- a/leetcode/279-PerfectSquares/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**279. 完全平方数** ---- -[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) diff --git a/leetcode/300-LongestIncreasingSubsequence/README.md b/leetcode/300-LongestIncreasingSubsequence/README.md new file mode 100644 index 0000000..3fd713d --- /dev/null +++ b/leetcode/300-LongestIncreasingSubsequence/README.md @@ -0,0 +1,22 @@ +**300. 最长上升子序列** +--- +[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) + +给定一个无序的整数数组,找到其中最长上升子序列的长度。 + +**示例:** + +``` +输入: [10,9,2,5,3,7,101,18] +输出: 4 +解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 +``` + +**说明:** + +* 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可 +* 你算法的时间复杂度应该为 O(n2) + +**进阶:** +你能将算法的时间复杂度降低到 O(n log n) 吗? + diff --git a/leetcode/300-LongestIncreasingSubsequence/official.md b/leetcode/300-LongestIncreasingSubsequence/official.md deleted file mode 100644 index 81ee403..0000000 --- a/leetcode/300-LongestIncreasingSubsequence/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**300. 最长上升子序列** ---- -[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) diff --git a/leetcode/303-rangeSumQueryImmutable/README.md b/leetcode/303-rangeSumQueryImmutable/README.md new file mode 100644 index 0000000..1dfa33e --- /dev/null +++ b/leetcode/303-rangeSumQueryImmutable/README.md @@ -0,0 +1,20 @@ +**303. 区域和检索 - 数组不可变** +--- +[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) + +给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。 + +**示例:** + +``` +给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange() + +sumRange(0, 2) -> 1 +sumRange(2, 5) -> -1 +sumRange(0, 5) -> -3 +``` + +**说明:** + +1. 你可以假设数组不可变。 +2. 会多次调用 sumRange 方法。 diff --git a/leetcode/303-rangeSumQueryImmutable/official.md b/leetcode/303-rangeSumQueryImmutable/official.md deleted file mode 100644 index 3a7024f..0000000 --- a/leetcode/303-rangeSumQueryImmutable/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**303. 区域和检索 - 数组不可变** ---- -[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) diff --git a/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md b/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md new file mode 100644 index 0000000..f3c38d0 --- /dev/null +++ b/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md @@ -0,0 +1,18 @@ +**303. 区域和检索 - 数组不可变** +--- +[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) + +给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​ + +设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): + +* 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票) +* 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天) + +**示例:** + +``` +输入: [1,2,3,0,2] +输出: 3 +解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出] +``` diff --git a/leetcode/343-IntegerBreak/README.md b/leetcode/343-IntegerBreak/README.md new file mode 100644 index 0000000..a41a2c6 --- /dev/null +++ b/leetcode/343-IntegerBreak/README.md @@ -0,0 +1,24 @@ +**343. 整数拆分** +--- +[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) + +给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 + +**示例 1:** + +``` +输入: 2 +输出: 1 +解释: 2 = 1 + 1, 1 × 1 = 1。 +``` + +**示例 2:** + +``` +输入: 10 +输出: 36 +解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 +``` + +说明: 你可以假设 n 不小于 2 且不大于 58。 + diff --git a/leetcode/343-IntegerBreak/official.md b/leetcode/343-IntegerBreak/official.md deleted file mode 100644 index 16e682f..0000000 --- a/leetcode/343-IntegerBreak/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**343. 整数拆分** ---- -[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) diff --git a/leetcode/403-FrogJump/official.md b/leetcode/403-FrogJump/official.md deleted file mode 100644 index bfb5af2..0000000 --- a/leetcode/403-FrogJump/official.md +++ /dev/null @@ -1,47 +0,0 @@ -**403. 青蛙过河** ---- -[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) - -**难度** -困难 - -**题目描述** - -一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 - -给定石子的位置列表(用单元格序号升序表示), **请判定青蛙能否成功过河**(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 - -如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 - -**请注意:** - -* 石子的数量 ≥ 2 且 < 1100; -* 每一个石子的位置序号都是一个非负整数,且其 < 231; -* 第一个石子的位置永远是0。 - -**示例 1:** -```shell -[0,1,3,5,6,8,12,17] - -总共有8个石子。 -第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, -第三个石子在序号为3的单元格的位置, 以此定义整个数组... -最后一个石子处于序号为17的单元格的位置。 - -返回 true。即青蛙可以成功过河,按照如下方案跳跃: -跳1个单位到第2块石子, 然后跳2个单位到第3块石子, 接着 -跳2个单位到第4块石子, 然后跳3个单位到第6块石子, -跳4个单位到第7块石子, 最后,跳5个单位到第8个石子(即最后一块石子)。 -``` - -**示例 2:** -```shell - -[0,1,2,3,4,8,9,11] - -返回 false。青蛙没有办法过河。 -这是因为第5和第6个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。 -``` - -**相关话题** -贪心算法,动态规划 \ No newline at end of file diff --git a/leetcode/416-PartitionEqualSubsetSum/README.md b/leetcode/416-PartitionEqualSubsetSum/README.md new file mode 100644 index 0000000..ff4db77 --- /dev/null +++ b/leetcode/416-PartitionEqualSubsetSum/README.md @@ -0,0 +1,30 @@ +**416. 分割等和子集** +--- +[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) + +给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 + +**注意:** + +1. 每个数组中的元素不会超过 100 +2. 数组的大小不会超过 200 + +**示例 1:** + +``` +输入: [1, 5, 11, 5] + +输出: true + +解释: 数组可以分割成 [1, 5, 5] 和 [11]. +``` + +**示例 2:** + +``` +输入: [1, 2, 3, 5] + +输出: false +``` + +解释: 数组不能分割成两个元素和相等的子集. diff --git a/leetcode/416-PartitionEqualSubsetSum/official.md b/leetcode/416-PartitionEqualSubsetSum/official.md deleted file mode 100644 index 2f25f64..0000000 --- a/leetcode/416-PartitionEqualSubsetSum/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**416. 分割等和子集** ---- -[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) diff --git a/leetcode/583-DeleteOperationForTwoStrings/README.md b/leetcode/583-DeleteOperationForTwoStrings/README.md new file mode 100644 index 0000000..bd64857 --- /dev/null +++ b/leetcode/583-DeleteOperationForTwoStrings/README.md @@ -0,0 +1,18 @@ +**583. 两个字符串的删除操作** +--- +[https://leetcode-cn.com/problems/delete-operation-for-two-strings/](https://leetcode-cn.com/problems/delete-operation-for-two-strings/) + +给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。 + +**示例 1:** + +``` +输入: "sea", "eat" +输出: 2 +解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea" +``` + +**说明:** + +* 给定单词的长度不超过500 +* 给定单词中的字符只含有小写字母 diff --git a/leetcode/673-NumberOfLongestIncreasingSubsequence/official.md b/leetcode/673-NumberOfLongestIncreasingSubsequence/README.md similarity index 100% rename from leetcode/673-NumberOfLongestIncreasingSubsequence/official.md rename to leetcode/673-NumberOfLongestIncreasingSubsequence/README.md diff --git a/leetcode/695-MaxAreaOfIsland/README.md b/leetcode/695-MaxAreaOfIsland/README.md new file mode 100644 index 0000000..aa90a11 --- /dev/null +++ b/leetcode/695-MaxAreaOfIsland/README.md @@ -0,0 +1,28 @@ +**695. 岛屿的最大面积** +--- +[https://leetcode-cn.com/problems/max-area-of-island/](https://leetcode-cn.com/problems/max-area-of-island/) + +给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。 + +找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。) + +**示例 1:** + +``` +[[0,0,1,0,0,0,0,1,0,0,0,0,0], + [0,0,0,0,0,0,0,1,1,1,0,0,0], + [0,1,1,0,1,0,0,0,0,0,0,0,0], + [0,1,0,0,1,1,0,0,1,0,1,0,0], + [0,1,0,0,1,1,0,0,1,1,1,0,0], + [0,0,0,0,0,0,0,0,0,0,1,0,0], + [0,0,0,0,0,0,0,1,1,1,0,0,0], + [0,0,0,0,0,0,0,1,1,0,0,0,0]] +``` + +对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。 + +**示例 2:** + +``` +[[0,0,0,0,0,0,0,0]] +``` From 49a308b6c06be672ee2eb0cad2fd19b547d5591e Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:07:21 +0800 Subject: [PATCH 36/66] Create zengdiqing.md --- leetcode/006-ZigZagConversion/zengdiqing.md | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 leetcode/006-ZigZagConversion/zengdiqing.md diff --git a/leetcode/006-ZigZagConversion/zengdiqing.md b/leetcode/006-ZigZagConversion/zengdiqing.md new file mode 100644 index 0000000..1882f4c --- /dev/null +++ b/leetcode/006-ZigZagConversion/zengdiqing.md @@ -0,0 +1,51 @@ +6.将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 + +比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: + +L C I R +E T O E S I I G +E D H N +之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。 + +请你实现这个将字符串进行指定行数变换的函数: + +string convert(string s, int numRows); +示例 1: + +输入: s = "LEETCODEISHIRING", numRows = 3 +输出: "LCIRETOESIIGEDHN" +示例 2: + +输入: s = "LEETCODEISHIRING", numRows = 4 +输出: "LDREOEIIECIHNTSG" +解释: + +L D R +E O E I I +E C I H N +T S G + +思路:idx从0开始,自增直到numRows-1,此后又一直自减到0,重复执行。 + +从第一行开始往下,走到第四行又往上走,这里用 step = 1 代表往下走, step = -1 代表往上走 + +因为只会有一次遍历,同时把每一行的元素都存下来,所以时间复杂度和空间复杂度都是 O(N) + +```py +class Solution: + def convert(self, s: str, numRows: int) -> str: + if numRows==1 or numRows>=len(s): + return s #判断情况 + res = [''] * numRows #初始化res结果 + idx, step = 0, 1 + for c in s: + res[idx] += c #把字符加入res中 + if idx == 0: + step = 1 #step向下加一 + elif idx == numRows-1: #一直到最后一行为止 + step = -1 #向上操作 + idx += step #idx代表第几行 + return ''.join(res) +``` +时间复杂度: O(n) +空间复杂度: O(1) From 69c011cd7fa1ffd6c547af881bda622607a9ccf4 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:20:51 +0800 Subject: [PATCH 37/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md diff --git a/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md b/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md new file mode 100644 index 0000000..2933550 --- /dev/null +++ b/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md @@ -0,0 +1,64 @@ +33.假设按照升序排序的数组在预先未知的某个点上进行了旋转。 + +( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 + +搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 + +你可以假设数组中不存在重复的元素。 + +你的算法时间复杂度必须是 O(log n) 级别。 + +示例 1: + +输入: nums = [4,5,6,7,0,1,2], target = 0 +输出: 4 +示例 2: + +输入: nums = [4,5,6,7,0,1,2], target = 3 +输出: -1 + +思路:二分法 + +这道题让在旋转数组中搜索一个给定值,若存在返回坐标,若不存在返回-1。我们还是考虑二分搜索法,但是这道题的难点在于我们不知道原数组在哪旋转了,我们还是 +用题目中给的例子来分析,对于数组[0 1 2 4 5 6 7] 共有下列七种旋转方法: + +0  1  2   **4  5  6  7** + +7  0  1   2  4  5  6 + +6  7  0   1  2  4  5 + +5  6  7   0  1  2  4 + +4  5  6  7  0  1  2 + +2  4  5  6  7  0  1 + +1  2  4  5  6  7  0 + +二分搜索法的关键在于获得了中间数后,判断下面要搜索左半段还是右半段,我们观察上面粗体的数字都是升序的,由此我们可以观察出规律,如果中间的数小于最右边 +的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留 +哪半边了. + +```py +def search(nums,target): + l, r = 0, len(nums) - 1 + while l < r: + mid = l + ((r-l)>>2) + if nums[mid] == target: + return mid + if nums[mid] < nums[r]: + if nums[mid] < target <= nums[r]: + l = mid + 1 + else: + r = mid - 1 + else: + if nums[l] <= target < nums[mid] + r = mid - 1 + else: + l = mid + 1 + return -1 +``` + +时间复杂度:O(lgn) +空间复杂度:O(1) From 6d854b2cf7e8c4f94d6b7e244727f94d749b7e20 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:23:02 +0800 Subject: [PATCH 38/66] Create zengdiqing.md --- leetcode/048-RotateImage/zengdiqing.md | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 leetcode/048-RotateImage/zengdiqing.md diff --git a/leetcode/048-RotateImage/zengdiqing.md b/leetcode/048-RotateImage/zengdiqing.md new file mode 100644 index 0000000..9bea58f --- /dev/null +++ b/leetcode/048-RotateImage/zengdiqing.md @@ -0,0 +1,51 @@ +48.你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。 + +示例 1: + +给定 matrix = +[ + [1,2,3], + [4,5,6], + [7,8,9] +], + +原地旋转输入矩阵,使其变为: +[ + [7,4,1], + [8,5,2], + [9,6,3] +] +示例 2: + +给定 matrix = +[ + [ 5, 1, 9,11], + [ 2, 4, 8,10], + [13, 3, 6, 7], + [15,14,12,16] +], + +原地旋转输入矩阵,使其变为: +[ + [15,13, 2, 5], + [14, 3, 4, 1], + [12, 6, 8, 9], + [16, 7,10,11] +] + +思路:先用一个临时变量放置非对角线的数字,然后再把几行数组反过来排列 + +``` +def rotate(matrix): + length = len(matrix) + for i in range(length): + for j in range(i+1,length): + temp = matrix[i][j] + matrix[i][j] = matrix[j][i] + matrix[j][i] = temp + for i in range(length): + matrix[i] = matrix[i][::-1] + return matrix +``` +时间复杂度:O(n^2) +空间复杂度:O(n) From 3ec8f984dc161e0da05923e0eaef191e470cd828 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:24:07 +0800 Subject: [PATCH 39/66] Create zengdiqing1994.md --- leetcode/054-SpiralMatrix/zengdiqing1994.md | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 leetcode/054-SpiralMatrix/zengdiqing1994.md diff --git a/leetcode/054-SpiralMatrix/zengdiqing1994.md b/leetcode/054-SpiralMatrix/zengdiqing1994.md new file mode 100644 index 0000000..0690c7f --- /dev/null +++ b/leetcode/054-SpiralMatrix/zengdiqing1994.md @@ -0,0 +1,56 @@ +54.给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 + +示例 1: + +输入: +[ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] +输出: [1,2,3,6,9,8,7,4,5] +示例 2: + +输入: +[ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9,10,11,12] +] +输出: [1,2,3,4,8,12,11,10,9,5,6,7] + +思路:用四个变量来控制辩解,方向总是“左右上下”,这个和Z字形变换很像。 + +```py +def spiralOrder(matrix): + if matrix == []: + return [] + res = [] + maxUp = maxLeft = 0 + maxDown = len(matrix) - 1 + maxRight = len(matrix[0]) - 1 + direction = 0 # 0 go right , 1 go down, 2 go left, 3 up + while True: + if direction == 0: # go right + for i in range(maxLeft,maxRight+1): + res.append(matrix[maxUp][i]) + maxUp += 1 + elif direction == 1: # 1 go down + for i in range(maxUp,maxDown+1): + res.append(matrix[i][maxRight]) + maxRight -= 1 + elif direction == 2: # go left + for i in reversed(range(maxLeft,maxRight+1)): + res.append(matrix[maxDown][i]) + maxDown -= 1 + else: # go up + for i in reversed(range(maxUp,maxDown+1)): + res.append(matrix[i][maxLeft]) + maxLeft += 1 + if maxUp > maxDown or maxLeft > maxRight: + return res + direction = (direction + 1) % 4 # direction = 3之后就是0重新开始 +``` +时间复杂度:O(m*n) + +空间复杂度:O(1) From 77d0f71f08cde277306e6ad061f170b0536e5c10 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:27:32 +0800 Subject: [PATCH 40/66] Create zengdiqing1994.md --- leetcode/059-SpiralMatrixII/zengdiqing1994.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 leetcode/059-SpiralMatrixII/zengdiqing1994.md diff --git a/leetcode/059-SpiralMatrixII/zengdiqing1994.md b/leetcode/059-SpiralMatrixII/zengdiqing1994.md new file mode 100644 index 0000000..e4d7bad --- /dev/null +++ b/leetcode/059-SpiralMatrixII/zengdiqing1994.md @@ -0,0 +1,49 @@ +59.给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 + +示例: + +输入: 3 +输出: +[ + [ 1, 2, 3 ], + [ 8, 9, 4 ], + [ 7, 6, 5 ] +] + +思路:和之前的那道螺旋矩阵题类似,只不过这次要自己生成一个矩阵 + +```py +class Solution: + def generateMatrix(self, n: int) -> List[List[int]]: + curNum = 0 + matrix = [[0 for i in range(n)] for j in range(n)] #生成一个矩阵 + maxUp = maxLeft = 0 + maxDown = maxRight = n - 1 + direction = 0 + while True: + if direction == 0: + for i in range(maxLeft,maxRight+1): + curNum += 1 + matrix[maxUp][i] = curNum #依次按顺序递增赋值 + maxUp += 1 + elif direction == 1: + for i in range(maxUp,maxDown+1): + curNum += 1 + matrix[i][maxRight] = curNum + maxRight -= 1 + elif direction == 2: + for i in reversed(range(maxLeft,maxRight+1)): + curNum += 1 + matrix[maxDown][i] = curNum + maxDown -= 1 + else: + for i in reversed(range(maxUp,maxDown+1)): + curNum += 1 + matrix[i][maxLeft] = curNum + maxLeft += 1 + if curNum >= n*n: + return matrix + direction = (direction + 1) % 4 +``` +时间复杂度O(N^2) +空间复杂度O(N) From 986ad7716d09f9c86227e35ada250e438e91cf00 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:29:59 +0800 Subject: [PATCH 41/66] Create zengdiqing1994.md --- .../053-maximumSubarray/zengdiqing1994.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 leetcode/053-maximumSubarray/zengdiqing1994.md diff --git a/leetcode/053-maximumSubarray/zengdiqing1994.md b/leetcode/053-maximumSubarray/zengdiqing1994.md new file mode 100644 index 0000000..4c4c9e1 --- /dev/null +++ b/leetcode/053-maximumSubarray/zengdiqing1994.md @@ -0,0 +1,26 @@ +53.给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 + +示例: + +输入: [-2,1,-3,4,-1,2,1,-5,4], +输出: 6 +解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 + +思路:用DP来求解,只关注:当前值和当前值+过去的状态,是变好还是变坏 + +状态定义方程:maxSum = [nums[0] for i in range(n)] + +状态转移:maxSum[i] = max(maxSum[i-1] + nums[i],nums[i]),一个是加上nums[i]的,另一个是从a[i]起头,重新开始。 + +```py +class Solution: + def maxSubArray(self, nums: List[int]) -> int: + n = len(nums) + maxSum = [nums[0] for i in range(n)] + for i in range(1,n): + maxSum[i] = max(maxSum[i-1] + nums[i],nums[i]) + return max(maxSum) +``` + +时间复杂度O(n) +空间复杂度O(1) From 3fc4f5d2bd18c4a47ce271d1514e1319649cc29a Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:31:10 +0800 Subject: [PATCH 42/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 leetcode/152-MaximumProductSubarray/zengdiqing1994.md diff --git a/leetcode/152-MaximumProductSubarray/zengdiqing1994.md b/leetcode/152-MaximumProductSubarray/zengdiqing1994.md new file mode 100644 index 0000000..72aea9e --- /dev/null +++ b/leetcode/152-MaximumProductSubarray/zengdiqing1994.md @@ -0,0 +1,31 @@ +152.给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。 + +示例 1: + +输入: [2,3,-2,4] +输出: 6 +解释: 子数组 [2,3] 有最大乘积 6。 +示例 2: + +输入: [-2,0,-1] +输出: 0 +解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。 + +思路:乘积最大子序列,和53是不一样的,因为乘积可正可负,之前的DP方程不能保证结果。而且要用两个dp数组,其中maxdp[i]表示子数组[0, i]范围内并且一定包 +含nums[i]数字的最大子数组乘积,mindp[i]表示子数组[0, i]范围内并且一定包含nums[i]数字的最小子数组乘积,初始化时maxdp[0]和mindp[0]都初始化为 +nums[0],其余都初始化为0。那么从数组的第二个数字开始遍历,那么此时的最大值和最小值只会在这三个数字之间产生,即maxdp[i-1]*nums[i],mindp[i- +1]*nums[i],和nums[i]。所以我们用三者中的最大值来更新maxdp[i],用最小值来更新mindp[i],然后用maxdp[i]来更新结果res即可,由于最终的结果不一定会包 +括nums[n-1]这个数字,所以maxdp[n-1]不一定是最终解,不断更新的结果res才是,参见代码如下: + +```py +def solution(nums): + maxdp = [nums[0]]*len(nums) + mindp = [nums[0]]*len(nums) + + for i in range(1,len(nums)): + maxdp[i] = max(mindp[i-1]*nums[i],maxdp[i-1]*nums[i],nums[i]) + mindp[i] = min(maxdp[i-1]*nums[i],mindp[i-1]*nums[i],nums[i]) + return max(maxdp) +``` +时间复杂度O(n) +空间复杂度O(n) From daf2cf84ee49d7cfa44642a8b103273f6bbfbd1d Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 9 Apr 2019 10:33:24 +0800 Subject: [PATCH 43/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md diff --git a/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md b/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md new file mode 100644 index 0000000..cb21f72 --- /dev/null +++ b/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md @@ -0,0 +1,37 @@ +153.假设按照升序排序的数组在预先未知的某个点上进行了旋转。 + +( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 + +请找出其中最小的元素。 + +你可以假设数组中不存在重复元素。 + +示例 1: + +输入: [3,4,5,1,2] +输出: 1 +示例 2: + +输入: [4,5,6,7,0,1,2] +输出: 0 + +思路:首先要判断这个有序数组是否旋转了,通过比较第一个和最后一个数的大小,如果第一个数小,则没有旋转,直接返回这个数。如果第一个数大,就要进一步搜索。 +我们定义left和right两个指针分别指向开头和结尾,还要找到中间那个数,然后和left指的数比较,如果中间的数大,则继续二分查找右半段数组,反之查找左半段。 +终止条件是当左右两个指针相邻,返回小的那个。 + +```py +def solution(nums): + l, r = 0, len(nums) - 1 + while l <= r: + mid = l + ((r - l) >> 1) + if nums[mid] < nums[mid - 1]: + return nums[mid] + elif nums[mid] < nums[l]: + r = mid - 1 + elif nums[mid] > nums[r]: + l = mid + 1 + else: + return nums[i] +``` +时间复杂度O(lgN) +空间复杂度O(1) From 7a50b170a39b8a04ad1936feae6494cf288a9f53 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 9 Apr 2019 12:22:25 +0800 Subject: [PATCH 44/66] update --- leetcode/002-addTwoNumber/README.md | 17 +++++++++++ .../README.md | 30 +++++++++++++++++++ leetcode/076-MinimumWindowSubstring/README.md | 17 +++++++++++ 3 files changed, 64 insertions(+) create mode 100644 leetcode/002-addTwoNumber/README.md create mode 100644 leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md create mode 100644 leetcode/076-MinimumWindowSubstring/README.md diff --git a/leetcode/002-addTwoNumber/README.md b/leetcode/002-addTwoNumber/README.md new file mode 100644 index 0000000..8dc4992 --- /dev/null +++ b/leetcode/002-addTwoNumber/README.md @@ -0,0 +1,17 @@ +**2. 两数相加** +--- +[https://leetcode-cn.com/problems/add-two-numbers/](https://leetcode-cn.com/problems/add-two-numbers/) + +给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 + +如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 + +您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 + +**示例:** + +``` +输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) +输出:7 -> 0 -> 8 +原因:342 + 465 = 807 +``` diff --git a/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md b/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md new file mode 100644 index 0000000..f05424e --- /dev/null +++ b/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md @@ -0,0 +1,30 @@ +**3. 无重复字符的最长子串** +--- +[https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/](https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) + +给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 + +**示例 1:** + +``` +输入: "abcabcbb" +输出: 3 +解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 +``` + +**示例 2:** + +``` +输入: "bbbbb" +输出: 1 +解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 +``` + +**示例 3:** + +``` +输入: "pwwkew" +输出: 3 +解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 + 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 +``` diff --git a/leetcode/076-MinimumWindowSubstring/README.md b/leetcode/076-MinimumWindowSubstring/README.md new file mode 100644 index 0000000..7778718 --- /dev/null +++ b/leetcode/076-MinimumWindowSubstring/README.md @@ -0,0 +1,17 @@ +**76. 最小覆盖子串** +--- +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。 + +**示例:** + +``` +输入: S = "ADOBECODEBANC", T = "ABC" +输出: "BANC" +``` + +**说明:** + +* 如果 S 中不存这样的子串,则返回空字符串 ""。 +* 如果 S 中存在这样的子串,我们保证它是唯一的答案。 From a88b3134198c582795fb66a98f3dab9bd1ff132f Mon Sep 17 00:00:00 2001 From: bigablecat Date: Tue, 9 Apr 2019 12:24:15 +0800 Subject: [PATCH 45/66] update --- leetcode/076-MinimumWindowSubstring/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leetcode/076-MinimumWindowSubstring/README.md b/leetcode/076-MinimumWindowSubstring/README.md index 7778718..f43233d 100644 --- a/leetcode/076-MinimumWindowSubstring/README.md +++ b/leetcode/076-MinimumWindowSubstring/README.md @@ -1,6 +1,6 @@ **76. 最小覆盖子串** --- -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) +[https://leetcode-cn.com/problems/minimum-window-substring/](https://leetcode-cn.com/problems/minimum-window-substring/) 给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。 From c683e192b8719b88b8aa28cc346b2ae3e78679f5 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sun, 14 Apr 2019 18:44:20 +0800 Subject: [PATCH 46/66] Rename zengdiqing1994 to zengdiqing1994.md --- .../{zengdiqing1994 => zengdiqing1994.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename leetcode/513-FindBottomLeftTreeValue/{zengdiqing1994 => zengdiqing1994.md} (100%) diff --git a/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 b/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md similarity index 100% rename from leetcode/513-FindBottomLeftTreeValue/zengdiqing1994 rename to leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md From e68605ca1c75934c87d9649234bdfb1e5085768f Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sun, 14 Apr 2019 18:44:56 +0800 Subject: [PATCH 47/66] Update zengdiqing1994.md --- leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md b/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md index 1cbaf79..dfff351 100644 --- a/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md +++ b/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md @@ -5,7 +5,9 @@ 输入: 2 + / \ + 1 3 输出: From 7b1d5f59885baf911a6d2896128cf769b30219d9 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sun, 14 Apr 2019 18:49:50 +0800 Subject: [PATCH 48/66] Create zengdiqing1994.md --- leetcode/242-ValidAnagram/zengdiqing1994.md | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 leetcode/242-ValidAnagram/zengdiqing1994.md diff --git a/leetcode/242-ValidAnagram/zengdiqing1994.md b/leetcode/242-ValidAnagram/zengdiqing1994.md new file mode 100644 index 0000000..b2fe40b --- /dev/null +++ b/leetcode/242-ValidAnagram/zengdiqing1994.md @@ -0,0 +1,36 @@ +242.有效的异位字符串 + +给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。 + +示例 1: + +输入: s = "anagram", t = "nagaram" +输出: true +示例 2: + +输入: s = "rat", t = "car" +输出: false +说明: +你可以假设字符串只包含小写字母。 + +思路:使用哈希表,通过统计出现的次数,来判断,数量一致就可以。 + +```py +class Solution: + def isAnagram(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + dic1, dic2 = {}, {} + for item in s: + dic1[item] = dic1.get(item, 0) + 1 + for item in t: + dic2[item] = dic2.get(item, 0) + 1 + + return dic1 == dic2 +``` +时间复杂度:O(s*t) + +空间复杂度:O(n) From 60b7b7f5d1cbc1dcd41e2c141f762b5ac040f344 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Sun, 14 Apr 2019 18:57:11 +0800 Subject: [PATCH 49/66] Create zengdiqing1994.md --- .../zengdiqing1994.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md diff --git a/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md b/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md new file mode 100644 index 0000000..2bdab90 --- /dev/null +++ b/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md @@ -0,0 +1,42 @@ +3.给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 + +示例 1: + +输入: "abcabcbb" +输出: 3 +解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 +示例 2: + +输入: "bbbbb" +输出: 1 +解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 +示例 3: + +输入: "pwwkew" +输出: 3 +解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 + 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 + +思路: + +```py + def lengthOfLongestSubstring(self, s): + lookup = collections.defaultdict(int) + l, r, counter, res = 0, 0, 0, 0 # counter 为当前子串中 unique 字符的数量 + while r < len(s): + lookup[s[r]] += 1 + if lookup[s[r]] == 1: # 遇到了当前子串中未出现过的字符 + counter += 1 + r += 1 + # counter < r - l 说明有重复字符出现,否则 counter 应该等于 r - l + while l < r and counter < r - l: + lookup[s[l]] -= 1 + if lookup[s[l]] == 0: # 当前子串中的一种字符完全消失了 + counter -= 1 + l += 1 + res = max(res, r - l) # 当前子串满足条件了,更新最大长度 + return res +``` +时间复杂度:O(n^2) + +空间复杂度:O(n) From 7a64a41bd0974ff53c7c19eabab120639543576d Mon Sep 17 00:00:00 2001 From: bigablecat Date: Mon, 15 Apr 2019 22:51:17 +0800 Subject: [PATCH 50/66] update --- README.md | 158 +++++++++--------- leetcode/110-BalancedBinaryTree/bigablecat.md | 61 +++++++ leetcode/142-linkedListCycleII/bigablecat.md | 82 +++++++++ .../bigablecat.md | 52 ++++++ .../bigablecat.md | 4 +- .../208-implementTriePrefixTree/bigablecat.md | 135 +++++++++++++++ .../bigablecat.md | 54 ++++++ .../bigablecat.md | 4 +- .../bigablecat.md | 4 +- .../513-FindBottomLeftTreeValue/bigablecat.md | 48 ++++++ leetcode/785-IsGraphBipartite/bigablecat.md | 76 +++++++++ 11 files changed, 593 insertions(+), 85 deletions(-) create mode 100644 leetcode/110-BalancedBinaryTree/bigablecat.md create mode 100644 leetcode/144-BinaryTreePreorderTraversal/bigablecat.md create mode 100644 leetcode/208-implementTriePrefixTree/bigablecat.md create mode 100644 leetcode/230-KthSmallestElementInABST/bigablecat.md create mode 100644 leetcode/513-FindBottomLeftTreeValue/bigablecat.md create mode 100644 leetcode/785-IsGraphBipartite/bigablecat.md diff --git a/README.md b/README.md index c47855b..ac5cec1 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ [https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) -无官方题解,网友最高票Java答案: +无官方题解,网友最高票Java解法: [https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.](https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.) @@ -79,7 +79,7 @@ [https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) @@ -95,7 +95,7 @@ [https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments](https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments) @@ -175,7 +175,7 @@ [https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) @@ -207,7 +207,7 @@ [https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/sliding-window-maximum/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation](https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation) @@ -255,7 +255,7 @@ [https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution](https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution) @@ -271,11 +271,11 @@ [https://leetcode-cn.com/problems/validate-binary-search-tree/](https://leetcode-cn.com/problems/validate-binary-search-tree/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)](https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines](https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines) @@ -307,11 +307,11 @@ [https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers](https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers) @@ -343,11 +343,11 @@ [https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts](https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java](https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java) @@ -395,11 +395,11 @@ [https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)](https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)) @@ -431,11 +431,11 @@ [https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS) @@ -467,11 +467,11 @@ [https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.](https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.) @@ -487,11 +487,11 @@ [https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings](https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code](https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code) @@ -507,7 +507,7 @@ [https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking](https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking) @@ -523,7 +523,7 @@ [https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) @@ -539,7 +539,7 @@ [https://leetcode-cn.com/problems/valid-perfect-square/](https://leetcode-cn.com/problems/valid-perfect-square/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code](https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code) @@ -571,7 +571,7 @@ [https://leetcode-cn.com/problems/word-search-ii/](https://leetcode-cn.com/problems/word-search-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)](https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)) @@ -603,7 +603,7 @@ [https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) @@ -619,7 +619,7 @@ [https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount](https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount) @@ -635,11 +635,11 @@ [https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution](https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)) @@ -671,11 +671,11 @@ [https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle](https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution](https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution) @@ -691,11 +691,11 @@ [https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity](https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time](https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time) @@ -711,11 +711,11 @@ [https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution) @@ -747,7 +747,7 @@ [https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java) @@ -763,7 +763,7 @@ [https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) @@ -843,7 +843,7 @@ [https://leetcode-cn.com/problems/number-of-islands/](https://leetcode-cn.com/problems/number-of-islands/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution](https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution) @@ -859,11 +859,11 @@ [https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) -无官方题解,网友高票Java答案1(DFS): +无官方题解,网友高票Java解法1(DFS): [https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution](https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution) -无官方题解,网友高票Java答案2(Union Find): +无官方题解,网友高票Java解法2(Union Find): [https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) @@ -879,7 +879,7 @@ [https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)](https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)) @@ -935,7 +935,7 @@ [https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.) @@ -967,7 +967,7 @@ [https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) @@ -1031,11 +1031,11 @@ [https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space](https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)](https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)) @@ -1099,7 +1099,7 @@ [https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution](https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution) @@ -1179,7 +1179,7 @@ [https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) @@ -1195,7 +1195,7 @@ [https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments](https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments) @@ -1211,7 +1211,7 @@ [https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation](https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation) @@ -1243,7 +1243,7 @@ [https://leetcode-cn.com/problems/count-numbers-with-unique-digits/](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.) @@ -1275,7 +1275,7 @@ [https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution](https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution) @@ -1355,7 +1355,7 @@ [https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways](https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways) @@ -1371,7 +1371,7 @@ [https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) @@ -1387,11 +1387,11 @@ [https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand) @@ -1455,11 +1455,11 @@ [https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.](https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space](https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space) @@ -1475,7 +1475,7 @@ [https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/articles/push-dominoes/](https://leetcode.com/articles/push-dominoes/) @@ -1491,7 +1491,7 @@ [https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) @@ -1587,7 +1587,7 @@ [https://leetcode-cn.com/problems/house-robber-ii/](https://leetcode-cn.com/problems/house-robber-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation](https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation) @@ -1603,7 +1603,7 @@ [https://leetcode-cn.com/problems/largest-divisible-subset/](https://leetcode-cn.com/problems/largest-divisible-subset/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)](https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)) @@ -1619,7 +1619,7 @@ [https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP) @@ -1635,11 +1635,11 @@ [https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation](https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation](https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation) @@ -1671,11 +1671,11 @@ [https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm) @@ -1723,7 +1723,7 @@ [https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~](https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~) @@ -1771,7 +1771,7 @@ [https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.](https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.) @@ -1787,7 +1787,7 @@ [https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.](https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.) @@ -1819,7 +1819,7 @@ [https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space](https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space) @@ -1867,11 +1867,11 @@ [https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) -无官方题解,网友高票Java答案1: +无官方题解,网友高票Java解法1: [https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference](https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference) -无官方题解,网友高票Java答案2: +无官方题解,网友高票Java解法2: [https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation](https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation) @@ -1887,7 +1887,7 @@ [https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations](https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations) @@ -1903,7 +1903,7 @@ [https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)](https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)) @@ -1935,7 +1935,7 @@ [https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java](https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java) @@ -1983,7 +1983,7 @@ [https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space) @@ -1999,7 +1999,7 @@ [https://leetcode-cn.com/problems/remove-boxes/](https://leetcode-cn.com/problems/remove-boxes/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions](https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions) @@ -2015,7 +2015,7 @@ [https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution](https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution) @@ -2128,7 +2128,7 @@ [https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) @@ -2145,7 +2145,7 @@ [https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) -无官方题解,网友高票Java答案: +无官方题解,网友高票Java解法: [https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) diff --git a/leetcode/110-BalancedBinaryTree/bigablecat.md b/leetcode/110-BalancedBinaryTree/bigablecat.md new file mode 100644 index 0000000..ba0d8fd --- /dev/null +++ b/leetcode/110-BalancedBinaryTree/bigablecat.md @@ -0,0 +1,61 @@ +**110. 平衡二叉树** +--- +[https://leetcode-cn.com/problems/balanced-binary-tree/](https://leetcode-cn.com/problems/balanced-binary-tree/) + +* 网友高票Java解法: + +```java + + /** + * 网友高票Java解法 + * + * @param root + * @return + */ + public boolean isBalanced(TreeNode root) { + return height(root) != -1; + } + + /** + * 获取当前节点的树高 + * 如果是高度平衡的二叉树,返回树的真实高度 + * 如果不是高度平衡二叉树,返回-1 + * + * @param node + * @return + */ + public int height(TreeNode node) { + //检查当前节点是否为空 + if (node == null) { + //空节点返回0 + return 0; + } + //获取左子节点的树高 + int lH = height(node.left); + //如果返回-1,说明左子节点不符合题意 + if (lH == -1) { + return -1; + } + //同理判断右子节点 + int rH = height(node.right); + if (rH == -1) { + return -1; + } + //检查左右子节点高度差的绝对值是否不超过1 + if (lH - rH < -1 || lH - rH > 1) { + //绝对值超过1,不符合题意,返回-1 + return -1; + } + //Math.max(lH,rH)返回左右子节点中高度较大的一个 + //在子节点中较大的高度上+1,即当前节点自身的高度1 + //返回的最终结果就是当前节点的树高 + return Math.max(lH, rH) + 1; + } + +``` + +**参考资料** + +* 网友高票答案: +[https://leetcode.com/problems/balanced-binary-tree/discuss/35686/Java-solution-based-on-height-check-left-and-right-node-in-every-recursion-to-avoid-further-useless-search](https://leetcode.com/problems/balanced-binary-tree/discuss/35686/Java-solution-based-on-height-check-left-and-right-node-in-every-recursion-to-avoid-further-useless-search) + diff --git a/leetcode/142-linkedListCycleII/bigablecat.md b/leetcode/142-linkedListCycleII/bigablecat.md index 439a91c..d9131ac 100644 --- a/leetcode/142-linkedListCycleII/bigablecat.md +++ b/leetcode/142-linkedListCycleII/bigablecat.md @@ -1,3 +1,85 @@ **142. 环形链表 II** --- [https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) + +* 网友高票Java解法: + +```java + + /** + * 双指针法 + *

+ * 时间复杂度 O(n) + * 判断是否有环时,循环了n+k次,k是快指针比慢指针多跑的长度 + * 查找环的入口时循环了s次,s是从头节点到环入口的距离 + *

+ * 空间复杂度 O(1) 只使用了两个临时变量,空间复杂度为常数O(1) + * + * @param head + * @return + */ + public ListNode detectCycle(ListNode head) { + //快慢指针都从头节点出发 + ListNode slow = head; + ListNode fast = head; + boolean hasCycle = false; //判断是否有环的标识 + while (fast != null && fast.next != null) { + slow = slow.next;//慢指针每次走一步 + fast = fast.next.next;//快指针每次走两步 + + if (slow == fast) { //如果快指针等于慢指针,说明有环 + hasCycle = true; + break; //跳出循环 + } + } + //如果有环,第二次循环找出环的入口 + if (hasCycle) { + //设从头节点到环入口的长度为len + //从环入口到快慢指针相遇点的距离为h + //环的长度为r + //fast和slow走过的相同路段为len+h + //fast比slow多走的路段为m(m≥1且m是整数)个r,即m*r + //设slow走过的路程为s,s=len+h + //设fast走过的路程为f,f=(len+h)+m*r + //又知道fast走过的路程是slow的两倍,即f=2s + //2(len+h) = (len+h) + m*r + // len+h = m*r + // len = m*r - h + // 将公式右边变化以后更好理解 + // len = m*r - h = (m-1)*r + (r-h) + // 让两个指针分别从头节点和相遇点出发,以相同的速度前进 + // 一个指针走完len距离时,到达环形入口 + // 另一个指针围着环绕了(m-1)圈,并且从h位置出发,走了(r-h)步 + // 第二个指针最后到达的位置为 h+(r-h) = r 正好回到环形起点,即环形的入口 + // 最终两个指针会在环形入口处相遇 + slow = head; //让慢指针从头节点重新出发 + while (slow != fast) { //当两个节点未相遇时循环继续 + //慢指针和快指针各走一步 + slow = slow.next; + fast = fast.next; + } + return slow;//循环结束后返回的节点就是环形入口 + } + return null; + } + +``` + +**复杂度分析** + +时间复杂度: O(n), +判断是否有环时,循环了n+k次,k是快指针比慢指针多跑的长度 +查找环的入口时循环了s次,s是从头节点到环入口的距离 + +空间复杂度: O(1), +只使用了两个临时变量,空间复杂度为常数O(1) + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) + +* 《数据结构面试 之 单链表是否有环及环入口点 附有最详细明了的图解》: +[https://www.jianshu.com/p/ef71e04241e4](https://www.jianshu.com/p/ef71e04241e4) diff --git a/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md b/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md new file mode 100644 index 0000000..0a450e8 --- /dev/null +++ b/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md @@ -0,0 +1,52 @@ +**144. 二叉树的前序遍历** +--- +[https://leetcode-cn.com/problems/binary-tree-preorder-traversal/](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/) + +* 网友高票Java解法: + +```java + + /** + * 前序遍历(DLR),是二叉树遍历的一种,首先访问根结点然后遍历左子树,最后遍历右子树 + * + * 网友高票Java解法 + * + * @param node + * @return + */ + public List preorderTraversal(TreeNode node) { + //创建一个链表 + List list = new LinkedList(); + //创建一个栈对象,用于存储右节点 + Stack rights = new Stack(); + //当前节点非空时进行遍历 + while(node != null) { + //将当前节点的值存入链表 + list.add(node.val); + //如果当前节点存在右子节点 + if (node.right != null) { + //将右子节点存入栈 + rights.push(node.right); + } + //获取当前节点的左子节点并赋值给node + node = node.left; + //node == null表示刚才获取的左子节点为空 + //rights.isEmpty()表示存放右子节点的栈非空 + if (node == null && !rights.isEmpty()) { + //弹出栈最顶端的元素并赋值给node + node = rights.pop(); + } + //最终赋值的node将在下一次循环把val存入链表list + } + //返回最终结果 + return list; + } + +``` + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/binary-tree-preorder-traversal/discuss/45266/Accepted-iterative-solution-in-Java-using-stack.](https://leetcode.com/problems/binary-tree-preorder-traversal/discuss/45266/Accepted-iterative-solution-in-Java-using-stack.) diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md b/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md index fc90eaf..8632db6 100644 --- a/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md +++ b/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md @@ -2,7 +2,7 @@ --- [https://leetcode-cn.com/problems/intersection-of-two-linked-lists/](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) -* 网友高票java答案 +* 网友高票Java解法 ```java @@ -75,5 +75,5 @@ while循环最差情况是完整遍历两个链表, * 官方题解3:双指针法 [https://leetcode.com/articles/intersection-of-two-linked-lists/](https://leetcode.com/articles/intersection-of-two-linked-lists/) -* 网友高票Java答案: +* 网友高票Java解法: [https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!](https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!) diff --git a/leetcode/208-implementTriePrefixTree/bigablecat.md b/leetcode/208-implementTriePrefixTree/bigablecat.md new file mode 100644 index 0000000..859ee7c --- /dev/null +++ b/leetcode/208-implementTriePrefixTree/bigablecat.md @@ -0,0 +1,135 @@ +**208. 实现 Trie (前缀树)** +--- +[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) + +* 英文官方题解: + +```java + +public class Trie { + /** + * 英文官方题解 + * + */ + class TrieNode { + + // 节点的R个连接,将用于存放英文26个小写字母 + private TrieNode[] links; + + // R = 26 表示英文26个小写字母的个数 + private final int R = 26; + + //判断Trie树是否已经到底 + private boolean isEnd; + + //构造函数,创建一个大小为R的TrieNode + public TrieNode() { + links = new TrieNode[R]; + } + + //是否包含某个字符ch + public boolean containsKey(char ch) { + //ch -'a'得到字符ch为英文字母表第几个字符 + //从links中获取第ch -'a'个字符对应的节点 + // 并判断节点是否为null + return links[ch -'a'] != null; + } + + //获取第ch -'a'个字符对应的节点 + public TrieNode get(char ch) { + return links[ch -'a']; + } + + //将当前字符ch存入节点node + public void put(char ch, TrieNode node) { + links[ch -'a'] = node; + } + + //设置Trie树的终点 + public void setEnd() { + isEnd = true; + } + + //判断是否到达终点 + public boolean isEnd() { + return isEnd; + } + } + + //私有变量根结点root + private TrieNode root; + + //构造方法,获得一个Trie树 + public Trie() { + //根结点赋值为新的TrieNode + root = new TrieNode(); + } + + // 在Trie中插入一个词word + public void insert(String word) { + //将root节点赋值给一个临时变量node + TrieNode node = root; + //遍历word的每一个字符 + for (int i = 0; i < word.length(); i++) { + //获取当前位置的字符,赋值给currentChar + char currentChar = word.charAt(i); + //如果node不包含当前字符 + if (!node.containsKey(currentChar)) { + //将当前字符赋值给一个新的TrieNode,并存入node节点 + node.put(currentChar, new TrieNode()); + } + //获取包含当前字符的节点并赋值给临时变量node + node = node.get(currentChar); + } + //为node设置结束标识 + node.setEnd(); + } + + // 在Trie树中搜索包含输入word的节点,并返回字符终结的节点 + private TrieNode searchPrefix(String word) { + //将根结点root赋值给临时变量node + TrieNode node = root; + //遍历word的每一个字符 + for (int i = 0; i < word.length(); i++) { + //获取当前位置的字符,赋值给curLetter + char curLetter = word.charAt(i); + //查看节点node是否包含curLetter + if (node.containsKey(curLetter)) { + //get方法获取包含curLetter的节点并赋值给临时变量node + node = node.get(curLetter); + } else { + //否则返回null + return null; + } + } + //返回终点node + return node; + } + + // 查找Trie是否包含当前输入word + public boolean search(String word) { + //获取包含当前输入word的节点 + TrieNode node = searchPrefix(word); + //判断node是否为null且是否为终结点 + return node != null && node.isEnd(); + } + + // 查找是否有以当前输入prefix为前缀的节点 + public boolean startsWith(String prefix) { + //查找包含前缀的节点 + TrieNode node = searchPrefix(prefix); + //判断节点是否为null并返回真值 + return node != null; + } + +} + + +``` + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/implement-trie-prefix-tree/](https://leetcode.com/articles/implement-trie-prefix-tree/) diff --git a/leetcode/230-KthSmallestElementInABST/bigablecat.md b/leetcode/230-KthSmallestElementInABST/bigablecat.md new file mode 100644 index 0000000..edef66e --- /dev/null +++ b/leetcode/230-KthSmallestElementInABST/bigablecat.md @@ -0,0 +1,54 @@ +**230. 二叉搜索树中第K小的元素** +--- +[https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/](https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/) + +* 网友高票Java解法: + +```java + + /** + * + * 网友高票Java解法1:递归查找二叉搜索树 + * + */ + public int kthSmallest(TreeNode root, int k) { + //计算左子树的节点总数 + int count = countNodes(root.left); + //如果k小于或等于左子树的节点总数 + if (k <= count) { + //直接计算并放回左子树中的第k个最小值 + //因为二叉搜索树的左子节点值小于根结点值 + return kthSmallest(root.left, k); + } else if (k > count + 1) { + //如果k大于左子树节点总数 + //返回右子树的第k - 1 - count个最小值 + //k -1 减去了当前节点 + return kthSmallest(root.right, k - 1 - count); + } + //返回当前节点的值 + return root.val; + } + + /** + * 计算当前树的节点总数 + * + * @param n + * @return + */ + public int countNodes(TreeNode n) { + //如果树根结点为空,返回0 + if (n == null) return 0; + //否则分别计算左子树和右子树的节点总数 + // 1+表示将当前节点计入总数 + return 1 + countNodes(n.left) + countNodes(n.right); + } + + +``` + +--- + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/kth-smallest-element-in-a-bst/discuss/63660/3-ways-implemented-in-JAVA-(Python)%3A-Binary-Search-in-order-iterative-and-recursive](https://leetcode.com/problems/kth-smallest-element-in-a-bst/discuss/63660/3-ways-implemented-in-JAVA-(Python)%3A-Binary-Search-in-order-iterative-and-recursive) diff --git a/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md b/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md index ba8e680..6063e61 100644 --- a/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md +++ b/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md @@ -2,7 +2,7 @@ --- [https://leetcode-cn.com/problems/different-ways-to-add-parentheses/](https://leetcode-cn.com/problems/different-ways-to-add-parentheses/) -* 网友高票Java答案: +* 网友高票Java解法: ```java /** @@ -69,5 +69,5 @@ **参考资料** -* 网友高票Java答案: +* 网友高票Java解法: [https://leetcode.com/problems/different-ways-to-add-parentheses/discuss/66328/A-recursive-Java-solution-(284-ms)](https://leetcode.com/problems/different-ways-to-add-parentheses/discuss/66328/A-recursive-Java-solution-(284-ms)) diff --git a/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md b/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md index 78ce4c3..680fb44 100644 --- a/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md +++ b/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md @@ -2,7 +2,7 @@ --- [https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) -* 网友高票Java答案(动态规划) +* 网友高票Java解法(动态规划) ```java public static int maxProfit(int[] prices) { @@ -81,5 +81,5 @@ **参考资料** -* 网友高票Java答案: +* 网友高票Java解法: [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) diff --git a/leetcode/513-FindBottomLeftTreeValue/bigablecat.md b/leetcode/513-FindBottomLeftTreeValue/bigablecat.md new file mode 100644 index 0000000..4ef70e6 --- /dev/null +++ b/leetcode/513-FindBottomLeftTreeValue/bigablecat.md @@ -0,0 +1,48 @@ +**513. 找树左下角的值** +--- +[https://leetcode-cn.com/problems/find-bottom-left-tree-value/](https://leetcode-cn.com/problems/find-bottom-left-tree-value/) + +* 网友高票Java解法: + +```java + /** + * 网友高票Java解法 + * + * @param root + * @return + */ + public int findBottomLeftValue(TreeNode root) { + //定义一个队列 + Queue queue = new LinkedList<>(); + //将当前节点加入队列 + queue.add(root); + //如果队列非空,继续循环 + while (!queue.isEmpty()) { + //从队列中取出第一个元素,赋值给root + root = queue.poll(); + //如果root右子节点非空 + //将右子节点加入队列 + if (root.right != null) + queue.add(root.right); + //同理将左子节点加入队列 + if (root.left != null) + queue.add(root.left); + + //队列先进先出 + //右子节点先被放进Queue,会在下一轮循环中先出 + //这个解法的思路是不断搜索树的节点 + //将节点按照右-左的顺序存入队列 + //再在下一轮循环中弹出队列顶端的节点 + //最终队列只留下树最后一行的左节点 + } + //返回最后一行左节点的值 + return root.val; + } + + +``` + +**参考资料** + +* 网友高票Java解法: +[https://leetcode.com/problems/find-bottom-left-tree-value/discuss/98779/Right-to-Left-BFS-(Python-%2B-Java)](https://leetcode.com/problems/find-bottom-left-tree-value/discuss/98779/Right-to-Left-BFS-(Python-%2B-Java)) diff --git a/leetcode/785-IsGraphBipartite/bigablecat.md b/leetcode/785-IsGraphBipartite/bigablecat.md new file mode 100644 index 0000000..905d7f8 --- /dev/null +++ b/leetcode/785-IsGraphBipartite/bigablecat.md @@ -0,0 +1,76 @@ +**785. 判断二分图** +--- +[https://leetcode-cn.com/problems/is-graph-bipartite/](https://leetcode-cn.com/problems/is-graph-bipartite/) + +* 网友高票Java解法: + +```java + + /** + * 网友高票Java解法 + * + * 本题的思路是分别用两种颜色中的一种为每个节点染色 + * 查看相邻节点是否被染了相同的颜色 + * 0: 为染色 + * 1: 蓝色 + * -1: 红色 + * + * @param graph + * @return + */ + public boolean isBipartite(int[][] graph) { + //获取图的大小n + int n = graph.length; + // 创建一个大小为n的数组存储颜色 + int[] colors = new int[n]; + + //遍历图中的所有节点 + for (int i = 0; i < n; i++) { + //colors[i] == 0 获取当前位置的颜色并判断是否未染色 + //validColor(graph, colors, 1, i)查看i位置的节点,是否是蓝色 + if (colors[i] == 0 && !validColor(graph, colors, 1, i)) { + //未染色且节点是蓝色则返回false + return false; + } + } + //符合条件,返回true + return true; + } + + /** + * 为图中的节点染色 + * + * @param graph + * @param colors + * @param color + * @param node + * @return + */ + public boolean validColor(int[][] graph, int[] colors, int color, int node) { + //colors[node] 获取当前位置node的颜色 + //colors[node] != 0表示当前节点已经染色 + if (colors[node] != 0) { + //判断已染颜色是否与指定颜色值color相同 + return colors[node] == color; + } + //没染色则将当前节点用指定颜色值color染色 + colors[node] = color; + //遍历graph[node]位置下的每个节点 + for (int next : graph[node]) { + //判断next是否是红色 + if (!validColor(graph, colors, -color, next)) { + //不是红色则直接返回false + return false; + } + } + //返回true + return true; + } + + +``` + +**参考资料** + +* 网友高效答案: +[https://leetcode.com/problems/is-graph-bipartite/discuss/115487/Java-Clean-DFS-solution-with-Explanation](https://leetcode.com/problems/is-graph-bipartite/discuss/115487/Java-Clean-DFS-solution-with-Explanation) From 6258b01268a1a236450338ab7862ffa3321def27 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 17 Apr 2019 15:46:53 +0800 Subject: [PATCH 51/66] update --- leetcode/191-NumberOf1Bits/README.md | 39 ++++++ leetcode/207-CourseSchedule/bigablecat.md | 124 +++++++++++++++++ .../684-RedundantConnection/bigablecat.md | 127 ++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100644 leetcode/191-NumberOf1Bits/README.md create mode 100644 leetcode/207-CourseSchedule/bigablecat.md create mode 100644 leetcode/684-RedundantConnection/bigablecat.md diff --git a/leetcode/191-NumberOf1Bits/README.md b/leetcode/191-NumberOf1Bits/README.md new file mode 100644 index 0000000..40b59b8 --- /dev/null +++ b/leetcode/191-NumberOf1Bits/README.md @@ -0,0 +1,39 @@ +**191. 位1的个数** +--- + +[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) + +编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 + + +**示例 1:** + +``` +输入:00000000000000000000000000001011 +输出:3 +解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 +``` + +**示例 2:** +``` +输入:00000000000000000000000010000000 +输出:1 +解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 +``` + +**示例 3:** + +``` +输入:11111111111111111111111111111101 +输出:31 +解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 +``` + +**提示:** + +* 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 +* 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。 + +**进阶:** +如果多次调用这个函数,你将如何优化你的算法? + diff --git a/leetcode/207-CourseSchedule/bigablecat.md b/leetcode/207-CourseSchedule/bigablecat.md new file mode 100644 index 0000000..233de22 --- /dev/null +++ b/leetcode/207-CourseSchedule/bigablecat.md @@ -0,0 +1,124 @@ +**207. 课程表** +--- +[https://leetcode-cn.com/problems/course-schedule/](https://leetcode-cn.com/problems/course-schedule/) + +* 网友高票Java解法 + +```java + + /** + * + * 网友高票Java解法 + * + * 做这道题目首先需要明确几个知识点: + * 《算法》第四版中文,作者Sedgewick + * 1. 有向图(P364): + * 一副有向图是由一组顶点和一组有方向的边组成的, + * 每条有方向的边都连接着有序的一对顶点 + * + * 2. 有向路径(P364): + * 一副有向图中,有向路径由一系列顶点组成, + * 对于其中的每个顶点都存在一条有向边, + * 从它指向序列中的下一个顶点 + * + * 3. 有向环(P364): + * 有向环为一条至少含有一条边且起点和终点相同的有向路径 + * + * 4. 有向无环图(P371): + * 有向无环图(DAG)就是一副不含有向环的有向图 + * + * 5. 拓扑排序(P371): + * 给定一副有向图,将所有顶点排序, + * 使得所有的有向边都从排在前面的元素指向排在后面的元素 + * + * 6. 入度(P364): + * 一个顶点的入度为指向该顶点的边的总数 + * + * 本题查找有向图中是否存在环,即入度是否大于1 + * + * + * @param numCourses + * @param prerequisites + * @return + */ + public boolean canFinish(int numCourses, int[][] prerequisites) { + + //创建大小为numCourses*numCourses的矩阵 + //matrix记录有课程之间依赖关系的状态 + //如 matrix[0][1] = 1 表示课程0是课程1的先修课 + int[][] matrix = new int[numCourses][numCourses]; // i -> j + //建立一个大小为numCourses的数组indegree + //每门课代表有向图的一个顶点,共有numCourses个顶点 + //indegree记录每个顶点的“入度”,即指向该顶点的边的总数 + int[] indegree = new int[numCourses]; + + //遍历课程列表prerequisites + //prerequisites是一个二维数组,其中的每个元素又是一个数组 + for (int i=0; i queue = new LinkedList(); + //遍历indegree,获取每个顶点的入度 + for (int i=0; i rank[yr]) { + //同理,让y的根节点yr指向更高的xr + parent[yr] = xr; + } else { + // 当两者的rank值相等时 + // 其中一个指向另一个即可 + parent[yr] = xr; + //同时被指向的节点rank值递增1 + rank[xr]++; + } + return true; + } + } + +``` + +**复杂度分析** + +时间复杂度:O(N·α(N))≈O(N), +其中N是边的数目, +α表示Inverse-Ackermann方程, +因为对dsu.union进行了N次调用, +所以时间复杂度是α(N), +而α(N)近似于1,所以最终时间复杂度是O(N) + +空间复杂度:O(N), +构造DSU对象时, +其中的数组只使用了大小为N的额外空间 + +--- + +**参考资料** + +* 英文官方题解: +[https://leetcode.com/articles/redundant-connection/](https://leetcode.com/articles/redundant-connection/) From 78eced06e438950df12e0a0ae7938d1aeb1ef214 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Wed, 17 Apr 2019 15:54:46 +0800 Subject: [PATCH 52/66] update --- leetcode/198-houseRobber/README.md | 25 +++++++++++++++++++++++++ leetcode/198-houseRobber/official.md | 3 --- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 leetcode/198-houseRobber/README.md delete mode 100644 leetcode/198-houseRobber/official.md diff --git a/leetcode/198-houseRobber/README.md b/leetcode/198-houseRobber/README.md new file mode 100644 index 0000000..fdf715f --- /dev/null +++ b/leetcode/198-houseRobber/README.md @@ -0,0 +1,25 @@ +**198. 打家劫舍** +--- +[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) + +你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 + +给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 + +**示例 1:** + +``` +输入: [1,2,3,1] +输出: 4 +解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 + 偷窃到的最高金额 = 1 + 3 = 4 。 +``` + +**示例 2:** + +``` +输入: [2,7,9,3,1] +输出: 12 +解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 + 偷窃到的最高金额 = 2 + 9 + 1 = 12 。 +``` diff --git a/leetcode/198-houseRobber/official.md b/leetcode/198-houseRobber/official.md deleted file mode 100644 index 90116ff..0000000 --- a/leetcode/198-houseRobber/official.md +++ /dev/null @@ -1,3 +0,0 @@ -**198. 打家劫舍** ---- -[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) From 894a4ee968e0db6bee7742c1ee5b33bf19c8093d Mon Sep 17 00:00:00 2001 From: bigablecat Date: Fri, 26 Apr 2019 22:38:23 +0800 Subject: [PATCH 53/66] update --- .../README.md" | 14 ++++++++++++++ .../README.md" | 14 ++++++++++++++ .../README.md" | 11 +++++++++++ .../README.md" | 8 ++++++++ .../README.md" | 10 ++++++++++ .../README.md" | 11 +++++++++++ .../README.md" | 10 ++++++++++ 7 files changed, 78 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" create mode 100644 "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" create mode 100644 "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" create mode 100644 "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" create mode 100644 "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" create mode 100644 "\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" create mode 100644 "\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" diff --git "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000..8c46ca2 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" @@ -0,0 +1,14 @@ +**3. 数组中重复的数字** +--- + +在一个长度为n的数组里的所有数字都在0到n-1的范围内。 +数组中某些数字是重复的,但不知道有几个数字是重复的。 +也不知道每个数字重复几次。 +请找出数组中任意一个重复的数字。 +例如, +如果输入长度为7的数组{2,3,1,0,2,5,3}, +那么对应的输出是第一个重复的数字2。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) diff --git "a/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" "b/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" new file mode 100644 index 0000000..6e58bc1 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" @@ -0,0 +1,14 @@ +**4. 二维数组中的查找** +--- + +在一个二维数组中(每个一维数组的长度相同), +每一行都按照从左到右递增的顺序排序, +每一列都按照从上到下递增的顺序排序。 +请完成一个函数, +输入这样的一个二维数组和一个整数, +判断数组中是否含有该整数。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + diff --git "a/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" "b/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" new file mode 100644 index 0000000..d6c437f --- /dev/null +++ "b/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" @@ -0,0 +1,11 @@ +**5. 替换空格** +--- + +请实现一个函数,将一个字符串中的每个空格替换成“%20”。 +例如,当字符串为We Are Happy. +则经过替换之后的字符串为We%20Are%20Happy。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + diff --git "a/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" "b/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" new file mode 100644 index 0000000..389e69b --- /dev/null +++ "b/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" @@ -0,0 +1,8 @@ +**6. 从尾到头打印链表** +--- + +输入一个链表,按链表值从尾到头的顺序返回一个ArrayList + +**牛客网链接** + +[https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000..0859001 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,10 @@ +**8. 二叉树的下一个结点** +--- + +给定一个二叉树和其中的一个结点, +请找出中序遍历顺序的下一个结点并且返回。 +注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) diff --git "a/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" "b/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" new file mode 100644 index 0000000..35569a3 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" @@ -0,0 +1,11 @@ +**7. 从尾到头打印链表** +--- + +输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 +假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 +例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}, +则重建二叉树并返回。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) diff --git "a/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" "b/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" new file mode 100644 index 0000000..412a3b4 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" @@ -0,0 +1,10 @@ +**9. 用两个栈实现队列** +--- + +用两个栈来实现一个队列, +完成队列的Push和Pop操作。 +队列中的元素为int类型。 + +**牛客网链接** + +[https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) From 11aaaa8ce89b48353147cc541caada5a25d1a096 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Fri, 26 Apr 2019 22:44:19 +0800 Subject: [PATCH 54/66] update --- .../README.md" | 11 ++++++----- .../README.md" | 11 +++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" index 0859001..35569a3 100644 --- "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" +++ "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" @@ -1,10 +1,11 @@ -**8. 二叉树的下一个结点** +**7. 从尾到头打印链表** --- -给定一个二叉树和其中的一个结点, -请找出中序遍历顺序的下一个结点并且返回。 -注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 +输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 +假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 +例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}, +则重建二叉树并返回。 **牛客网链接** -[https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) +[https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) diff --git "a/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" "b/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" index 35569a3..0859001 100644 --- "a/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" +++ "b/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" @@ -1,11 +1,10 @@ -**7. 从尾到头打印链表** +**8. 二叉树的下一个结点** --- -输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 -假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 -例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}, -则重建二叉树并返回。 +给定一个二叉树和其中的一个结点, +请找出中序遍历顺序的下一个结点并且返回。 +注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 **牛客网链接** -[https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) +[https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) From d04f54a8ec99d5be50aff8e2560d253a2b40c650 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Fri, 26 Apr 2019 22:45:09 +0800 Subject: [PATCH 55/66] update --- .../README.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" index 35569a3..8010ebc 100644 --- "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" +++ "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" @@ -1,4 +1,4 @@ -**7. 从尾到头打印链表** +**7. 重建二叉树** --- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 From 30e0154f8343c49038ec4f2a19c20510e973afb3 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Fri, 3 May 2019 11:18:57 +0800 Subject: [PATCH 56/66] Create zengdiqing1994.md --- .../zengdiqing1994.md" | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" new file mode 100644 index 0000000..4085b5a --- /dev/null +++ "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" @@ -0,0 +1,69 @@ +思路1: + +先排序,再从排好序的数组中找出重复的数字,O(nlogn) + +```py +class Solution: + # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] + # 函数返回True/False + def duplicate(self, numbers, duplication): + # 列表排序 + numbers.sort() + for i in range(len(numbers)): + # 判断是否扫描到列表末尾。防止溢出。 + if i == len(numbers) - 1: + return False + if numbers[i] == numbers[i+1]: + duplication[0] = numbers[i] + return True + return False +``` + +思路2: + +用python中的字典,从头到尾按顺序扫描数组的每个数字,每扫描到一个数字的时候,判断哈希表里是否已经包含了该数字。如果哈希表里还没有这个数字,就把它加入 +哈希表。如果哈希表里已经存在该数字,就找到一个重复的数字。 + +```py +class Solution: + # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] + # 函数返回True/False + def duplicate(self, numbers, duplication): + # write code here + dict = {} + for num in numbers: + if num not in dict: + dict[num] = 0 + else: + duplication[0] = num + return True + return False +``` + +思路3: + +重新排列这个数组,从头到尾依次扫描数字,当扫描搭配下标为i的数字时,首先比较这个数字numbers[i]是不是等于i,如果是,就扫描下一个数字;如果不是,就再 +拿他和第number[i]个数字进行比较。如果他和第numbers[i]个数字相等,就找到了一个重复的数字(该数字在下标为i和numbers[i]的位置都出现了。)。如果他和 +第numbers[i]个数字不等,就把第i个数字和第numebrs[i]个数字交换,把numbers[i]放在属于他的位置。接下来重复这个比较,交换的过程,直到找到一个重复的 +数字。 + +```py +class Solution: + # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] + # 函数返回True/False + def duplicate(self, numbers, duplication): + # write code here + if numbers == None or len(numbers)<0: + return False + for i in range(len(numbers)): + while numbers[i] != i: + if numbers[i] == numbers[numbers[i]]: + duplication[0] = numbers[i] + return True + temp = numbers[i] + numbers[i] = numbers[temp] + numbers[temp] = temp + #numbers[i],numbers[numbers[i]]=numbers[numbers[i]],numbers[i] + return False +``` +注意这里不能直接用python的直接赋值代替交换swap,会超时。 From 0b7ac6b856b0d42eef46a46cd9524b75e9c4421c Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Fri, 3 May 2019 11:35:18 +0800 Subject: [PATCH 57/66] Create zengdiqing1994.md --- .../zengdiqing1994.md" | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" "b/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" new file mode 100644 index 0000000..5527883 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" @@ -0,0 +1,29 @@ +**4.二维数组中的查找** + +思路: + +首先选取数组中右上角的数字,如果该数字等于要查找的数字,则查找过程结束;如果数字大于要查找的数字,则剔除这个数字所在的列;如果该数字小于要查找的数字,则 +剔除这个数字所在的行。也就是说,如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,知道找到 +查找的数字。 + +```py +class Solution: + # array 二维列表 + def Find(self, target, array): + if array == []: + return False + num_row = len(array) + num_col = len(array[0]) + + i = num_col - 1 + j = 0 + while i>=0 and j target: + i-=1 + elif array[j][i] < target: + j+=1 + else: + return True +``` +时间复杂度:O(n^2) +空间复杂度:O(n) From 66471223c77eada7a05e43915a13d49f0340d72b Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 14 May 2019 10:23:44 +0800 Subject: [PATCH 58/66] Create zengdiqing.md --- .../zengdiqing.md" | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" diff --git "a/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" "b/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" new file mode 100644 index 0000000..be68aeb --- /dev/null +++ "b/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" @@ -0,0 +1,32 @@ +**思路:** + +因为一个空格要替换成三个字符(%20),所以当遍历到一个空格时,需要在尾部填充两个任意字符。令p1指向字符串原来的末尾位置,p2指向字符串现在的末尾位置。 +p1和p2从后向前遍历,当p1遍历到一个空格时,就需要令p2指向的位置依次填充02%,否则就填充上p1指向字符的值。 + +```py +class Solution: + def replaceSpace(self, s): + if not isinstance(s,str) or len(s) <= 0 or s == None: + return '' + spaceNum = 0 + for i in s: + if i == "": + spaceNum += 1 + newStrLen = len(s) + spaceNum*2 + newStr = newStrLen*[None] + indexOfOriginal, indexOfNew = len(s) - 1, newStrLen - 1 + while indexOfNew >= 0 and indexOfOriginal <= indexOfNew: + if s[indexOfOriginal] == '': + newStr[indexOfNew-2:indexOfNew+1] = ['%','2','0'] + indexOfNew -= 3 + indexOfOriginal -= 1 + else: + newStr[indexOfNew] = s[indexOfOriginal] + indexOfNew -= 1 + indexOfOriginal -= 1 + return ''.join(newStr) + +``` +时间复杂度:O(n) + +空间复杂度:O(n) From 733f5a7f7172ed943ca18f96952ab12d1c03b06a Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 14 May 2019 13:48:11 +0800 Subject: [PATCH 59/66] Create zengdiqing94.md --- .../zengdiqing94.md" | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" diff --git "a/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" "b/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" new file mode 100644 index 0000000..baa4ed3 --- /dev/null +++ "b/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" @@ -0,0 +1,26 @@ +**思路:** + +使用链表头插法为逆序的特点 + +头结点和第一个结点的区别: + +头结点是头插法中使用的一个额外结点,这个结点不存储值。 + +第一个节点就是链表的第一个真正存储值得结点。 + +这道题也可以使用递归和栈来解决。 + +```py +class Solution: + # 返回从尾部到头部的列表值序列,例如[1,2,3] + def printListFromTailToHead(self, listNode): + # write code here + if not listNode: + return [] + result = [] + + while listNode: + result.insert(0,listNode.val) + listNode = listNode.next + return result +``` From d1dda7c56a21b730afe21821f9c5320ac210b53a Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Tue, 14 May 2019 19:16:31 +0800 Subject: [PATCH 60/66] Update zengdiqing1994.md --- .../zengdiqing1994.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" index 4085b5a..4825008 100644 --- "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" +++ "b/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" @@ -67,3 +67,4 @@ class Solution: return False ``` 注意这里不能直接用python的直接赋值代替交换swap,会超时。 + From f0f582ed61ae8b53f6d0ea38d37ff9d22446ce40 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Thu, 16 May 2019 10:06:08 +0800 Subject: [PATCH 61/66] Rename zengdiqing.md to zengdiqing1994.md --- .../zengdiqing1994.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" => "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" (100%) diff --git "a/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" "b/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing.md" rename to "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" From 7a6c3f5e2b70ad05ce49511a288e504578528c84 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Thu, 16 May 2019 10:06:41 +0800 Subject: [PATCH 62/66] Rename zengdiqing94.md to zengdiqing1994.md --- .../zengdiqing1994.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" => "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" (100%) diff --git "a/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" "b/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing94.md" rename to "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" From 85c087af62f1b4a60169c822e69acc66fae32ca9 Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Thu, 16 May 2019 10:27:24 +0800 Subject: [PATCH 63/66] Create zengdiqing1994 --- .../zengdiqing1994" | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" new file mode 100644 index 0000000..f99cdfd --- /dev/null +++ "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" @@ -0,0 +1,26 @@ + +**7.重建二叉树** + +思路:我们知道前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两个部分,左部分为树的左子数中序遍历结果,右部分为树的右子树中序遍历的结果 + +```py +class TreeNode: + def __init__(self, x): # 初始化树 + self.val = x + self.left = None + self.right = None +class Solution: + # 返回构造的TreeNode根节点 + def reConstructBinaryTree(self, pre, tin): + # write code here + if not pre and not tin: + return None + root = TreeNode(pre[0]) # 前序遍历的root + if set(pre) != set(tin): #判断其他情况 + return None + i = tin.index(pre[0]) #看前序遍历的root在中序遍历的哪个位置 + root.left = self.reConstructBinaryTree(pre[1:i+1],tin[:i]) #开始递归 + root.right = self.reConstructBinaryTree(pre[i+1:],tin[i+1:]) + return root +``` +时间复杂度O(n^2) From d5729f0bbc66181baaa0491083bfcf8190def708 Mon Sep 17 00:00:00 2001 From: bigablecat Date: Thu, 13 Jun 2019 08:39:08 +0800 Subject: [PATCH 64/66] update --- leetcode/279-PerfectSquares/bigablecat.md | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 leetcode/279-PerfectSquares/bigablecat.md diff --git a/leetcode/279-PerfectSquares/bigablecat.md b/leetcode/279-PerfectSquares/bigablecat.md new file mode 100644 index 0000000..b294636 --- /dev/null +++ b/leetcode/279-PerfectSquares/bigablecat.md @@ -0,0 +1,64 @@ +**279. 完全平方数** +--- +[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) + +* 网友高票Java解法 + +```java + + /** + * 1. 英文站网友高票Java解法 + * https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java + * + * 2. 中文站网友高票Java解法 + * https://leetcode-cn.com/problems/perfect-squares/solution/javati-jie-dong-tai-gui-hua-qiu-jie-by-pphdsny/ + * + * @param n + * @return + */ + public static int numSquares(int n) { + //定义一个长度为 n + 1 的整型数组 + //其中每个元素 dp[i] 都存了整数i所需的最少完全平方数的个数 + //比如dp[12] = 3,表示组成整数12最少需要3个完全平方数 + int[] dp = new int[n + 1]; + //用Java中整数的最大取值上限Integer.MAX_VALUE填充数组 + Arrays.fill(dp, Integer.MAX_VALUE); + //将数组dp的首个元素赋值为0 + dp[0] = 0; + //遍历数组 + for (int i = 1; i <= n; ++i) { + // 将整数上限赋值给临时变量 min 作为初始值 + // min最终会记录组成整数i最少需要多少个完全平方数 + int min = Integer.MAX_VALUE; + //内循环控制变量 j 从 1 开始 + int j = 1; + // j*j 得到一个完全平方数 + // i - j * j >= 0 找到 i 这个数里最大的完全平方数 + while (i - j * j >= 0) { + // dp[i - j * j] 的值表示组成 i - j * j 这个整数,最少需要多少个完全平方数 + // dp[i - j * j] + 1 表示在dp[i - j * j]原有个数的基础上 + // 加上 j*j 这个完全平方数,得到 dp[i] 所需的完全平方数 + // 每次while循环都比较min和dp[i - j * j] + 1的大小,取较小值 + min = Math.min(min, dp[i - j * j] + 1); + ++j; + } + //经过while循环,从组成i的完全平方数的所有可能中 + //得到最少的个数 min 赋值给 dp[i] + dp[i] = min; + } + // 经过for循环,n所包含的每个整数都取得了最少完全平方数的个数 + // dp[n]得到的也是最少个数 + return dp[n]; + } + +``` + +--- + +**参考资料** + +* 1. 英文站网友高票Java解法 +[https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) + +* 2. 中文站网友高票Java解法 +[https://leetcode-cn.com/problems/perfect-squares/solution/javati-jie-dong-tai-gui-hua-qiu-jie-by-pphdsny/](https://leetcode-cn.com/problems/perfect-squares/solution/javati-jie-dong-tai-gui-hua-qiu-jie-by-pphdsny/) From 3586f98f45c84d0353cfc5f2d5fbda81a5f5d3fb Mon Sep 17 00:00:00 2001 From: elbowrocket <735349225@qq.com> Date: Fri, 14 Jun 2019 18:55:00 +0800 Subject: [PATCH 65/66] Rename zengdiqing1994 to zengdiqing1994.md --- .../zengdiqing1994.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" => "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" (100%) diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" "b/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994" rename to "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" From 6bcb047f7fc9296e03de5661567e13b78799d0fd Mon Sep 17 00:00:00 2001 From: bigablecat Date: Mon, 15 Mar 2021 22:44:49 +0800 Subject: [PATCH 66/66] update --- README.md | 3138 ++++++----------- codes/java_dataStructure_luozhaoyong/1.bmp | Bin 0 -> 625878 bytes codes/java_dataStructure_luozhaoyong/2.zip | Bin 0 -> 79515 bytes codes/java_dataStructure_luozhaoyong/3.bmp | 1 + .../java_dataStructure_luozhaoyong/README.md | 937 +++++ .../src/demo1/AddOneToHundred.java | 31 + .../src/demo1/TestArray.java | 45 + .../src/demo1/TestBinarySearch.java | 48 + .../src/demo1/TestMyArray.java | 57 + .../src/demo1/TestMyArraySearch.java | 25 + .../src/demo1/TestOpArray.java | 41 + .../src/demo1/TestOpArray2.java | 51 + .../src/demo1/TestSearch.java | 27 + .../src/demo1/util/MyArray.java | 206 ++ .../src/demo10/Node.java | 55 + .../src/demo10/TestHuffmanCode.java | 426 +++ .../src/demo11/BinarySortTree.java | 150 + .../src/demo11/Node.java | 132 + .../src/demo11/TestBinarySortTree.java | 38 + .../src/demo12/BinarySortTree.java | 152 + .../src/demo12/Node.java | 219 ++ .../src/demo12/TestBinarySortTree.java | 49 + .../src/demo13/HashTable.java | 44 + .../src/demo13/StuInfo.java | 59 + .../src/demo13/TestHashTable.java | 29 + .../src/demo14/Graph.java | 140 + .../src/demo14/TestGraph.java | 51 + .../src/demo14/Vertex.java | 34 + .../src/demo2/DoubleNode.java | 78 + .../src/demo2/LoopNode.java | 73 + .../src/demo2/MyQueue.java | 77 + .../src/demo2/MyStack.java | 94 + .../src/demo2/Node.java | 119 + .../src/demo2/TestLoopNode.java | 19 + .../src/demo2/test/TestDoubleNode.java | 41 + .../src/demo2/test/TestLoopNode.java | 31 + .../src/demo2/test/TestMyQueue.java | 31 + .../src/demo2/test/TestMyStack.java | 45 + .../src/demo2/test/TestNode.java | 47 + .../src/demo3/TestFibonacci.java | 33 + .../src/demo3/TestHanoi.java | 53 + .../src/demo3/TestRecursive.java | 23 + .../src/demo4/BubbleSort.java | 60 + .../src/demo4/HeapSort.java | 95 + .../src/demo4/InsertSort.java | 67 + .../src/demo4/MergeSort.java | 115 + .../src/demo4/QuickSort.java | 90 + .../src/demo4/RadixQueueSort.java | 133 + .../src/demo4/RadixSort.java | 138 + .../src/demo4/SelectionSort.java | 60 + .../src/demo4/ShellSort.java | 56 + .../src/demo5/BinaryTree.java | 81 + .../src/demo5/TestBinaryTree.java | 58 + .../src/demo5/TreeNode.java | 162 + .../src/demo6/ArrayBinaryTree.java | 58 + .../src/demo6/TestArrayBinaryTree.java | 18 + .../src/demo7/TestThreadedBinaryTree.java | 57 + .../src/demo7/ThreadedBinaryTree.java | 169 + .../src/demo7/ThreadedNode.java | 175 + .../src/demo9/Node.java | 48 + .../src/demo9/TestHuffmanTree.java | 63 + solutions/README.md | 2156 +++++++++++ .../images}/017_Telephone-keypad2.png | Bin .../images}/160_example_1.png | Bin .../images}/160_example_2.png | Bin .../images}/160_example_3.png | Bin .../images}/160_statement.png | Bin .../leetcode}/001-twoSum/README.md | 0 .../leetcode}/001-twoSum/hatrick.md | 0 .../leetcode}/001-twoSum/woody.md | 0 .../leetcode}/002-addTwoNumber/README.md | 0 .../leetcode}/002-addTwoNumber/monkey.md | 0 .../README.md | 0 .../monkey.md | 0 .../zengdiqing1994.md | 0 .../hatrick.md | 0 .../official.md | 0 .../leetcode}/006-ZigZagConversion/README.md | 0 .../006-ZigZagConversion/zengdiqing.md | 0 .../leetcode}/015-threeSum/hatrick.md | 0 .../leetcode}/015-threeSum/official.md | 0 .../README.md | 0 .../020-validParentheses/official.md | 0 .../leetcode}/023-MergeKSortedLists/README.md | 0 .../024-swapNodesInPairs/official.md | 0 .../025-reverseNodesInKGroup/bigablecat.md | 0 .../025-reverseNodesInKGroup/official.md | 0 .../032-LongestValidParentheses/official.md | 0 .../033-SearchInRotatedSortedArray/README.md | 0 .../zengdiqing1994.md | 0 .../leetcode}/036-ValidSudoku/SpecialYang.md | 0 .../leetcode}/036-ValidSudoku/official.md | 0 .../leetcode}/037-SudokuSolver/SpecialYang.md | 0 .../leetcode}/037-SudokuSolver/official.md | 0 .../leetcode}/048-RotateImage/README.md | 0 .../leetcode}/048-RotateImage/zengdiqing.md | 0 .../leetcode}/050-powxN/bigablecat.md | 0 .../leetcode}/051-NQueens/melody-l.md | 0 .../leetcode}/051-NQueens/official.md | 0 .../leetcode}/052-N-QueensII/hatrick.md | 0 .../leetcode}/052-N-QueensII/official.md | 0 .../leetcode}/053-maximumSubarray/BambooYH.md | 0 .../leetcode}/053-maximumSubarray/README.md | 0 .../053-maximumSubarray/zengdiqing1994.md | 0 .../leetcode}/054-SpiralMatrix/README.md | 0 .../054-SpiralMatrix/zengdiqing1994.md | 0 .../leetcode}/059-SpiralMatrixII/README.md | 0 .../059-SpiralMatrixII/zengdiqing1994.md | 0 .../leetcode}/062-UniquePaths/BambooYH.md | 0 .../leetcode}/062-UniquePaths/official.md | 0 .../063-UniquePathsII/SpecialYang.md | 0 .../leetcode}/063-UniquePathsII/official.md | 0 .../leetcode}/064-minimumPathSum/README.md | 0 .../leetcode}/064-minimumPathSum/melody-l.md | 0 .../leetcode}/069-SqrtX/README.md | 0 .../leetcode}/069-SqrtX/bigablecat.md | 0 .../leetcode}/070-ClimbingStairs/README.md | 0 .../leetcode}/070-ClimbingStairs/melody-l.md | 0 .../leetcode}/072-EditDistance/official.md | 0 .../leetcode}/075-SortColors/README.md | 0 .../leetcode}/075-SortColors/bigablecat.md | 0 .../076-MinimumWindowSubstring/README.md | 0 .../085-MaximalRectangle/passself.md | 0 .../leetcode}/087-ScrambleString/official.md | 0 .../leetcode}/091-DecodeWays/melody-l.md | 0 .../leetcode}/091-DecodeWays/official.md | 0 .../leetcode}/091-DecodeWays/sandao.md | 0 .../095-UniqueBinarySearchTreesII/melody-l.md | 0 .../095-UniqueBinarySearchTreesII/official.md | 0 .../096-uniqueBinarySearchTrees/official.md | 0 .../097-InterleavingString/official.md | 0 .../098-validateBinarySearchTree/BambooYH.md | 0 .../SpecialYang.md | 0 .../hatrick.md | 0 .../official.md | 0 .../zengdiqing1994.md | 0 .../104-MaximumDepthOfBinaryTree/melody-l.md | 0 .../104-MaximumDepthOfBinaryTree/official.md | 0 .../110-BalancedBinaryTree/README.md | 0 .../110-BalancedBinaryTree/bigablecat.md | 0 .../110-BalancedBinaryTree/zengdiqing1994.md | 0 .../115-DistinctSubsequences/official.md | 0 .../leetcode}/120-Triangle/melody-l.md | 0 .../leetcode}/120-Triangle/official.md | 0 .../bigablecat.md | 0 .../121-bestTimeToBuyAndSellStock/official.md | 0 .../SpecialYang.md | 0 .../bigablecat.md | 0 .../SpecialYang.md | 0 .../official.md | 0 .../131-PalindromePartitioning/official.md | 0 .../132-PalindromePartitioningII/official.md | 0 .../leetcode}/139-WordBreak/official.md | 0 .../leetcode}/140-WordBreakII/official.md | 0 .../leetcode}/141-linkedListCycle/official.md | 0 .../142-linkedListCycleII/bigablecat.md | 0 .../142-linkedListCycleII/official.md | 0 .../144-BinaryTreePreorderTraversal/README.md | 0 .../bigablecat.md | 0 .../leetcode}/146-lruCache/hatrick.md | 0 .../leetcode}/146-lruCache/official.md | 0 .../152-MaximumProductSubarray/README.md | 0 .../152-MaximumProductSubarray/SpecialYang.md | 0 .../zengdiqing1994.md | 0 .../README.md | 0 .../zengdiqing1994.md | 0 .../README.md | 0 .../bigablecat.md | 0 .../leetcode}/167-TwoSumII/README.md | 0 .../leetcode}/167-TwoSumII/bigablecat.md | 0 .../leetcode}/169-majorityElement/README.md | 0 .../169-majorityElement/SpecialYang.md | 0 .../169-majorityElement/bigablecat.md | 0 .../169-majorityElement/zengdiqing1994.md | 0 .../leetcode}/174-DungeonGame/passself.md | 0 .../BambooYH.md | 0 .../official.md | 0 .../leetcode}/191-NumberOf1Bits/README.md | 0 .../leetcode}/191-NumberOf1Bits/bigablecat.md | 0 .../leetcode}/198-houseRobber/README.md | 0 .../leetcode}/198-houseRobber/hatrick.md | 0 .../leetcode}/200-numberOfIslands/BambooYH.md | 0 .../leetcode}/200-numberOfIslands/official.md | 0 .../206-reverseLinkedList/official.md | 0 .../leetcode}/207-CourseSchedule/README.md | 0 .../207-CourseSchedule/bigablecat.md | 0 .../208-implementTriePrefixTree/README.md | 0 .../208-implementTriePrefixTree/bigablecat.md | 0 .../leetcode}/212-wordSearchII/official.md | 0 .../213-HouseRobberII/SpecialYang.md | 0 .../leetcode}/213-HouseRobberII/official.md | 0 .../BambooYH.md | 0 .../215-KthLargestElementInAnArray/README.md | 0 .../bigablecat.md | 0 .../leetcode}/221-MaximalSquare/official.md | 0 .../225-implementStackUsingQueues/hatrick.md | 0 .../225-implementStackUsingQueues/official.md | 0 .../230-KthSmallestElementInABST/README.md | 0 .../bigablecat.md | 0 .../leetcode}/231-PowerOfTwo/hatrick.md | 0 .../leetcode}/231-PowerOfTwo/official.md | 0 .../232-implementQueueUsingStacks/README.md | 0 .../232-implementQueueUsingStacks/hatrick.md | 0 .../BambooYH.md | 0 .../239-slidingWindowMaximum/official.md | 0 .../README.md | 0 .../bigablecat.md | 0 .../leetcode}/242-ValidAnagram/README.md | 0 .../leetcode}/242-ValidAnagram/bigablecat.md | 0 .../242-ValidAnagram/zengdiqing1994.md | 0 .../leetcode}/260-SingleNumberIII/README.md | 0 .../260-SingleNumberIII/zengdiqing1994.md | 0 .../leetcode}/264-UglyNumberII/bigablecat.md | 0 .../leetcode}/264-UglyNumberII/official.md | 0 .../leetcode}/279-PerfectSquares/README.md | 0 .../279-PerfectSquares/bigablecat.md | 0 .../279-PerfectSquares/zengdiqing1994.md | 0 .../295-FindMedianFromDataStream/BambooYH.md | 0 .../README.md | 0 .../melody-l.md | 0 .../303-rangeSumQueryImmutable/BambooYH.md | 0 .../303-rangeSumQueryImmutable/README.md | 0 .../304-RangeSumQuery2DImmutable/official.md | 0 .../304-RangeSumQuery2DImmutable/woody.md | 0 .../README.md | 0 .../bigablecat.md | 0 .../leetcode}/312-BurstBalloons/melody-l.md | 0 .../leetcode}/312-BurstBalloons/official.md | 0 .../321-CreateMaximumNumber/README.md | 0 .../leetcode}/322-CoinChange/official.md | 0 .../leetcode}/338-CountingBits/bigablecat.md | 0 .../leetcode}/343-IntegerBreak/README.md | 0 .../leetcode}/343-IntegerBreak/hatrick.md | 0 .../347-TopKFrequentElements/README.md | 0 .../347-TopKFrequentElements/bigablecat.md | 0 .../354-RussianDollEnvelopes/official.md | 0 .../zengdiqing1994.md | 0 .../official.md | 0 .../official.md | 0 .../367-ValidPerfectSquare/official.md | 0 .../368-LargestDivisibleSubset/passself.md | 0 .../374-GuessNumberHigherOrLower/official.md | 0 .../official.md | 0 .../376-WiggleSubsequence/melody-l.md | 0 .../376-WiggleSubsequence/official.md | 0 .../377-CombinationSumIV/official.md | 0 .../README.md | 0 .../zengdiqing1994.md | 0 .../leetcode}/392-IsSubsequence/official.md | 0 .../392-IsSubsequence/zengdiqing1994.md | 0 .../leetcode}/403-FrogJump/README.md | 0 .../leetcode}/409-LongestPalindrome/README.md | 0 .../409-LongestPalindrome/zengdiqing1994.md | 0 .../410-SplitArrayLargestSum/hatrick.md | 0 .../410-SplitArrayLargestSum/official.md | 0 .../413-arithmeticSlices/official.md | 0 .../416-PartitionEqualSubsetSum/README.md | 0 .../416-PartitionEqualSubsetSum/bigablecat.md | 0 .../official.md | 0 .../leetcode}/455-AssignCookies/README.md | 0 .../455-AssignCookies/SpecialYang.md | 0 .../leetcode}/455-AssignCookies/bigablecat.md | 0 .../README.md | 0 .../zengdiqing1994.md | 0 .../leetcode}/464-CanIWin/official.md | 0 .../passself.md | 0 .../472-ConcatenatedWords/official.md | 0 .../leetcode}/474-OnesAndZeroes/hatrick.md | 0 .../leetcode}/474-OnesAndZeroes/official.md | 0 .../486-PredictTheWinner/official.md | 0 .../leetcode}/494-TargetSum/official.md | 0 .../leetcode}/504-Base7/README.md | 0 .../leetcode}/504-Base7/zengdiqing1994.md | 0 .../513-FindBottomLeftTreeValue/README.md | 0 .../513-FindBottomLeftTreeValue/bigablecat.md | 0 .../zengdiqing1994.md | 0 .../leetcode}/514-FreedomTrail/hatrick.md | 0 .../leetcode}/514-FreedomTrail/official.md | 0 .../passself.md | 0 .../517-SuperWashingMachines/official.md | 0 .../523-ContinuousSubarraySum/hatrick.md | 0 .../523-ContinuousSubarraySum/official.md | 0 .../leetcode}/546-RemoveBoxes/passself.md | 0 .../leetcode}/547-friendCircles/bigablecat.md | 0 .../551-StudentAttendanceRecordI/official.md | 0 .../552-StudentAttendanceRecordII/official.md | 0 .../sandao.md | 0 .../576-OutOfBoundaryPaths/official.md | 0 .../576-OutOfBoundaryPaths/zengdiqing1994.md | 0 .../README.md | 0 .../629-KInversePairsArray/official.md | 0 .../629-KInversePairsArray/zengdiqing1994.md | 0 .../638-ShoppingOffers/bigablecat.md | 0 .../SpecialYang.md | 0 .../646-MaximumLengthOfPairChain/official.md | 0 .../647-PalindromicSubstrings/bigablecat.md | 0 .../647-PalindromicSubstrings/official.md | 0 .../leetcode}/650-2KeysKeyboard/mahone.md | 0 .../leetcode}/650-2KeysKeyboard/official.md | 0 .../leetcode}/664-StrangePrinter/official.md | 0 .../README.md | 0 .../bigablecat.md | 0 .../684-RedundantConnection/README.md | 0 .../684-RedundantConnection/bigablecat.md | 0 .../passself.md | 0 .../bigablecat.md | 0 .../official.md | 0 .../691-StickersToSpellWord/official.md | 0 .../692-TopKFrequentWords/bigablecat.md | 0 .../leetcode}/695-MaxAreaOfIsland/README.md | 0 .../hatrick.md | 0 .../official.md | 0 .../BambooYH.md | 0 .../BambooYH.md | 0 .../official.md | 0 .../hatrick.md | 0 .../official.md | 0 .../mahone.md | 0 .../official.md | 0 .../official.md | 0 .../leetcode}/740-DeleteAndEarn/melody-l.md | 0 .../leetcode}/740-DeleteAndEarn/official.md | 0 .../746-minCostClimbingStairs/bigablecat.md | 0 .../746-minCostClimbingStairs/official.md | 0 .../764-LargestPlusSign/SpecialYang.md | 0 .../leetcode}/764-LargestPlusSign/official.md | 0 .../leetcode}/785-IsGraphBipartite/README.md | 0 .../785-IsGraphBipartite/bigablecat.md | 0 .../official.md | 0 .../zengdiqing1994.md | 0 .../790-DominoAndTrominoTiling/mahone.md | 0 .../790-DominoAndTrominoTiling/official.md | 0 .../official.md | 0 .../leetcode}/808-SoupServings/official.md | 0 .../813-LargestSumOfAverages/melody-l.md | 0 .../813-LargestSumOfAverages/official.md | 0 .../leetcode}/837-New21Game/official.md | 0 .../leetcode}/838-PushDominoes/official.md | 0 .../844-BackspaceStringCompare/BambooYH.md | 0 .../844-BackspaceStringCompare/bigablecat.md | 0 .../bigablecat.md | 0 .../official.md | 0 .../leetcode}/860-lemonadeChange/BambooYH.md | 0 .../860-lemonadeChange/SpecialYang.md | 0 .../leetcode}/860-lemonadeChange/official.md | 0 .../official.md | 0 .../874-walkingRobotSimulation/SpecialYang.md | 0 .../874-walkingRobotSimulation/hatrick.md | 0 .../874-walkingRobotSimulation/official.md | 0 .../leetcode}/875-KokoEatingBananas/sandao.md | 0 .../leetcode}/877-stoneGame/melody-l.md | 0 .../leetcode}/877-stoneGame/official.md | 0 .../898-BitwiseORsOfSubarrays/official.md | 0 .../official.md | 0 .../zengdiqing1994.md | 0 .../920-NumberOfMusicPlaylists/passself.md | 0 .../931-MinimumFallingPathSum/hatrick.md | 0 .../931-MinimumFallingPathSum/official.md | 0 .../leetcode}/935-KnightDialer/official.md | 0 .../940-DistinctSubsequencesII/official.md | 0 .../official.md | 0 .../954-ArrayOfDoubledPairs/bigablecat.md | 0 .../956-TallestBillboard/official.md | 0 .../official.md | 0 .../bigablecat.md | 0 .../official.md | 0 .../968-BinaryTreeCameras/official.md | 0 .../968-BinaryTreeCameras/zengdiqing1994.md | 0 .../leetcode}/975-OddEvenJump/official.md | 0 .../official.md | 0 .../leetcode}/sample/concise.md | 0 .../leetcode}/sample/concise.png | Bin .../leetcode}/sample/full.md | 0 .../leetcode}/sample/full.png | Bin .../README.md" | 0 .../zengdiqing1994.md" | 0 .../README.md" | 0 .../zengdiqing1994.md" | 0 .../README.md" | 0 .../zengdiqing1994.md" | 0 .../README.md" | 0 .../zengdiqing1994.md" | 0 .../README.md" | 0 .../zengdiqing1994.md" | 0 .../README.md" | 0 .../README.md" | 0 .../\345\211\221\346\214\207Offer/README.md" | 0 387 files changed, 8652 insertions(+), 2156 deletions(-) create mode 100644 codes/java_dataStructure_luozhaoyong/1.bmp create mode 100644 codes/java_dataStructure_luozhaoyong/2.zip create mode 100644 codes/java_dataStructure_luozhaoyong/3.bmp create mode 100644 codes/java_dataStructure_luozhaoyong/README.md create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/AddOneToHundred.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestArray.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestBinarySearch.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArray.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArraySearch.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray2.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/TestSearch.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo1/util/MyArray.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo10/Node.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo10/TestHuffmanCode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo11/BinarySortTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo11/Node.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo11/TestBinarySortTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo12/BinarySortTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo12/Node.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo12/TestBinarySortTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo13/HashTable.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo13/StuInfo.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo13/TestHashTable.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo14/Graph.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo14/TestGraph.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo14/Vertex.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/DoubleNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/LoopNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/MyQueue.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/MyStack.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/Node.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/TestLoopNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/test/TestDoubleNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/test/TestLoopNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyQueue.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyStack.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo2/test/TestNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo3/TestFibonacci.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo3/TestHanoi.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo3/TestRecursive.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/BubbleSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/HeapSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/InsertSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/MergeSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/QuickSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/RadixQueueSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/RadixSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/SelectionSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo4/ShellSort.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo5/BinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo5/TestBinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo5/TreeNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo6/ArrayBinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo6/TestArrayBinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo7/TestThreadedBinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedBinaryTree.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedNode.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo9/Node.java create mode 100644 codes/java_dataStructure_luozhaoyong/src/demo9/TestHuffmanTree.java create mode 100644 solutions/README.md rename {images => solutions/images}/017_Telephone-keypad2.png (100%) rename {images => solutions/images}/160_example_1.png (100%) rename {images => solutions/images}/160_example_2.png (100%) rename {images => solutions/images}/160_example_3.png (100%) rename {images => solutions/images}/160_statement.png (100%) rename {leetcode => solutions/leetcode}/001-twoSum/README.md (100%) rename {leetcode => solutions/leetcode}/001-twoSum/hatrick.md (100%) rename {leetcode => solutions/leetcode}/001-twoSum/woody.md (100%) rename {leetcode => solutions/leetcode}/002-addTwoNumber/README.md (100%) rename {leetcode => solutions/leetcode}/002-addTwoNumber/monkey.md (100%) rename {leetcode => solutions/leetcode}/003-longestSubstringWithoutRepeatingCharacters/README.md (100%) rename {leetcode => solutions/leetcode}/003-longestSubstringWithoutRepeatingCharacters/monkey.md (100%) rename {leetcode => solutions/leetcode}/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/005-LongestPalindromicSubstring/hatrick.md (100%) rename {leetcode => solutions/leetcode}/005-LongestPalindromicSubstring/official.md (100%) rename {leetcode => solutions/leetcode}/006-ZigZagConversion/README.md (100%) rename {leetcode => solutions/leetcode}/006-ZigZagConversion/zengdiqing.md (100%) rename {leetcode => solutions/leetcode}/015-threeSum/hatrick.md (100%) rename {leetcode => solutions/leetcode}/015-threeSum/official.md (100%) rename {leetcode => solutions/leetcode}/017-LetterCombinationsOfAPhoneNumber/README.md (100%) rename {leetcode => solutions/leetcode}/020-validParentheses/official.md (100%) rename {leetcode => solutions/leetcode}/023-MergeKSortedLists/README.md (100%) rename {leetcode => solutions/leetcode}/024-swapNodesInPairs/official.md (100%) rename {leetcode => solutions/leetcode}/025-reverseNodesInKGroup/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/025-reverseNodesInKGroup/official.md (100%) rename {leetcode => solutions/leetcode}/032-LongestValidParentheses/official.md (100%) rename {leetcode => solutions/leetcode}/033-SearchInRotatedSortedArray/README.md (100%) rename {leetcode => solutions/leetcode}/033-SearchInRotatedSortedArray/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/036-ValidSudoku/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/036-ValidSudoku/official.md (100%) rename {leetcode => solutions/leetcode}/037-SudokuSolver/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/037-SudokuSolver/official.md (100%) rename {leetcode => solutions/leetcode}/048-RotateImage/README.md (100%) rename {leetcode => solutions/leetcode}/048-RotateImage/zengdiqing.md (100%) rename {leetcode => solutions/leetcode}/050-powxN/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/051-NQueens/melody-l.md (100%) rename {leetcode => solutions/leetcode}/051-NQueens/official.md (100%) rename {leetcode => solutions/leetcode}/052-N-QueensII/hatrick.md (100%) rename {leetcode => solutions/leetcode}/052-N-QueensII/official.md (100%) rename {leetcode => solutions/leetcode}/053-maximumSubarray/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/053-maximumSubarray/README.md (100%) rename {leetcode => solutions/leetcode}/053-maximumSubarray/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/054-SpiralMatrix/README.md (100%) rename {leetcode => solutions/leetcode}/054-SpiralMatrix/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/059-SpiralMatrixII/README.md (100%) rename {leetcode => solutions/leetcode}/059-SpiralMatrixII/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/062-UniquePaths/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/062-UniquePaths/official.md (100%) rename {leetcode => solutions/leetcode}/063-UniquePathsII/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/063-UniquePathsII/official.md (100%) rename {leetcode => solutions/leetcode}/064-minimumPathSum/README.md (100%) rename {leetcode => solutions/leetcode}/064-minimumPathSum/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/069-SqrtX/README.md (100%) rename {leetcode => solutions/leetcode}/069-SqrtX/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/070-ClimbingStairs/README.md (100%) rename {leetcode => solutions/leetcode}/070-ClimbingStairs/melody-l.md (100%) rename {leetcode => solutions/leetcode}/072-EditDistance/official.md (100%) rename {leetcode => solutions/leetcode}/075-SortColors/README.md (100%) rename {leetcode => solutions/leetcode}/075-SortColors/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/076-MinimumWindowSubstring/README.md (100%) rename {leetcode => solutions/leetcode}/085-MaximalRectangle/passself.md (100%) rename {leetcode => solutions/leetcode}/087-ScrambleString/official.md (100%) rename {leetcode => solutions/leetcode}/091-DecodeWays/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/091-DecodeWays/official.md (100%) rename {leetcode => solutions/leetcode}/091-DecodeWays/sandao.md (100%) rename {leetcode => solutions/leetcode}/095-UniqueBinarySearchTreesII/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/095-UniqueBinarySearchTreesII/official.md (100%) rename {leetcode => solutions/leetcode}/096-uniqueBinarySearchTrees/official.md (100%) rename {leetcode => solutions/leetcode}/097-InterleavingString/official.md (100%) rename {leetcode => solutions/leetcode}/098-validateBinarySearchTree/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/102-BinaryTreeLevelOrderTraversal/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/102-BinaryTreeLevelOrderTraversal/hatrick.md (100%) rename {leetcode => solutions/leetcode}/102-BinaryTreeLevelOrderTraversal/official.md (100%) rename {leetcode => solutions/leetcode}/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/104-MaximumDepthOfBinaryTree/melody-l.md (100%) rename {leetcode => solutions/leetcode}/104-MaximumDepthOfBinaryTree/official.md (100%) rename {leetcode => solutions/leetcode}/110-BalancedBinaryTree/README.md (100%) rename {leetcode => solutions/leetcode}/110-BalancedBinaryTree/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/110-BalancedBinaryTree/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/115-DistinctSubsequences/official.md (100%) rename {leetcode => solutions/leetcode}/120-Triangle/melody-l.md (100%) rename {leetcode => solutions/leetcode}/120-Triangle/official.md (100%) rename {leetcode => solutions/leetcode}/121-bestTimeToBuyAndSellStock/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/121-bestTimeToBuyAndSellStock/official.md (100%) rename {leetcode => solutions/leetcode}/122-bestTimeToBuyAndSellStockII/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/122-bestTimeToBuyAndSellStockII/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/123-BestTimeToBuyAndSellStockIII/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/123-BestTimeToBuyAndSellStockIII/official.md (100%) rename {leetcode => solutions/leetcode}/131-PalindromePartitioning/official.md (100%) rename {leetcode => solutions/leetcode}/132-PalindromePartitioningII/official.md (100%) rename {leetcode => solutions/leetcode}/139-WordBreak/official.md (100%) rename {leetcode => solutions/leetcode}/140-WordBreakII/official.md (100%) rename {leetcode => solutions/leetcode}/141-linkedListCycle/official.md (100%) rename {leetcode => solutions/leetcode}/142-linkedListCycleII/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/142-linkedListCycleII/official.md (100%) rename {leetcode => solutions/leetcode}/144-BinaryTreePreorderTraversal/README.md (100%) rename {leetcode => solutions/leetcode}/144-BinaryTreePreorderTraversal/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/146-lruCache/hatrick.md (100%) rename {leetcode => solutions/leetcode}/146-lruCache/official.md (100%) rename {leetcode => solutions/leetcode}/152-MaximumProductSubarray/README.md (100%) rename {leetcode => solutions/leetcode}/152-MaximumProductSubarray/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/152-MaximumProductSubarray/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/153-FindMinimumInRotatedSortedArray/README.md (100%) rename {leetcode => solutions/leetcode}/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/160-IntersectionOfTwoLinkedLists/README.md (100%) rename {leetcode => solutions/leetcode}/160-IntersectionOfTwoLinkedLists/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/167-TwoSumII/README.md (100%) rename {leetcode => solutions/leetcode}/167-TwoSumII/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/169-majorityElement/README.md (100%) rename {leetcode => solutions/leetcode}/169-majorityElement/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/169-majorityElement/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/169-majorityElement/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/174-DungeonGame/passself.md (100%) rename {leetcode => solutions/leetcode}/188-bestTimeToBuyAndSellStockIV/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/188-bestTimeToBuyAndSellStockIV/official.md (100%) rename {leetcode => solutions/leetcode}/191-NumberOf1Bits/README.md (100%) rename {leetcode => solutions/leetcode}/191-NumberOf1Bits/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/198-houseRobber/README.md (100%) rename {leetcode => solutions/leetcode}/198-houseRobber/hatrick.md (100%) rename {leetcode => solutions/leetcode}/200-numberOfIslands/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/200-numberOfIslands/official.md (100%) rename {leetcode => solutions/leetcode}/206-reverseLinkedList/official.md (100%) rename {leetcode => solutions/leetcode}/207-CourseSchedule/README.md (100%) rename {leetcode => solutions/leetcode}/207-CourseSchedule/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/208-implementTriePrefixTree/README.md (100%) rename {leetcode => solutions/leetcode}/208-implementTriePrefixTree/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/212-wordSearchII/official.md (100%) rename {leetcode => solutions/leetcode}/213-HouseRobberII/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/213-HouseRobberII/official.md (100%) rename {leetcode => solutions/leetcode}/215-KthLargestElementInAnArray/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/215-KthLargestElementInAnArray/README.md (100%) rename {leetcode => solutions/leetcode}/215-KthLargestElementInAnArray/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/221-MaximalSquare/official.md (100%) rename {leetcode => solutions/leetcode}/225-implementStackUsingQueues/hatrick.md (100%) rename {leetcode => solutions/leetcode}/225-implementStackUsingQueues/official.md (100%) rename {leetcode => solutions/leetcode}/230-KthSmallestElementInABST/README.md (100%) rename {leetcode => solutions/leetcode}/230-KthSmallestElementInABST/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/231-PowerOfTwo/hatrick.md (100%) rename {leetcode => solutions/leetcode}/231-PowerOfTwo/official.md (100%) rename {leetcode => solutions/leetcode}/232-implementQueueUsingStacks/README.md (100%) rename {leetcode => solutions/leetcode}/232-implementQueueUsingStacks/hatrick.md (100%) rename {leetcode => solutions/leetcode}/236-lowestCommonAncestorOfABinaryTree/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/239-slidingWindowMaximum/official.md (100%) rename {leetcode => solutions/leetcode}/241-DifferentWaysToAddParentheses/README.md (100%) rename {leetcode => solutions/leetcode}/241-DifferentWaysToAddParentheses/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/242-ValidAnagram/README.md (100%) rename {leetcode => solutions/leetcode}/242-ValidAnagram/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/242-ValidAnagram/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/260-SingleNumberIII/README.md (100%) rename {leetcode => solutions/leetcode}/260-SingleNumberIII/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/264-UglyNumberII/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/264-UglyNumberII/official.md (100%) rename {leetcode => solutions/leetcode}/279-PerfectSquares/README.md (100%) rename {leetcode => solutions/leetcode}/279-PerfectSquares/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/279-PerfectSquares/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/295-FindMedianFromDataStream/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/300-LongestIncreasingSubsequence/README.md (100%) rename {leetcode => solutions/leetcode}/300-LongestIncreasingSubsequence/melody-l.md (100%) rename {leetcode => solutions/leetcode}/303-rangeSumQueryImmutable/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/303-rangeSumQueryImmutable/README.md (100%) rename {leetcode => solutions/leetcode}/304-RangeSumQuery2DImmutable/official.md (100%) rename {leetcode => solutions/leetcode}/304-RangeSumQuery2DImmutable/woody.md (100%) rename {leetcode => solutions/leetcode}/309-BestTimeToBuyAndSellStockWithCooldown/README.md (100%) rename {leetcode => solutions/leetcode}/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/312-BurstBalloons/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/312-BurstBalloons/official.md (100%) rename {leetcode => solutions/leetcode}/321-CreateMaximumNumber/README.md (100%) rename {leetcode => solutions/leetcode}/322-CoinChange/official.md (100%) rename {leetcode => solutions/leetcode}/338-CountingBits/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/343-IntegerBreak/README.md (100%) rename {leetcode => solutions/leetcode}/343-IntegerBreak/hatrick.md (100%) rename {leetcode => solutions/leetcode}/347-TopKFrequentElements/README.md (100%) rename {leetcode => solutions/leetcode}/347-TopKFrequentElements/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/354-RussianDollEnvelopes/official.md (100%) rename {leetcode => solutions/leetcode}/354-RussianDollEnvelopes/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/357-CountNumbersWithUniqueDigits/official.md (100%) rename {leetcode => solutions/leetcode}/363-MaxSumOfRectangleNoLargerThanK/official.md (100%) rename {leetcode => solutions/leetcode}/367-ValidPerfectSquare/official.md (100%) rename {leetcode => solutions/leetcode}/368-LargestDivisibleSubset/passself.md (100%) rename {leetcode => solutions/leetcode}/374-GuessNumberHigherOrLower/official.md (100%) rename {leetcode => solutions/leetcode}/375-GuessNumberHigherOrLowerII/official.md (100%) rename {leetcode => solutions/leetcode}/376-WiggleSubsequence/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/376-WiggleSubsequence/official.md (100%) rename {leetcode => solutions/leetcode}/377-CombinationSumIV/official.md (100%) rename {leetcode => solutions/leetcode}/378-KthSmallestElementInASortedMatrix/README.md (100%) rename {leetcode => solutions/leetcode}/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/392-IsSubsequence/official.md (100%) rename {leetcode => solutions/leetcode}/392-IsSubsequence/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/403-FrogJump/README.md (100%) rename {leetcode => solutions/leetcode}/409-LongestPalindrome/README.md (100%) rename {leetcode => solutions/leetcode}/409-LongestPalindrome/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/410-SplitArrayLargestSum/hatrick.md (100%) rename {leetcode => solutions/leetcode}/410-SplitArrayLargestSum/official.md (100%) rename {leetcode => solutions/leetcode}/413-arithmeticSlices/official.md (100%) rename {leetcode => solutions/leetcode}/416-PartitionEqualSubsetSum/README.md (100%) rename {leetcode => solutions/leetcode}/416-PartitionEqualSubsetSum/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/446-ArithmeticSlicesIISubsequence/official.md (100%) rename {leetcode => solutions/leetcode}/455-AssignCookies/README.md (100%) rename {leetcode => solutions/leetcode}/455-AssignCookies/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/455-AssignCookies/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/462-MinimumMovesToEqualArrayElementsII/README.md (100%) rename {leetcode => solutions/leetcode}/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/464-CanIWin/official.md (100%) rename {leetcode => solutions/leetcode}/467-UniqueSubstringsInWraparoundString/passself.md (100%) rename {leetcode => solutions/leetcode}/472-ConcatenatedWords/official.md (100%) rename {leetcode => solutions/leetcode}/474-OnesAndZeroes/hatrick.md (100%) rename {leetcode => solutions/leetcode}/474-OnesAndZeroes/official.md (100%) rename {leetcode => solutions/leetcode}/486-PredictTheWinner/official.md (100%) rename {leetcode => solutions/leetcode}/494-TargetSum/official.md (100%) rename {leetcode => solutions/leetcode}/504-Base7/README.md (100%) rename {leetcode => solutions/leetcode}/504-Base7/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/513-FindBottomLeftTreeValue/README.md (100%) rename {leetcode => solutions/leetcode}/513-FindBottomLeftTreeValue/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/513-FindBottomLeftTreeValue/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/514-FreedomTrail/hatrick.md (100%) rename {leetcode => solutions/leetcode}/514-FreedomTrail/official.md (100%) rename {leetcode => solutions/leetcode}/516-LongestPalindromicSubsequence/passself.md (100%) rename {leetcode => solutions/leetcode}/517-SuperWashingMachines/official.md (100%) rename {leetcode => solutions/leetcode}/523-ContinuousSubarraySum/hatrick.md (100%) rename {leetcode => solutions/leetcode}/523-ContinuousSubarraySum/official.md (100%) rename {leetcode => solutions/leetcode}/546-RemoveBoxes/passself.md (100%) rename {leetcode => solutions/leetcode}/547-friendCircles/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/551-StudentAttendanceRecordI/official.md (100%) rename {leetcode => solutions/leetcode}/552-StudentAttendanceRecordII/official.md (100%) rename {leetcode => solutions/leetcode}/557-Reverse Words in a String III/sandao.md (100%) rename {leetcode => solutions/leetcode}/576-OutOfBoundaryPaths/official.md (100%) rename {leetcode => solutions/leetcode}/576-OutOfBoundaryPaths/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/583-DeleteOperationForTwoStrings/README.md (100%) rename {leetcode => solutions/leetcode}/629-KInversePairsArray/official.md (100%) rename {leetcode => solutions/leetcode}/629-KInversePairsArray/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/638-ShoppingOffers/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/646-MaximumLengthOfPairChain/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/646-MaximumLengthOfPairChain/official.md (100%) rename {leetcode => solutions/leetcode}/647-PalindromicSubstrings/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/647-PalindromicSubstrings/official.md (100%) rename {leetcode => solutions/leetcode}/650-2KeysKeyboard/mahone.md (100%) rename {leetcode => solutions/leetcode}/650-2KeysKeyboard/official.md (100%) rename {leetcode => solutions/leetcode}/664-StrangePrinter/official.md (100%) rename {leetcode => solutions/leetcode}/673-NumberOfLongestIncreasingSubsequence/README.md (100%) rename {leetcode => solutions/leetcode}/673-NumberOfLongestIncreasingSubsequence/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/684-RedundantConnection/README.md (100%) rename {leetcode => solutions/leetcode}/684-RedundantConnection/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/688-KnightProbabilityInChessboard/passself.md (100%) rename {leetcode => solutions/leetcode}/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/689-MaximumSumOf3Non-OverlappingSubarrays/official.md (100%) rename {leetcode => solutions/leetcode}/691-StickersToSpellWord/official.md (100%) rename {leetcode => solutions/leetcode}/692-TopKFrequentWords/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/695-MaxAreaOfIsland/README.md (100%) rename {leetcode => solutions/leetcode}/698-PartitionToKEqualSumSubsets/hatrick.md (100%) rename {leetcode => solutions/leetcode}/698-PartitionToKEqualSumSubsets/official.md (100%) rename {leetcode => solutions/leetcode}/703-KthLargestElementInAStream/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/712-MinimumASCIIDeleteSumforTwoStrings/official.md (100%) rename {leetcode => solutions/leetcode}/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md (100%) rename {leetcode => solutions/leetcode}/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md (100%) rename {leetcode => solutions/leetcode}/718-MaximumLengthOfRepeatedSubarray/mahone.md (100%) rename {leetcode => solutions/leetcode}/718-MaximumLengthOfRepeatedSubarray/official.md (100%) rename {leetcode => solutions/leetcode}/730-CountDifferentPalindromicSubsequences/official.md (100%) rename {leetcode => solutions/leetcode}/740-DeleteAndEarn/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/740-DeleteAndEarn/official.md (100%) rename {leetcode => solutions/leetcode}/746-minCostClimbingStairs/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/746-minCostClimbingStairs/official.md (100%) rename {leetcode => solutions/leetcode}/764-LargestPlusSign/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/764-LargestPlusSign/official.md (100%) rename {leetcode => solutions/leetcode}/785-IsGraphBipartite/README.md (100%) rename {leetcode => solutions/leetcode}/785-IsGraphBipartite/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/787-CheapestFlightsWithinKStops/official.md (100%) rename {leetcode => solutions/leetcode}/787-CheapestFlightsWithinKStops/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/790-DominoAndTrominoTiling/mahone.md (100%) rename {leetcode => solutions/leetcode}/790-DominoAndTrominoTiling/official.md (100%) rename {leetcode => solutions/leetcode}/801-MinimumSwapsToMakeSequencesIncreasing/official.md (100%) rename {leetcode => solutions/leetcode}/808-SoupServings/official.md (100%) rename {leetcode => solutions/leetcode}/813-LargestSumOfAverages/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/813-LargestSumOfAverages/official.md (100%) rename {leetcode => solutions/leetcode}/837-New21Game/official.md (100%) rename {leetcode => solutions/leetcode}/838-PushDominoes/official.md (100%) rename {leetcode => solutions/leetcode}/844-BackspaceStringCompare/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/844-BackspaceStringCompare/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/847-ShortestPathVisitingAllNodes/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/847-ShortestPathVisitingAllNodes/official.md (100%) rename {leetcode => solutions/leetcode}/860-lemonadeChange/BambooYH.md (100%) rename {leetcode => solutions/leetcode}/860-lemonadeChange/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/860-lemonadeChange/official.md (100%) rename {leetcode => solutions/leetcode}/873-LengthOfLongestFibonacciSubsequence/official.md (100%) rename {leetcode => solutions/leetcode}/874-walkingRobotSimulation/SpecialYang.md (100%) rename {leetcode => solutions/leetcode}/874-walkingRobotSimulation/hatrick.md (100%) rename {leetcode => solutions/leetcode}/874-walkingRobotSimulation/official.md (100%) rename {leetcode => solutions/leetcode}/875-KokoEatingBananas/sandao.md (100%) rename {leetcode => solutions/leetcode}/877-stoneGame/melody-l.md (100%) mode change 100755 => 100644 rename {leetcode => solutions/leetcode}/877-stoneGame/official.md (100%) rename {leetcode => solutions/leetcode}/898-BitwiseORsOfSubarrays/official.md (100%) rename {leetcode => solutions/leetcode}/903-ValidPermutationsForDISequence/official.md (100%) rename {leetcode => solutions/leetcode}/903-ValidPermutationsForDISequence/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/920-NumberOfMusicPlaylists/passself.md (100%) rename {leetcode => solutions/leetcode}/931-MinimumFallingPathSum/hatrick.md (100%) rename {leetcode => solutions/leetcode}/931-MinimumFallingPathSum/official.md (100%) rename {leetcode => solutions/leetcode}/935-KnightDialer/official.md (100%) rename {leetcode => solutions/leetcode}/940-DistinctSubsequencesII/official.md (100%) rename {leetcode => solutions/leetcode}/943-FindTheShortestSuperstring/official.md (100%) rename {leetcode => solutions/leetcode}/954-ArrayOfDoubledPairs/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/956-TallestBillboard/official.md (100%) rename {leetcode => solutions/leetcode}/964-LeastOperatorsToExpressNumber/official.md (100%) rename {leetcode => solutions/leetcode}/967-NumbersWithSameConsecutiveDifferences/bigablecat.md (100%) rename {leetcode => solutions/leetcode}/967-NumbersWithSameConsecutiveDifferences/official.md (100%) rename {leetcode => solutions/leetcode}/968-BinaryTreeCameras/official.md (100%) rename {leetcode => solutions/leetcode}/968-BinaryTreeCameras/zengdiqing1994.md (100%) rename {leetcode => solutions/leetcode}/975-OddEvenJump/official.md (100%) rename {leetcode => solutions/leetcode}/982-TriplesWithBitwiseANDEqualToZero/official.md (100%) rename {leetcode => solutions/leetcode}/sample/concise.md (100%) rename {leetcode => solutions/leetcode}/sample/concise.png (100%) rename {leetcode => solutions/leetcode}/sample/full.md (100%) rename {leetcode => solutions/leetcode}/sample/full.png (100%) rename "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" => "solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" (100%) rename "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" => "solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" (100%) rename "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" => "solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" (100%) rename "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" => "solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" (100%) rename "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" => "solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" (100%) rename "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" => "solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" (100%) rename "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" => "solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" (100%) rename "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" => "solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" (100%) rename "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" => "solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" (100%) rename "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" => "solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" (100%) rename "\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" => "solutions/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" (100%) rename "\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" => "solutions/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" (100%) rename "\345\211\221\346\214\207Offer/README.md" => "solutions/\345\211\221\346\214\207Offer/README.md" (100%) diff --git a/README.md b/README.md index ac5cec1..dad72a7 100644 --- a/README.md +++ b/README.md @@ -1,2156 +1,982 @@ - -### 算法每日一练 - -* 这个专栏是Hollis知识星球的朋友们练习算法的地方,同时也欢迎广大网友参与 -* 所有题目来源是[leetCode](https://leetcode-cn.com/problemset/all/)官方公开题库 - -### 初学者友好的算法题目解答 - -* 算法解答部分的代码注释细致到每一行 -* 希望能为初学者提供最大的便利去理解每道题目和解法 -* 欢迎网友为本项目做贡献,提交你的解题方法和详细解释 - ---- - -### 专题列表 -* 2018年11月27日~2019年01月16日 ->[《算法面试通关40讲》专题](https://time.geekbang.org/course/intro/130) ->[《算法面试通关40讲》官方课件](https://github.com/geektime-geekbang/algorithm-1) - -* 2018年11月16日 ->LeetCode动态规划专题 - ---- - -专题(Begin):《算法面试40讲》 ---- - -2018年11月27日 - -[206. 反转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/206-reverseLinkedList) - -[https://leetcode-cn.com/problems/reverse-linked-list/](https://leetcode-cn.com/problems/reverse-linked-list/) - -英文官方题解: - -[https://leetcode.com/articles/reverse-linked-list/](https://leetcode.com/articles/reverse-linked-list/) - -知识点:数组、链表 - -难度:简单 - ---- - -2018年11月28日 - -[24. 两两交换链表中的节点](https://github.com/hollischuang/algorithm/tree/master/leetcode/024-swapNodesInPairs) - -[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) - -无官方题解,网友最高票Java解法: - -[https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.](https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.) - -知识点:数组、链表 - -难度:中等 - ---- - -2018年11月29日 - -[141. 环形链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/141-linkedListCycle) - -[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) - -官方题解: - -[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) - -知识点:数组、链表 - -难度:简单 - ---- - -2018年11月30日 - -[142. 环形链表 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/142-linkedListCycleII) - -[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) - -知识点:数组、链表 - -难度:中等 - ---- - -2018年12月01日 - -[25. k个一组翻转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/025-reverseNodesInKGroup) - -[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments](https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments) - -知识点:数组、链表 - -难度:困难 - ---- - -2018年12月02日 - -[20. 有效的括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/020-validParentheses) - -[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) - -官方题解: - -[https://leetcode-cn.com/articles/valid-parentheses/](https://leetcode-cn.com/articles/valid-parentheses/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月03日 - -[232. 用栈实现队列](https://github.com/hollischuang/algorithm/tree/master/leetcode/232-implementQueueUsingStacks) - -[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) - -英文官方题解: - -[https://leetcode.com/articles/implement-queue-using-stacks/](https://leetcode.com/articles/implement-queue-using-stacks/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月04日 - -[225. 用队列实现栈](https://github.com/hollischuang/algorithm/tree/master/leetcode/225-implementStackUsingQueues) - -[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) - -英文官方题解: - -[https://leetcode.com/articles/implement-stack-using-queues/](https://leetcode.com/articles/implement-stack-using-queues/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月05日 - -[844. 比较含退格的字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/844-BackspaceStringCompare) - -[https://leetcode-cn.com/problems/backspace-string-compare/](https://leetcode-cn.com/problems/backspace-string-compare/) - -英文官方题解: - -[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) - -知识点:堆栈、队列 - -难度:简单 - ---- - -2018年12月06日 - -[703. 数据流中的第K大元素](https://github.com/hollischuang/algorithm/tree/master/leetcode/703-KthLargestElementInAStream) - -[https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) - -知识点:优先队列 - -难度:简单 - ---- - -2018年12月07日 - -[692. 前K个高频单词](https://github.com/hollischuang/algorithm/tree/master/leetcode/692-TopKFrequentWords) - -[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) - -英文官方题解: - -[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) - -知识点:优先队列 - -难度:中等 - ---- - -2018年12月08日 - -[239. 滑动窗口最大值](https://github.com/hollischuang/algorithm/tree/master/leetcode/239-slidingWindowMaximum) - -[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/sliding-window-maximum/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation](https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation) - -知识点:优先队列 - -难度:困难 - ---- - -2018年12月09日 - -[242. 有效的字母异位词](https://github.com/hollischuang/algorithm/tree/master/leetcode/242-ValidAnagram) - -[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) - -英文官方题解: - -[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) - -知识点:哈希表和集合 - -难度:简单 - ---- - -2018年12月10日 - -[1. 两数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/001-twoSum) - -[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) - -官方题解: - -[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) - -知识点:哈希表和集合 - -难度:简单 - ---- - -2018年12月11日 - -[15. 三数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/015-threeSum) - -[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution](https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution) - -知识点:哈希表和集合 - -难度:中等 - ---- - -2018年12月12日 - -[98. 验证二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/098-validateBinarySearchTree) - -[https://leetcode-cn.com/problems/validate-binary-search-tree/](https://leetcode-cn.com/problems/validate-binary-search-tree/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)](https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines](https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines) - -知识点:树、二叉树、二叉搜索树 - -难度:中等 - ---- - -2018年12月13日 - -[236. 二叉树的最近公共祖先](https://github.com/hollischuang/algorithm/tree/master/leetcode/236-lowestCommonAncestorOfABinaryTree) - -[https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) - -英文官方题解: - -[https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/) - -知识点:树、二叉树、二叉搜索树 - -难度:中等 - ---- - -2018年12月14日 - -[50. Pow(x, n)](https://github.com/hollischuang/algorithm/tree/master/leetcode/050-powxN) - -[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers](https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers) - -知识点:递归、分治 - -难度:中等 - ---- - -2018年12月15日 - -[169. 求众数](https://github.com/hollischuang/algorithm/tree/master/leetcode/169-majorityElement) - -[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) - -英文官方题解: - -[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) - -知识点:递归、分治 - -难度:简单 - ---- - -2018年12月16日 - -[53. 最大子序和](https://github.com/hollischuang/algorithm/tree/master/leetcode/053-maximumSubarray) - -[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts](https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java](https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java) - -知识点:递归、分治、动态规划 - -难度:简单 - ---- - -2018年12月17日 - -[860. 柠檬水找零](https://github.com/hollischuang/algorithm/tree/master/leetcode/860-lemonadeChange) - -[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) - -官方题解: - -[https://leetcode-cn.com/articles/lemonade-change/](https://leetcode-cn.com/articles/lemonade-change/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月18日 - -[122. 买卖股票的最佳时机 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/122-bestTimeToBuyAndSellStockII) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) - -官方题解: - -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月19日 - -[455. 分发饼干](https://github.com/hollischuang/algorithm/tree/master/leetcode/455-AssignCookies) - -[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)](https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月20日 - -[874. 模拟行走机器人](https://github.com/hollischuang/algorithm/tree/master/leetcode/874-walkingRobotSimulation) - -[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) - -英文官方题解: - -[https://leetcode.com/problems/walking-robot-simulation/solution/](https://leetcode.com/problems/walking-robot-simulation/solution/) - -知识点:贪心算法 - -难度:简单 - ---- - -2018年12月21日 - -[102. 二叉树的层次遍历](https://github.com/hollischuang/algorithm/tree/master/leetcode/102-BinaryTreeLevelOrderTraversal) - -[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS) - -知识点:广度优先搜索 - -难度:中等 - ---- - -2018年12月22日 - -[104. 二叉树的最大深度](https://github.com/hollischuang/algorithm/tree/master/leetcode/104-MaximumDepthOfBinaryTree) - -[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) - -官方题解: - -[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) - -知识点:深度优先搜索 - -难度:简单 - ---- - -2018年12月23日 - -[51. N-皇后](https://github.com/hollischuang/algorithm/tree/master/leetcode/051-NQueens) - -[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.](https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.) - -知识点:剪枝 - -难度:困难 - ---- - -2018年12月24日 - -[36. 有效的数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/036-ValidSudoku) - -[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings](https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code](https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code) - -知识点:剪枝 - -难度:中等 - ---- - -2018年12月25日 - -[37. 解数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/037-SudokuSolver) - -[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking](https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking) - -知识点:剪枝 - -难度:困难 - ---- - -2018年12月26日 - -[69. x 的平方根](https://github.com/hollischuang/algorithm/tree/master/leetcode/069-SqrtX) - -[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) - -知识点:二分查找 - -难度:简单 - ---- - -2018年12月27日 - -[367. 有效的完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) - -[https://leetcode-cn.com/problems/valid-perfect-square/](https://leetcode-cn.com/problems/valid-perfect-square/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code](https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code) - -知识点:二分查找 - -难度:简单 - ---- - -2018年12月28日 - -[208. 实现 Trie (前缀树)](https://github.com/hollischuang/algorithm/tree/master/leetcode/208-implementTriePrefixTree) - -[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) - -英文官方题解: - -[https://leetcode.com/articles/implement-trie-prefix-tree/](https://leetcode.com/articles/implement-trie-prefix-tree/) - -知识点:字典树 - -难度:中等 - ---- - -2018年12月29日 - -[212. 单词搜索 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/212-wordSearchII) - -[https://leetcode-cn.com/problems/word-search-ii/](https://leetcode-cn.com/problems/word-search-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)](https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)) - -知识点:字典树 - -难度:困难 - ---- - -2018年12月30日 - -[191. 位1的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/191-NumberOf1Bits) - -[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) - -英文官方题解: - -[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) - -知识点:位运算 - -难度:简单 - ---- - -2018年12月31日 - -[338. 比特位计数](https://github.com/hollischuang/algorithm/tree/master/leetcode/338-CountingBits) - -[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) - -知识点:位运算 - -难度:中等 - ---- - -2019年01月01日 - -[231. 2的幂](https://github.com/hollischuang/algorithm/tree/master/leetcode/231-PowerOfTwo) - -[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount](https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount) - -知识点:位运算 - -难度:简单 - ---- - -2019年01月02日 - -[52. N皇后 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/052-N-QueensII) - -[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution](https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)) - -知识点:位运算 - -难度:困难 - ---- - -2019年01月03日 - -[70. 爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/070-ClimbingStairs) - -[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) - -英文官方题解: - -[https://leetcode.com/articles/climbing-stairs/](https://leetcode.com/articles/climbing-stairs/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月04日 - -[120. 三角形最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/120-Triangle) - -[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle](https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution](https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月05日 - -[152. 乘积最大子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/152-MaximumProductSubarray) - -[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity](https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time](https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月06日 - -[123. 买卖股票的最佳时机 III](https://github.com/hollischuang/algorithm/tree/master/leetcode/123-BestTimeToBuyAndSellStockIII) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月07日 - -[121. 买卖股票的最佳时机](https://github.com/hollischuang/algorithm/tree/master/leetcode/121-bestTimeToBuyAndSellStock) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) - -官方题解: - -[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月08日 - -[188. 买卖股票的最佳时机 IV](https://github.com/hollischuang/algorithm/tree/master/leetcode/188-bestTimeToBuyAndSellStockIV) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月09日 - -[309. 最佳买卖股票时机含冷冻期](https://github.com/hollischuang/algorithm/tree/master/leetcode/309-BestTimeToBuyAndSellStockWithCooldown) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月10日 - -[714. 买卖股票的最佳时机含手续费](https://github.com/hollischuang/algorithm/tree/master/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee) - -[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) - -英文官方题解: - -[https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月11日 - -[300. 最长上升子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/300-LongestIncreasingSubsequence) - -[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/longest-increasing-subsequence/](https://leetcode.com/articles/longest-increasing-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月12日 - -[322. 零钱兑换](https://github.com/hollischuang/algorithm/tree/master/leetcode/322-CoinChange) - -[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) - -英文官方题解: - -[https://leetcode.com/articles/coin-change/](https://leetcode.com/articles/coin-change/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月13日 - -[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) - -[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) - -英文官方题解: - -[https://leetcode.com/articles/edit-distance/](https://leetcode.com/articles/edit-distance/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年01月14日 - -[200. 岛屿的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/200-numberOfIslands) - -[https://leetcode-cn.com/problems/number-of-islands/](https://leetcode-cn.com/problems/number-of-islands/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution](https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution) - -知识点:并查集 - -难度:中等 - ---- - -2019年01月15日 - -[547. 朋友圈](https://github.com/hollischuang/algorithm/tree/master/leetcode/547-friendCircles) - -[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) - -无官方题解,网友高票Java解法1(DFS): - -[https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution](https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution) - -无官方题解,网友高票Java解法2(Union Find): - -[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) - -知识点:并查集 - -难度:中等 - ---- - -2019年01月16日 - -[146. LRU缓存机制](https://github.com/hollischuang/algorithm/tree/master/leetcode/146-lruCache) - -[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)](https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)) - -知识点:LRU - -难度:困难 - ---- - -专题(End):《算法面试40讲》 ---- - -
- -专题(Begin):动态规划 ---- - -2019年01月17日 - -[303. 区域和检索 - 数组不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/303-rangeSumQueryImmutable) - -[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) - -英文官方题解: - -[https://leetcode.com/articles/range-sum-query-immutable/](https://leetcode.com/articles/range-sum-query-immutable/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月18日 - -[746. 使用最小花费爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/746-minCostClimbingStairs) - -[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) - -英文官方题解: - -[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月19日 - -[198. 打家劫舍](https://github.com/hollischuang/algorithm/tree/master/leetcode/198-houseRobber) - -[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.) - -知识点:动态规划 - -难度:简单 - ---- - -2019年01月20日 - -[877. 石子游戏](https://github.com/hollischuang/algorithm/tree/master/leetcode/877-stoneGame) - -[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) - -官方题解: - -[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月21日 - -[64. 最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/064-minimumPathSum) - -[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月22日 - -[96. 不同的二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/096-uniqueBinarySearchTrees) - -[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) - -英文官方题解: - -[https://leetcode.com/articles/unique-binary-search-trees/](https://leetcode.com/articles/unique-binary-search-trees/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月23日 - -[413. 等差数列划分](https://github.com/hollischuang/algorithm/tree/master/leetcode/413-arithmeticSlices) - -[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) - -英文官方题解: - -[https://leetcode.com/articles/arithmetic-slices/](https://leetcode.com/articles/arithmetic-slices/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月24日 - -[712. 两个字符串的最小ASCII删除和](https://github.com/hollischuang/algorithm/tree/master/leetcode/712-MinimumASCIIDeleteSumforTwoStrings) - -[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月25日 - -[62. 不同路径](https://github.com/hollischuang/algorithm/tree/master/leetcode/062-UniquePaths) - -[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space](https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)](https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月26日 - -[638. 大礼包](https://github.com/hollischuang/algorithm/tree/master/leetcode/638-ShoppingOffers) - -[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) - -英文官方题解: - -[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月27日 - -[647. 回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/647-PalindromicSubstrings) - -[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) - -英文官方题解: - -[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月28日 - -[931. 下降路径最小和](https://github.com/hollischuang/algorithm/tree/master/leetcode/931-MinimumFallingPathSum) - -[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-path-falling-sum/](https://leetcode.com/articles/minimum-path-falling-sum/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月29日 - -[343. 整数拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/343-IntegerBreak) - -[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution](https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月30日 - -[95. 不同的二叉搜索树 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/095-UniqueBinarySearchTreesII) - -[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) - -英文官方题解: - -[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年01月31日 - -[740. 删除与获得点数](https://github.com/hollischuang/algorithm/tree/master/leetcode/740-DeleteAndEarn) - -[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) - -英文官方题解: - -[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月01日 - -[646. 最长数对链](https://github.com/hollischuang/algorithm/tree/master/leetcode/646-MaximumLengthOfPairChain) - -[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) - -英文官方题解: - -[https://leetcode.com/articles/maximum-length-of-pair-chain/](https://leetcode.com/articles/maximum-length-of-pair-chain/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月02日 - -[764. 最大加号标志](https://github.com/hollischuang/algorithm/tree/master/leetcode/764-LargestPlusSign) - -[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) - -英文官方题解: - -[https://leetcode.com/articles/largest-plus-sign/](https://leetcode.com/articles/largest-plus-sign/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月03日 - -[279. 完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/279-PerfectSquares) - -[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月04日 - -[392. 判断子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/392-IsSubsequence) - -[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments](https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月05日 - -[377. 组合总和 Ⅳ](https://github.com/hollischuang/algorithm/tree/master/leetcode/377-CombinationSumIV) - -[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation](https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月06日 - -[486. 预测赢家](https://github.com/hollischuang/algorithm/tree/master/leetcode/486-PredictTheWinner) - -[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) - -英文官方题解: - -[https://leetcode.com/articles/predict-the-winner/](https://leetcode.com/articles/predict-the-winner/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月07日 - -[357. 计算各个位数不同的数字个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/357-CountNumbersWithUniqueDigits) - -[https://leetcode-cn.com/problems/count-numbers-with-unique-digits/](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月08日 - -[494. 目标和](https://github.com/hollischuang/algorithm/tree/master/leetcode/494-TargetSum) - -[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) - -英文官方题解: - -[https://leetcode.com/articles/target-sum/](https://leetcode.com/articles/target-sum/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月09日 - -[516. 最长回文子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/516-LongestPalindromicSubsequence) - -[https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution](https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月10日 - -[688. “马”在棋盘上的概率](https://github.com/hollischuang/algorithm/tree/master/leetcode/688-KnightProbabilityInChessboard) - -[https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) - -英文官方题解: - -[https://leetcode.com/articles/knight-probability-in-chessboard/](https://leetcode.com/articles/knight-probability-in-chessboard/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月11日 - -[718. 最长重复子数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/718-MaximumLengthOfRepeatedSubarray) - -[https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/) - -英文官方题解: - -[https://leetcode.com/articles/maximum-length-of-repeated-subarray/](https://leetcode.com/articles/maximum-length-of-repeated-subarray/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月12日 - -[650. 只有两个键的键盘](https://github.com/hollischuang/algorithm/tree/master/leetcode/650-2KeysKeyboard) - -[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) - -英文官方题解: - -[https://leetcode.com/articles/2-keys-keyboard/](https://leetcode.com/articles/2-keys-keyboard/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月13日 - -[873. 最长的斐波那契子序列的长度](https://github.com/hollischuang/algorithm/tree/master/leetcode/873-LengthOfLongestFibonacciSubsequence) - -[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) - -官方题解: - -[https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月14日 - -[139. 单词拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/139-WordBreak) - -[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways](https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月15日 - -[264. 丑数 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/264-UglyNumberII) - -[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月16日 - -[416. 分割等和子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/416-PartitionEqualSubsetSum) - -[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月17日 - -[304. 二维区域和检索 - 矩阵不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/304-RangeSumQuery2DImmutable) - -[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) - -英文无官方题解: - -[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月18日 - -[221. 最大正方形](https://github.com/hollischuang/algorithm/tree/master/leetcode/221-MaximalSquare) - -[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) - -英文官方题解: - -[https://leetcode.com/articles/maximal-square/](https://leetcode.com/articles/maximal-square/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月19日 - -[698. 划分为k个相等的子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/698-PartitionToKEqualSumSubsets) - -[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) - -英文官方题解: - -[https://leetcode.com/articles/partition-to-k-equal-sum-subsets/](https://leetcode.com/articles/partition-to-k-equal-sum-subsets/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月20日 - -[474. 一和零](https://github.com/hollischuang/algorithm/tree/master/leetcode/474-OnesAndZeroes) - -[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.](https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space](https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月21日 - -[838. 推多米诺](https://github.com/hollischuang/algorithm/tree/master/leetcode/838-PushDominoes) - -[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/articles/push-dominoes/](https://leetcode.com/articles/push-dominoes/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月22日 - -[790. 多米诺和托米诺平铺](https://github.com/hollischuang/algorithm/tree/master/leetcode/790-DominoAndTrominoTiling) - -[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月23日 - -[813. 最大平均值和的分组](https://github.com/hollischuang/algorithm/tree/master/leetcode/813-LargestSumOfAverages) - -[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) - -英文官方题解: - -[https://leetcode.com/articles/largest-sum-of-averages/](https://leetcode.com/articles/largest-sum-of-averages/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月24日 - -[376. 摆动序列变](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) - -[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月25日 - -[801. 使序列递增的最小交换次数](https://github.com/hollischuang/algorithm/tree/master/leetcode/801-MinimumSwapsToMakeSequencesIncreasing) - -[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) - -英文官方题解: - -[https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/](https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月26日 - -[808. 分汤](https://github.com/hollischuang/algorithm/tree/master/leetcode/808-SoupServings) - -[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) - -英文官方题解: - -[https://leetcode.com/articles/soup-servings/](https://leetcode.com/articles/soup-servings/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月27日 - -[63. 不同路径 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/063-UniquePathsII) - -[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) - -英文官方题解: - -[https://leetcode.com/articles/unique-paths-ii/](https://leetcode.com/articles/unique-paths-ii/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年02月28日 - -[213. 打家劫舍 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/213-HouseRobberII) - -[https://leetcode-cn.com/problems/house-robber-ii/](https://leetcode-cn.com/problems/house-robber-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation](https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月01日 - -[368. 最大整除子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/368-LargestDivisibleSubset) - -[https://leetcode-cn.com/problems/largest-divisible-subset/](https://leetcode-cn.com/problems/largest-divisible-subset/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)](https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月02日 - -[467. 环绕字符串中唯一的子字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/467-UniqueSubstringsInWraparoundString) - -[https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月03日 - -[464. 我能赢吗](https://github.com/hollischuang/algorithm/tree/master/leetcode/464-CanIWin) - -[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation](https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation](https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月04日 - -[935. 骑士拨号器](https://github.com/hollischuang/algorithm/tree/master/leetcode/935-KnightDialer) - -[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) - -英文官方题解: - -[https://leetcode.com/articles/knight-dialer/](https://leetcode.com/articles/knight-dialer/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月05日 - -[787. K 站中转内最便宜的航班](https://github.com/hollischuang/algorithm/tree/master/leetcode/787-CheapestFlightsWithinKStops) - -[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月06日 - -[576. 出界的路径数](https://github.com/hollischuang/algorithm/tree/master/leetcode/576-OutOfBoundaryPaths) - -[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) - -英文官方题解: - -[https://leetcode.com/articles/out-of-boundary-paths/](https://leetcode.com/articles/out-of-boundary-paths/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月07日 - -[374. 猜数字大小](https://github.com/hollischuang/algorithm/tree/master/leetcode/374-GuessNumberHigherOrLower) - -[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) - -英文官方题解: - -[https://leetcode.com/articles/guess-number-higher-or-lower/](https://leetcode.com/articles/guess-number-higher-or-lower/) - -知识点:二分查找 - -难度:简单 - ---- - -2019年03月08日 - -[375. 猜数字大小 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/375-GuessNumberHigherOrLowerII) - -[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~](https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月09日 - -[967. 连续差相同的数字](https://github.com/hollischuang/algorithm/tree/master/leetcode/967-NumbersWithSameConsecutiveDifferences) - -[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) - -英文官方题解: - -[https://leetcode.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/numbers-with-same-consecutive-differences/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月10日 - -[673. 最长递增子序列的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/673-NumberOfLongestIncreasingSubsequence) - -[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) - -英文官方题解: - -[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月11日 - -[131. 分割回文串](https://github.com/hollischuang/algorithm/tree/master/leetcode/131-PalindromePartitioning) - -[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.](https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.) - -知识点:回溯算法 - -难度:中等 - ---- - -2019年03月12日 - -[132. 分割回文串II](https://github.com/hollischuang/algorithm/tree/master/leetcode/132-PalindromePartitioningII) - -[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.](https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月13日 - -[5. 最长回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/005-LongestPalindromicSubstring) - -[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) - -英文官方题解: - -[https://leetcode.com/articles/longest-palindromic-substring/](https://leetcode.com/articles/longest-palindromic-substring/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月14日 - -[523. 连续的子数组和](https://github.com/hollischuang/algorithm/tree/master/leetcode/523-ContinuousSubarraySum) - -[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space](https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月15日 - -[837. 新21点](https://github.com/hollischuang/algorithm/tree/master/leetcode/837-New21Game) - -[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) - -英文官方题解: - -[https://leetcode.com/articles/new-21-game/](https://leetcode.com/articles/new-21-game/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月16日 - -[898. 子数组按位或操作](https://github.com/hollischuang/algorithm/tree/master/leetcode/898-BitwiseORsOfSubarrays) - -[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) - -英文官方题解: - -[https://leetcode.com/articles/bitwise-ors-of-subarrays/](https://leetcode.com/articles/bitwise-ors-of-subarrays/) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月17日 - -[91. 解码方法](https://github.com/hollischuang/algorithm/tree/master/leetcode/091-DecodeWays) - -[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) - -无官方题解,网友高票Java解法1: - -[https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference](https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference) - -无官方题解,网友高票Java解法2: - -[https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation](https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation) - -知识点:动态规划 - -难度:中等 - ---- - -2019年03月18日 - -[312. 戳气球](https://github.com/hollischuang/algorithm/tree/master/leetcode/312-BurstBalloons) - -[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations](https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月19日 - -[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) - -[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)](https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月20日 - -[975. 奇偶跳](https://github.com/hollischuang/algorithm/tree/master/leetcode/975-OddEvenJump) - -[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) - -官方题解: - -[https://leetcode-cn.com/articles/odd-even-jump/](https://leetcode-cn.com/articles/odd-even-jump/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月21日 - -[115. 不同的子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/115-DistinctSubsequences) - -[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java](https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月22日 - -[940. 不同的子序列 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/940-DistinctSubsequencesII) - -[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) - -英文官方题解: - -[https://leetcode.com/articles/distinct-subsequences-ii/](https://leetcode.com/articles/distinct-subsequences-ii/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月23日 - -[691. 贴纸拼词](https://github.com/hollischuang/algorithm/tree/master/leetcode/691-StickersToSpellWord) - -[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) - -英文官方题解: - -[https://leetcode.com/articles/stickers-to-spell-word/](https://leetcode.com/articles/stickers-to-spell-word/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月24日 - -[982. 按位与为零的三元组](https://github.com/hollischuang/algorithm/tree/master/leetcode/982-TriplesWithBitwiseANDEqualToZero) - -[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月25日 - -[546. 移除盒子](https://github.com/hollischuang/algorithm/tree/master/leetcode/546-RemoveBoxes) - -[https://leetcode-cn.com/problems/remove-boxes/](https://leetcode-cn.com/problems/remove-boxes/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions](https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月26日 - -[85. 最大矩形](https://github.com/hollischuang/algorithm/tree/master/leetcode/085-MaximalRectangle) - -[https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution](https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月27日 - -[903. DI 序列的有效排列](https://github.com/hollischuang/algorithm/tree/master/leetcode/903-ValidPermutationsForDISequence) - -[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) - -英文官方题解: - -[https://leetcode.com/articles/valid-permutations-for-di-sequence/](https://leetcode.com/articles/valid-permutations-for-di-sequence/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月28日 - -[629. K个逆序对数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) - -英文官方题解: - -[https://leetcode.com/articles/k-inverse-pairs-array/](https://leetcode.com/articles/k-inverse-pairs-array/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月29日 - -[956. 最高的广告牌](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) - -英文官方题解: - -[https://leetcode.com/problems/tallest-billboard/solution/](https://leetcode.com/problems/tallest-billboard/solution/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年03月30日 - -[664. 奇怪的打印机](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) - -[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) - -英文官方题解: - -[https://leetcode.com/problems/strange-printer/solution/](https://leetcode.com/problems/strange-printer/solution/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年04月01日 - -[943. 最短超级串](https://github.com/hollischuang/algorithm/tree/master/leetcode/943-FindTheShortestSuperstring) - -[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) - -英文官方题解: - -[https://leetcode.com/articles/find-the-shortest-superstring/](https://leetcode.com/articles/find-the-shortest-superstring/) - -知识点:动态规划 - -难度:困难 - ---- - -2019年04月02日 - -[32. 最长有效括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/032-LongestValidParentheses) - -[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) - -英文官方题解: - -[https://leetcode.com/articles/longest-valid-parentheses/](https://leetcode.com/articles/longest-valid-parentheses/) - -知识点:动态规划 - -难度:困难 - ---- - - -2019年04月03日 - -[403. 青蛙过河](https://github.com/hollischuang/algorithm/tree/master/leetcode/403-FrogJump) - -[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) - -知识点:动态规划 - -难度:困难 - ---- - - -2019年04月04日 - -[321. 拼接最大数](https://github.com/hollischuang/algorithm/tree/master/leetcode/321-CreateMaximumNumber) - -[https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) - -无官方题解,网友高票Java解法: - -[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) - -知识点:动态规划 - -难度:困难 - ---- +# 算法学习 + +* 这个专栏是Hollis知识星球的朋友们练习算法的地方 +* 欢迎广大网友参与分享算法学习经验 +* 项目目前分为两部分 + * solutions 目录 + * 算法题解,格式是 md 格式文件,方便阅读 + * 包括 + * 算法平台的题解,如 Leetcode 等 + * 算法书籍的题解,如 《剑指 Offer》 + * codes 目录: + * 数据结构和算法的实现代码 + * 包括 + * 各类网络公开课的代码 + * 各类算法书籍的代码 +* 备注 + * 本项目选取的资源都来自官方公开免费资源 + * 本项目所有内容不做商业用途 + * 本项目大部分代码由贡献者自己编写,如有引用则注明出处 + +# 学习方式 + +## 1. 面试刷题 +>适合短期面试突击或日常刷题练手 + +* LeetCode:https://leetcode-cn.com/problemset/all +* 牛客网:https://www.nowcoder.com + +## 2. 基础知识 +> 适合从零开始真正学习和掌握数据结构和算法知识 + +### 网络公开课 +#### 1) 数据结构与算法基础-java版(罗召勇) +* 访问地址: + https://www.bilibili.com/video/BV1Zt411o7Rn + +#### 2) 尚硅谷Java数据结构与java算法(Java数据结构与算法) +* 访问地址 + https://www.bilibili.com/video/BV1E4411H73v + +# 笔记 + +# 一、数据结构与算法基础-java版(罗召勇) +>本课程为 DT 课堂颜群发布在 Bilibili 上的免费视频 +《数据结构与算法基础-java版(罗召勇)》 +https://www.bilibili.com/video/BV1Zt411o7Rn +* 本项目中实现代码: + codes/java_dataStructure_luozhaoyong + +# 1. 数据结构概述 + +## 概念 +* 数据结构:数据与数据之间的关系 +* 两方面讨论: + * 存储结构 + * 顺序存储:存储在连续的存储单元 + * 链式存储:不连续,每次存储都有数据和指针 + * 逻辑结构 + * 数据和数据本身之间的关系 + * 集合结构:数据同属于一个集合 + * 线性结构:元素之间一对一的关系 + * 数组 + * 栈 + * 队列 + * 单链表 + * 循环链表 + * 双链表 + * 递归 + * 排序算法 + * 树形结构:元素之间一对多的关系 + * 图形结构:元素之间多对多的关系 + +# 2. 算法概述 +* 算法定义:解决问题的思路 +* 算法的特性: + * 输入:0 到多个输入 + * 输出:至少 1 个输出 + * 有穷性:有限的步骤里算出结果 + * 确定性:一个输入对应一个输出,结果确定 + * 可行性:能够解决实际问题 +* 算法的基本要求: + * 正确性:能够得出正确的结果 + * 可读性:能够被看懂 + * 健壮性:对于各种情形算法都有效 + * 时间复杂度:消耗的时间 + * 空间复杂度:占用的内存 + +# 3. 数组的基本作用 +>顺序存储的线性结构称为数组 + +## 数组的使用 +* 下标从 0 开始,下标最大值为(数组长度-1) +* 数组创建方式: + * int[] arr = new int[3]; + * int 规定了数组中元素的类型 + * 3 规定了数组的长度 + * arr[0] = 1; // 为数组中指定位置赋值 + * int[] arr = new int[]{1, 2, 3 }; + * 创建数组的同时给数组赋值 + +# 4. 数组元素的添加 + +## 动态扩容 +>解决数组元素不可变的问题 + +* 1) 新建一个数组,长度为原数组长度+1 +* 2) 将原数组中的元素逐个赋值到新数组 +* 3) 将目标元素添加到新数组的末尾 +* 4) 用新数组替换原数组 + +# 5. 数组元素的删除 +* 1) 创建一个新数组,长度为原数组长度-1 +* 2) 将原数组中除要删除元素之外的元素,逐个赋值给新数组 +* 3) 用新数组替换原数组 + +# 6. 面向对象的数组 +* 在对象数组中创建一个数组成员变量,实际操作都在这个成员变量中进行 +* 主要操作: + * 向数组末尾添加元素 + * 删除指定位置的元素 + * 获取指定位置的元素 + * 插入一个元素到指定位置 + * 为数组中指定位置赋值 + +# 7. 查找算法之线性查找 +* 遍历每一个元素,依次与目标值对比 + +# 8. 查找算法之二分法查找 +* 适用范围:有序数组 +* 步骤: + * 1) 数组开始位置为 0,结束位置为数组长度 -1 + * 2) 通过开始位置和结束位置获取中间位置的值 + * 3) 将中间值与目标值对比 + * 中间值 > 目标值:将结束位置左移到中间位置-1,继续向左查找更小的值 + * 中间值 < 目标值:将开始位置右移到中间位置+1,继续向右查找更小的值 + * 中间值 = 目标值:中间值就是要查找的值,返回中间值下标 + * 4) 重复步骤 2 和 3,直至找出目标位置或者遍历完数组 + +# 10. 栈 + +## 数组实现栈的思路 +* 向数组末尾添加元素 +* 从数组末尾取元素 +* 依次实现下列方法: + * push + * pop + * peek + * isEmpty + +# 11. 队列 + +## 数组实现队列的思路 +* 在数组末尾加入元素 +* 在数组开头取出元素 +* 依次实现下列方法 + * add + * poll + * isEmpty + +# 12. 单链表 +* 定义节点类 Node,包含以下成员变量 + * int data:节点内容/数据 + * Node next:下一个节点,类型也是节点 +* 为节点类添加下列方法 + * append // 向链表末尾添加 + * next // 获取当前节点的下一个节点 + * getData // 获取节点的数据 + * isLast // 判断当前节点是否为最后一个节点 + +# 13. 删除单链表中的节点 +* 删除当前节点的后继节点 + * 获取后继节点的后继节点 + * 将当前节点的后继节点指向新的后继节点 + * 原有后继节点与前置和后继节点都失去了联系,达到了删除效果 + +# 14. 在单链表中插入一个节点 +* 让当前节点的后继节点指向要插入的节点 +* 要插入的节点后继节点指向原后继节点 +* 新的连接关系:当前节点-->插入节点-->原后继节点 + +# 15. 循环链表 +* 链表最后一个节点的后继节点指向链表的头节点 +* 实现下列方法 + * next 获取后继节点 + * getData 获取当前节点值 + * after 插入一个新节点 + +# 16. 循环双链表 +* 每一个节点都会记录其前置节点和后继节点 +* 三个成员变量 + * 上一个节点 + * 下一个节点 + * 当前节点数据 +* 实现下列方法 + * after 新增节点 + * next 获取后继节点 + * pre 获取前驱节点 + * getData 获取当前节点值 + +# 17. 递归和斐波那契数列 +* 递归就是在函数内部调用该函数本身 +* 斐波那契数列:1 1 2 3 ... + * 从第三项起,每一项的值都是前两项之和 + +# 18. 汉诺塔问题 +* 三根柱子 + n 个盘子 +* n 个盘子一开始都在第一根柱子上 +* 每次只能移动一个盘子 +* 用最少的步数将 n 个盘子从第一根柱子移动到第三根柱子 +* 解决思路 + * 求出只有 1 个盘子的情况 + * 求出只有 2 个盘子的情况 + * n 个盘子的情况都可以简化成 2 个盘子的情况 + +# 19. 算法的时间复杂度和空间复杂度 +* 时间复杂度:运行时占用时间 +* 空间复杂度:运行时占用内存 +* 一个算法中语句需要执行的次数,称为语句频度,记为 T(N) +* 随着执行次数增多,时间复杂度估算时可以忽略以下内容 + * 忽略常数项 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 2n+20 和 2n 两条曲线会趋向重合 + * 3n+10 和 3n 两条曲线会趋向重合 + * 在 n 较大时,常数项的影响可以忽略 + * 忽略低次项 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 2n^2 + 3n + 10 和 2n^2 两条曲线都趋向 n^2 + * n^2 + 5n + 20 和 n^2 两条曲线都趋向 n^2 + * 在 n 较大时,低次项的影响可以忽略 + * 忽略系数 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 3n^2 + 2n 和 5n^2 + 7n 两条曲线趋向重合 + * n^3 + 5n 和 6n^3 + 4n 两条曲线趋向重合 + * 在 n 较大时,稀疏的影响可以忽略 +* 大 O 表示法 + * T(n) 表示算法中基本操作语句的重复执行次数是问题规模 n 的函数 + * 如果有一个辅助函数 f(n) + * 使得 n 趋近于无穷大时,T(n) 和 f(n) 的极限值为不等于 0 的常数 + * 则称 f(n) 是 T(n) 的同数量级函数,记做 T(n) = O(f(n)) + * O(f(n)) 称为算法的渐进时间复杂度,简称时间复杂度 +* 常见的时间复杂度 + * 常数阶 O(1) + * 对数阶 O(log2n) + * 线性阶 O(n) + * 线性对数阶 O(nlog2n) + * 平方阶 O(n^2) + * 立方阶 O(n^3) + * 次方阶 O(n^k) + * 指数阶 O(2^n) + * 随着问题规模 n 的不断增大,上述时间复杂度不断增大,算法执行效率越低 +* 计算时间复杂度的方法 + * 常数 1 代替所有加法常数 + * 只保留最高阶项 + * 去掉最高阶项的系数 +* 平均时间复杂度和最坏时间复杂度 + * 通常只讨论最坏时间复杂度 + +# 20. 排序算法之冒泡排序 + +## 常见排序算法总结 +* 交换排序 + * 冒泡排序 + * 快速排序 +* 插入排序 + * 直接插入排序 + * 希尔排序 +* 选择排序 + * 简单选择排序 + * 堆排序 +* 归并排序 +* 基数排序 + +## 冒泡排序 +* 第一轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到最大的元素移动到数组末尾 +* 第二轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到本轮最大的元素移动到数组倒数第二个位置 +* 第三轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到本轮最大的元素移动到数组倒数第三个位置 +* 第 n 轮 + * 每轮都从第 1 个元素开始,比较相邻两个元素,将较大的元素后移 + * 前一轮的最大元素不再参与下一轮比较,所以每一轮参与比较的元素都比上一轮少 1 个 + * 每一轮中最大元素都会从前往后移,类似气泡冒出水面,所以称为冒泡排序 + +# 21. 排序算法之快速排序 +* 1) 从数组中找出一个基准数 +* 2) 数组定义左右两个指针分别向中间移动 +* 3) 数组左侧的值比基准值大,则移到数组右侧 +* 4) 数组右侧的值比基准值小,则移到数组左侧 +* 5) 当左右两个指针重合时,当前轮排序结束 +* 6) 指针重合的位置将数组分为两部分,分别对两部分递归调用快速排序 +* 7) 重复上述步骤,直到排序完成 + +# 22. 排序算法之插入排序 +* 将数组分为未排序和已排序两部分 +* 从数组第二个元素位置开始 +* 每次从未排序部分取出第一个数字 +* 将其按规定顺序插入已排序部分 +* 同时插入位置之后的数字依次后移 1 位 +* 重复上述步骤,已排序部分逐渐向右扩大,直到所有数字都正确排序为止 + +# 23. 排序算法之希尔排序 +* 插入排序的问题 + * 如果待插入的数字,比已排序部分所有数字都小 + * 那么已排序部分就要进行大量的元素后移操作,效率较低 +* 希尔排序 + * 取某个数字作为步长,按步长对数组进行插入排序 + * 排序完成后,步长按规律递减 + * 用新步长进行下一轮插入排序 + * 重复上述步骤,直到步长变成 1,进行最后一轮普通的插入排序为止 + +# 24. 排序算法之选择排序 +* 将数组看作有序和无序两部分 +* 从第一个元素开始,在无序部分找出最小的元素 +* 将最小的元素与无序部分的第一个元素交换位置 +* 重复上述步骤,直到数组完全有序为止 + +# 25. 排序算法之归并排序 +* 归并方法 + * 原数组已经被分为两部分,每部分都各自有序 + * 创建一个与原数组等长的临时数组 + * 依次从两部分中取出元素进行对比,按照顺序放入临时数组 + * 所有元素都放入新数组后,整个数组已经排好序 + * 将临时数组重新赋值给原有数组 +* 递归部分 + * 将原数组折半划分为两部分 + * 依次对两部分递归调用递归算法 + * 直到数组不可再分 + +# 26. 排序算法之基数排序 +* 思路 + * 第一轮按所有元素的个位数字排序 + * 第二轮按所有元素的十位数字排序 + * 以此类推 + * 当按照数组中元素的最大位数排序之后,最终得到 1 个有序的数组 +* 举例 + * 例如数组 [5, 1, 72, 36, 101] + * 为便于理解,想象元素空缺的位数上都是 0 + * 把数组写成如下形式 + * 排序前的原始数组 [005, 001, 072, 036, 101] + * 第一轮按个位排序 [001, 101, 072, 005, 036] + * 第二轮按十位排序 [001, 101, 005, 036, 072] + * 第三轮按百位排序 [001, 005, 036, 072, 101] + * 每轮排序后,位数相同的数字,相对顺序不会改变 + * 如第一次按照个位排序后,两个个位数字 1 和 5 + * 1 在接下来的几轮排序过程中,总是位于 5 的前面 + * 所有排序结束后,就得到了按照数字整体大小排列的数组 + +# 27. 基数排序之队列实现 +* 26 节的基数排序中,我们使用二维数组来表示桶 +* 桶中的元素有先进先出的特点,可以将二维数组换成队列 + +# 28. 树结构概述 +## 数据结构的特点: +* 线性结构: + * 顺序存储:添加删除耗时 + * 链式存储:查找耗时 +* 树结构: + * 解决了顺序存储和链式存储的上述问题 + +## 树的基本概念: +* 根结点:起始节点 +* 双亲节点(即父节点):有子节点的节点 +* 子节点:向上溯源,有双亲节点的节点 +* 路径:从根结点到指定节点所要经过的所有节点 +* 节点的度:子节点的个数 +* 节点的权:节点的数值 +* 叶子节点:没有子节点的节点,即度为 0 的树 +* 子树:树中包含的树 +* 层:把根结点看作第一层,根结点的子树为第二层,树有多少代,就有多少层 +* 树的高度:树的最大层数 +* 森林:多棵树组成一个森林 + +# 29. 二叉树概述: +* 概念: + * 任何一个节点,子节点的数量不超过 2,这棵树就是二叉树 + * 二叉树的左右节点顺序不同,视为不同的两棵树 + +* 满二叉树: + * 所有叶子节点都在最后一层 + * 且总的节点个数为 2^n-1 + * n 是树的高度 + +* 完全二叉树: + * 所有叶子节点都在最后一层或倒数第二层 + * 且最后一层的叶子节点在左边连续 + * 倒数第二层的叶子节点在右边连续 + * 数节点确认: + * 从左向右从上到下数节点 + * 数到最后一个节点 + * 完全连续没有间断就是完全二叉树 + +# 30. 创建二叉树 +## 二叉树的存储结构 +* 链式存储 + * 创建二叉树 + * 添加节点 + * 查找节点 + * 树的遍历 + * 删除节点 +* 顺序存储 + +## 二叉树的形态 +* 空树:无节点 +* 左斜树:所有节点都在左侧 +* 右斜树:所有节点都在右侧 + +# 31. 树的遍历 +* 三种遍历形式: + * 根据根结点的位置确定顺序 + * 前序:根结点-->左节点-->右节点 + * 中序:左结点-->根节点-->右节点 + * 后序:左结点-->右节点-->根节点 + +# 32. 二叉树中节点的查找(链式存储) +* 与二叉树遍历方法类似 + +# 33. 删除二叉树的子树(链式存储) +* 递归删除 + +# 34. 顺序存储的二叉树介绍 +* 顺序存储二叉树通常只考虑完全二叉树 + +## 性质 +* 第 n 个元素的左子节点是 2*n+1 +* 第 n 个元素的右子节点是 2*n+2 +* 第 n 个节点的父节点是 (n-1)/2 + +# 35. 顺序二叉树的遍历 +* 与链式存储二叉树的遍历相似,以前序遍历为例 + * 双亲节点 index + * 左子节点 2*index+1 + * 右子节点 2*index+2 +* 需要传入一个参数,确定遍历的起点 + +# 36. 常用排序算法之堆排序 +## 堆的概念 +* 大顶堆:每个节点都大于等于其左右孩子节点的值 +* 小顶堆:每个节点都小于等于其左右孩子节点的值 + +## 堆排序的应用 +* 升序使用大顶堆 +* 降序使用小顶堆 + +## 如何将顺序存储的二叉树转成大顶堆 +>从左至右,从上至下调整 + +* 0) 从最后一个非叶子节点开始调整 +* 1) 将这个非叶子节点与其子节点对比,检查是否最大 +* 2) 如果不是,交换二者位置 +* 3) 交换位置后原有的堆结构发生了变化 +* 4) 对调整后的最大非叶子节点重复步骤 1~3 +* 5) 循环遍历一个顺序存储的二叉树,对每一个非叶子节点执行步骤 1~4 + +## 堆排序的步骤(以大顶堆为例) +* 1) 将大小为 n 的顺序存储二叉树调整成一个大顶堆 +* 2) 将数组第 0 个数和第 n 个数交换 +* 3) 将数组大小递减 1,对递减后的数组重复执行 1~2 + +# 37. 线索二叉树 +* 顺序存储二叉树遍历到某个节点时,无法知道它的前驱节点和后续节点 +* 利用二叉树节点的空链域存储前驱或者后继节点的指针,这些指针就称为线索 +* 当某个节点没有左子节点时,将左指针指向它的前一个节点 +* 当某个节点没有右子节点时,将右指针指向它的后一个节点 +* 线索化二叉树时,可以通过标记的方式,说明指向的是前驱/后继节点还是孩子节点 + +# 38. 线索二叉树的代码实现 +* 1) 创建两个变量,分别用于标识左子节点和右子节点的类型 + * 默认 0 表示指针指向孩子节点 + * 1 表示当前指针指向前驱或后继节点 +* 2) 创建一个变量,临时存储前驱节点 +* 3) 对左子节点和右子节点递归调用线索化方法 +* 4) 对当前节点的进行线索化: + * 如果左子节点为空,将空指针指向前驱节点,左指针类型标识改为 1 + * 如果前驱节点的右子节点为空,将空指针指向当前节点,前驱节点的右指针类型标识改为 1 +* 5) 线索化结束后,让前驱节点指向当前节点,供下一轮使用 + +# 39. 线索化二叉树的遍历 + +## 思路: +* 中序遍历,向左前溯,找到第一个被线索化的节点 +* 不断输出后继节点的值,直到没有后继节点 +* 找到最后一个后继节点的右子节点,继续下一轮查找和输出 + +## 步骤 +* 1) 不断前溯左子节点,直至找到第一个被线索化的节点 +* 2) 从这个节点开始,不断查找后继节点并输出节点的值 +* 3) 找到最后一个后继节点的右子节点,重复步骤 1 和 2,直到节点为空 + +# 40. 赫夫曼树概述 +* 赫夫曼编码是数据压缩的重要方法 +* 叶结点的带权路径: + * 从根结点出发,到达某个叶结点时,经过的节点数量,乘以叶结点的权值 + * 如叶子节点 A 的权值为 9,从根结点到达 A 节点,经过了 2 个节点,A 的权值就是 2*9=18 +* 树的带权路径长度: + * WPL:weighted path length + * 树中所有叶子节点带权路径之和 +* 最优二叉树: + * WPL 最小时,称为最优二叉树,也叫赫夫曼树 + * 权值越大的节点离根结点越近,这样才能保证带权路径尽可能小 + +# 41. 赫夫曼树的流程分析 +* 1) 将数组中的每个元素都转化为二叉树,初始状态每棵二叉树只有一个节点 +* 2) 将数组中的二叉树按根结点的权值正序排列 +* 3) 从数组中取出根结点权值最小的两棵二叉树 + * 将这两棵二叉树的根结点视为孩子节点,为它们创建一个父节点 + * 父节点的权值是两个孩子节点的权值之和 + * 新的父节点和原先的两棵二叉树组成了一棵新的二叉树 +* 4) 将新创建的二叉树插入数组 +* 5) 重复步骤 2~4,每次取出两个元素,放回一个元素,直到数组剩下一个元素为止 + * 剩下的这个元素,就是整棵赫夫曼树的根结点 + +# 42. 代码实现赫夫曼树 +* 1) 将数组中的所有元素转化为二叉树 +* 2) 取出数组中根结点权值最小的两棵二叉树 +* 3) 用两棵二叉树的根结点作为孩子节点,创建一棵新的二叉树 + * 二叉树根结点的权值是两棵孩子节点权值之和 +* 4) 移除数组中取出的两棵二叉树 +* 5) 将新创建的二叉树放入数组 +* 6) 当数组中的元素大于 1 时,循环执行步骤 2~5 + +# 43. 赫夫曼编码原理分析 +* 通信和压缩领域应用非常广泛 +``` +can you can a can as a can canner can a can +``` +* 通信领域中信息的处理 + * 定长编码: + * ```99 97 110 32 121 ... 32 97 32 99 97 110 46``` + * 单词-->ASIIC 编码-->每个数字都转成 8 位的字节 + * ```01100011 01100001 ... 00101110``` + * 缺点:固定长度,传输内容太多 + * 非定长编码: + * 计数:```r:1 s:1 .. n:8 :11 a:11``` + * ```0=a, 1= , 10=n, 11=c ... 10=r``` + * 将字符串中每个字符出现的次数表示出来 + * 编码: + * 出现次数多的字符用较少位的字节来表示 + * 出现次数少的字符用较多位的字节来表示 + * 前缀编码:字符的编码都不能是其他字符编码的前缀 + * 前缀编码才能进行解码 + * 赫夫曼编码: + * 将字符串中每个字符出现的次数表示出来 + *```r:1 s:1 .. a:11``` + * 将字符作为节点的数据,出现次数作为节点的权值 + * 出现次数多的字符靠近根结点,编码长度较短 + * 将左连接定义为 0,右连接定义为 1,树的路径就有了编码 + * 赫夫曼树的路径是唯一的,因此每个字符的编码都是唯一的 + +# 44~45. 数据压缩之创建赫夫曼树 + +## 创建节点类 Node: +* 属性: + * int weight 权值,某个字符出现了多少次 + * Node left 左子节点 + * Node right 右子节点 + * Byte data 当前节点对应的字符 + * 采用包装类 Byte 可以定义空值 +* 构造方法: + *public Node(Byte data, int weight) + +## 赫夫曼编码方法: +* 共经历了 6 次形态转换 +* 1) 字符串 --> 未压缩的 byte 数组 +* 2) 未压缩的 byte 数组 --> 二叉树节点列表 +* 3) 二叉树节点列表 --> 赫夫曼树 +* 4) 赫夫曼树 --> 赫夫曼编码表 +* 5) 字符数组 + 赫夫曼编码表 --> 二进制字符串 +* 6) 二进制字符串 --> 压缩后的 byte 数组 + +### 1. 字符串 --> byte 数组 +* 调用 String 对象的 getBytes() 方法 + +### 2. byte 数组 --> 二叉树节点列表 +* 创建一个 HashMap,键类型是 Byte,值类型是 Integer +* 遍历 byte 数组,通过 HashMap 存储并统计单个 byte 出现的次数 +* 从 HashMap 中取出对应的键值对 +* 以 Byte 值作为节点数据,出现次数作为节点权值 +* 每个键值对都转为一个二叉树根节点 Node +* 将所有二叉树节点存入列表备用 + +### 3. 二叉树节点列表 --> 赫夫曼树 +* 1) 遍历 Node 列表 +* 2) 按 Node 权值 weight 降序对列表排序 +* 3) 取出列表中权值最小的两个元素,即列表倒数两个元素 +* 4) 将两个元素作为孩子节点创建一个父节点,父节点的权值是两个孩子节点权值之和 +* 6) 同时将父节点的左右指针指向两个孩子节点 +* 7) 从原列表中删除第 3 步中取出的两个权值最小的元素 +* 8) 将新建的节点存入列表 +* 9) 当列表中元素数量大于 1 时,重复步骤 2~6 +* 10) 最终列表中只剩下一个元素,这个元素就是赫夫曼树的根结点 + +### 4. 赫夫曼树 --> 赫夫曼编码表 +* 1) 新建一个 HashMap 对象记录赫夫曼编码表 + * 键:赫夫曼树上某个节点的键,即字符 + * 值:赫夫曼树根节点到达当前字符的路径 + * 到达左子树的路径用 0 表示,到达右子树的路径用 1 表示 + * 路径变成一个由 0 和 1 组成的二进制字符串 + * 这样每个节点得到的二进制字符串都是唯一的 +* 2) 遍历赫夫曼树,将赫夫曼树上节点的相关信息转录到赫夫曼编码表 + +### 5. 字符数组 + 赫夫曼编码表 --> 二进制字符串 +* 1) 遍历原字符数组 +* 2) 对照赫夫曼编码表,获取每个字符对应的赫夫曼编码 +* 3) 将获取到的编码拼接到单个字符串 +* 4) 最终字符数组转成了一个遵循赫夫曼编码表的二进制字符串 + +### 6. 二进制字符串 --> 压缩后的 byte 数组 +* 1) 以 8 为步长遍历二进制字符串 + * 8 位二进制字符串 --> 十进制数字 --> byte 字符 + * 将新的 byte 字符存入新的字符数组中 +* 2) 最终得到一个按赫夫曼编码表压缩后的字符数组 + +# 46. 使用赫夫曼编码进行解码 +* 共进行了 2 次形态变化 +* 1) 字符数组 --> 二进制字符串 + * 1.1) 遍历字符数组 + * 1.2) 将每个字符都转为 8 位的二进制字符串 + * 如果正整数不够 8 位,数字前用 0 填充 + * 1.3) 将所有字符的二进制字符串拼接成一个完整的二进制字符串 +* 2) 二进制字符串 + 赫夫曼编码表 --> 原字符数组 + * 2.1) 将原赫夫曼编码表的键和值互换 + * 即原先键是 Byte,值是 String + * 互换后键是 String,值是 Byte + * 2.2) 遍历二进制字符串,以各种可能的组合在赫夫曼编码表中查找原 byte + * 2.3) 将 byte 存入列表后转成数组 + +# 47 使用赫夫曼编码压缩文件 +* 1) 文件来源路径 --> 创建输入流 + * new FileInputStream(文件来源路径) +* 2) 创建和输入流指向文件大小一致的 byte 数组 + * byte[] b = new byte[FileInputStream 对象.available()] + * available() 在操作前得知数据流大小 +* 3) 读取文件,关闭输入流 +* 4) 调用赫夫曼编码方法对 byte 数组编码 +* 5) 文件输出路径 --> 创建输出流 + * new FileOutputStream(文件输出路径) + * new ObjectOutputStream(FileOutputStream 对象) +* 6) 将压缩后的 byte 数组写入文件 +* 7) 将赫夫曼编码表写入文件 +* 8) 关闭输出流 + +# 48. 文件的解压 +* 1) 创建一个输入流对象,读取压缩文件 + * new FileInputStream(压缩文件路径) + * new ObjectInputStream(FileInputStream 对象) +* 2) 读取压缩文件中的 byte 数组 + * byte[] b = (byte[]) ObjectInputStream 对象.readObject() +* 3) 读取压缩文件中的赫夫曼编码 + * Map codes = (Map) ObjectInputStream 对象.readObject() +* 4) 关闭输入流 +* 5) 通过赫夫曼编码将读取出来的 byte 数组解码为原 byte 数组 +* 6) 创建一个输出流对象 + * new FileOutputStream(输出文件路径) +* 7) 将解码后的 byte 数组写入文件 + * FileOutputStream 对象.write(byte 数组) +* 8) 关闭输出流 + +# 49. 二叉排序树 + +## 线性结构 +* 顺序存储,不排序 + * 查找困难 +* 顺序存储,排序 + * 二分查找效率高 + * 删除插入困难 +* 链式存储 + * 无论是否排序,查找都困难 + +## 树形结构 +* 二叉排序树,BST + * 概念 + * 也叫二叉查找树,二叉搜索树 + * 对于排序树中的任何一个非叶子节点 + * 左子节点比当前节点小 + * 右子节点比当前节点大 + * 查找和插入删除性能都较高 + +# 50. 创建二叉排序树 & 添加节点 +* 待添加的节点 + * 1) 如果当前节点为空 --> 赋给当前节点 + * 2) 如果值比当前节点小 + * 左子节点为空 --> 赋给左子节点 + * 左子节点非空 --> 递归调用左子节点的添加方法 + * 3) 如果值比当前节点大 + * 右子节点为空 --> 赋给右子节点 + * 右子节点非空 --> 递归调用右子节点的添加方法 +* 二叉排序树的中序遍历正好是从小到大排列 + +# 51. 二叉排序树中查找节点 +* 要查找的值 == 当前节点的值 --> 返回当前节点 +* 要查找的值 < 当前节点的值 --> 递归调用左子节点的查找方法 +* 要查找的值 > 当前节点的值 --> 递归调用右子节点的查找方法 + +# 52. 删除叶子节点 +* 目标节点没有孩子节点 +* 查找目标节点 +* 查找目标节点的父节点 +* 将目标节点与父节点断开连接 + +# 53. 删除只有一棵子树的节点 +* 查找目标节点 +* 查找目标节点的父节点 +* 将目标节点的子树与父节点建立连接 + +# 54. 删除有两棵子树的节点 +* 查找目标节点 +* 查找目标节点的最小子树 +* 删除目标节点的最小子树,并返回最小子树的值 +* 用最小子树的值替换目标节点的值 + +# 55. 平衡二叉树概述 +* 二叉排序树的问题 + * 如果将连续递增或递减的数组转为二叉排序树 + * 二叉排序树的节点都在同一边,查询效率与链表差不多 +* 平衡二叉树 + * 首先平衡二叉树是一棵二叉排序树 + * 左子树和右子树高度差的绝对值不超过 1 + * 左子树和右子树也是平衡二叉树 + +# 56. 构建二叉平衡树之单旋转 +* 根据左右节点高度差的绝对值,判断当前节点是否为平衡二叉树 +* 左左:(左子树高度 - 右子树高度) > 1 + * 顺时针右旋 + * 1) node --> newNode + * 2) node.right --> newNode.right + * 3) node.left.right --> newNode.left + * 4) node.left.value --> node.value + * 5) node.left.left --> node.left + * 6) newNode --> node.right +* 右右:(右子树高度 - 左子树高度) > 1 + * 顺时针左旋 + * 1) node --> newNode + * 2) node.left --> newNode.left + * 3) node.right.left --> newNode.right + * 4) node.right.value --> node.value + * 5) node.right.right --> node.right + * 6) newNode --> node + +# 57. 构建平衡二叉树之双旋转 +* node.left.left 高度 < node.left.right 高度 + * 1) left 左旋转 + * 2) node 右旋转 +* node.right.right 高度 < node.right.left 高度 + * 1) right 右旋转 + * 2) node 左旋转 + +# 58. 多路查找树-计算机数据的存储原理 +* 应用于内存,小数据量的树结构 + * 二叉树 + * 线索二叉树 + * 赫夫曼树 + * 二叉排序树 + * AVL 树 +* 应用于磁盘存储,数据量大的树结构 + * 多路查找树 + * 2-3 树和 2-3-4 树 + * B 树和 B+ 树 + +## 数据存储方式 +* 内存 + * 优点: + * 电信号保存信息,不存在机器操作 + * 访问速度快 + * 缺点: + * 造价高 + * 断电后数据丢失 + * 一般作为 CPU 告诉缓存 +* 磁盘: + * 优点 + * 造价低,容量大 + * 断电数据不丢失 + * 缺点: + * 存储介质特性和机械运动耗费时间,磁盘速度慢 + * 磁盘的预读 + * 为了减少 I/O 操作,磁盘通常不是按需读取 + * 每次都会预读,顺序向后读取一定长度的数据放入内存 + * 计算机科学中的局部性原理:一个数据被用到时,其附近的数据通常也会被用到 + * 预读的长度一般为页(page)的整数倍 + * 页 + * 页是计算机管理存储的逻辑块 + * 硬件及操作系统将主存和磁盘存储区分割为连续的大小相等的块 + * 每个存储块为一页 + * 页的大小一般为 4k + * 主存和磁盘以页为单位交换数据 + * B 树存储 + * 利用磁盘预读原理,将一个节点的大小设为一个页 + * 单个节点进行横向扩展 + * 每个节点只需一次 I/O 就可以完全载入 + * 二叉树与 B 树对比 + * 二叉树 + * 树高为 5 的二叉树 + * 节点数=2^5-1 = 31 个 + * B 树 + * 树高为 2 + * 第一层 1 个节点,横向扩展为 3 个节点 + * 第二层 4 个节点,每个节点横向扩展为 7 个节点 + * 节点树=1×3 + 4×7 = 31 + * 同样的节点树,B 树只需要两层即可 + * 如果将树的度,即子节点的个数,设为 1024 + * 树高 2:1024^2 = 1,048,576 ≈ 100 万 + * 树高 3:1024^3 = 1,073,741,824 ≈ 1 亿 + * 树高 4:1024^4 = 1,099,511,627,776 ≈ 1000 亿 + * 600 亿 < 1000 亿,至多 4 次 I/O 即可查询到 + +# 59. 2-3 树的插入原理 +* B 树中所有的叶节点都在同一层 +* 2-3 树是 B 树的一种特例 + * 有两个子节点的节点叫做二节点 + * 有三个子节点的节点叫做三节点 + * 二节点要么有两个子节点,要么没有子节点 + * 三节点要么有三个子节点,要么没有子节点 + * 2-3 树有二节点和三节点 2 种情况 + * 2-3-4 树有二节点、三节点和四节点 3 种情况 +* 添加新节点 + * 如果叶节点无法在同一层 + * 先向上一层拆解 + * 如果现有层都满了,则增加一层 + +# 60. B 树和 B+ 树原理 + +## 概念 +* 2-3 树、2-3-4 树、2-3-4-5 树,等等,统称为 B 树 +* B 树中最大节点的数字,称为 B 树的阶 +* 2-3 树是 3 阶 B 树,2-3-4 树是 4 阶 B 树 + +## B+ 树 +* 在 B 树之上的改变 + * 非叶节点只存储索引信息,不存储数据 + * 叶子节点最右边的指针指向下一个相邻的叶节点 + * 所有叶节点组成一个有序链表 +* 设计原理 + * 更多的索引 --> 更快的查询 + +# 61. 哈希表概述 +* 线性查找 + * 逐个对比,数据量大时效率低 +* 二分查找: + * 效率更高 + * 要求数组有序 +* 存储位置 <--> 关键字 + * 通过散列函数建立对应关系 + +# 62. 散列函数的设计 +* 设计原则 + * 计算简单 + * 分布均匀 +## 常用方法 +* 直接定址法 + * 直接把关键字作为存储地址 + * 可能有空间分布不均匀的问题 + * 如果数字过大,甚至会超出编程语言的有效整数范围 +* 数字分析法 + * 通过特定规律,将数字转换成更方便存储的格式作为关键字 + * 需要事先知道数字的格式 + * 如手机号码只存后四位 +* 平方取中法 + * 将数字平方后取结果中间的数字作为关键字 + * 如 13*13 = 169,取中间数字 6 +* 取余法 + * 对数字取余数作为关键字 + * 按预计压缩范围来确定模数 +* 随机数法 + * 随机数函数产生数字作为关键字 + * 一般不用,数字随机,不便归类 + +# 63. 散列冲突的解决方案 + +## 开放地址法 +* 遇到冲突时,从当前地址后面查找合适的位置 +* 三种方式 + * 线性探测法 + * 在紧邻的位置放冲突的元素 + * 举例 + * x 位置已有元素,向后查找 x+1 + * x+1 位置有元素,再向后找 x+2 + * 问题:元素容易聚集在相邻的内存地址 + * 二次探测法 + * 第一次探测紧邻的位置 + * 第二次探测地址数字的平方 + * 举例: + * x 位置被占用,向后查找 x+1 + * x+1 位置被占用,再向后找 (x+1)^2 + * 拓宽了探测步长,元素不容易聚集在一起 + * 再哈希法 + * 多个散列函数 + * 通常 3 个散列函数可以解决大部分的冲突 + * 如果仍然有冲突,可以再使用探测法 + +## 链地址法 +* 将冲突的元素在同个地址上存储为链表形式 + * 节点内容:元素本身 + * 节点指针:下一个元素的地址 +* 优点:存储地址就是散列表计算结果,更为直观 +* 实际应用中更多采用链地址法 + +# 64. 图结构 +* 点和线构成 +* 顶点 Vertex + * 可以存储数据 +* 边 edge + * 连接顶点,表示点之间的关系 +* 邻接顶点 + * 两个顶点通过一条边就可以连接 +* 路径 + * 从某一个顶点出发,经过的所有顶点 +* 无向图 + * 边没有方向 +* 有向图 + * 边有方向 +* 带权图 + * 边加上有意义的值 + * 如 A 城市到 B 城市的距离 + * A --> B 是一个有向带权图 + +# 65. 图结构代码实现 +## 图的存储方式 +* 链表 + * 如果数据是对象,指针很难定义 +* 数组 + * 用列表存储顶点 + * 用邻接表存储顶点之间的关系 + * 类似链表的实现 + * 节点内容代表顶点 + * 指针指向下一个顶点 + * 类似矩阵的实现 + * 将顶点放到行列式中,任意两个顶点都能在矩阵中找到交叉点 + * 用数字表示两个顶点之间的关系 + * 如 0 表示不通,1 表示连通 + +# 66. 图的遍历原理 + +## 深度优先 +* 顺着路径一直查找,直到路径不通,再返回从第一个分叉的顶点处继续查找 +* 栈实现 + * 1) A 入栈,A 标记为已访问 + * 2) 按顺序查找连接 + * A --> B,连通,B 入栈,B 标记为已访问 + * B --> C,连通,C 入栈,C 标记为已访问 + * C --> D,不通,查找下一个 + * C --> E,不通,E 之后没有其他顶点 + * C 是栈顶元素,出栈 + * B --> D,连通,D 标记为已访问,D 入栈 + * D --> E,不通,E 之后没有其他顶点 + * D 是栈顶元素,出栈 + * B --> E,连通,E 入栈,E 标记为已访问 + * E 之后没有其他元素 + * E 是栈顶元素,出栈 + * B 是栈顶元素,检查 B 有无其他可能的连接 + * B 没有其他连接,出栈 + * A 是栈顶元素,检查 A 有无其他可能的连接 + * A 没有其他连接,出栈 + +## 广度优先 +* 把一个顶点所有的连接都找出来,再继续下一个顶点 +* 队列实现 + * 1) A 入队 + * 2) 查找 A 的所有连接,按顺序入队 + * A --> B,连通,B 入队 + * A --> C,连通,C 入队 + * A 无其他连接,A 出队 + * 3) A 出队后,B 是队首元素,从 B 开始查找 + * 4) 重复步骤 2~3,依次查找 B、C、D、E 所有顶点的所有连接 + +# 67. 图的遍历代码实现 +* 1) 从第 0 个顶点开始查找 + * 将第 0 个顶点标记为已访问 + * 将第 0 个顶点压入栈中 +* 2) 遍历顶点数组,按序检查邻近两个顶点之间的连通关系 + * 如果邻近顶点连通 + * 将目标顶点压入栈中,标记为已访问 + * 出发顶点和目标顶点同时后移 1 位 + * 如 A --> B 连通 + * 将出发顶点从 A 顺延到 B,检查 B --> C 是否连通 + * 如果邻近两个顶点不通,出发顶点不变,将目标顶点的指针后移一位 + * 如 C --> D 不通,将目标顶点 D 后移一位,检查 C --> E 是否连通 +* 3) 如果单条路径检查完毕,则弹出栈顶元素 +* 4) 如果栈此时非空,将出发顶点指针指向新的栈顶元素 +* 5) 重复执行步骤 2~4,直到栈为空 \ No newline at end of file diff --git a/codes/java_dataStructure_luozhaoyong/1.bmp b/codes/java_dataStructure_luozhaoyong/1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..eb3cd8501e0b66a8bfa21c97726dc402719035a1 GIT binary patch literal 625878 zcmeI&!Eq`_5C-6VM`z#=9DxrUeRmo}`Ur50@;D%PU+p|E41tgXDs1k43 zo#~nRr2T8*@!Riz|MAmweEb?ezr@d9Kc?xQ`1vvYd^|k;`F8&F;_d0+L4W`O0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;& zCNOPx^JY36_U+g=Z@%D`zxi*}_6Xc4@PZ-mf?K}vk3x3>-(27YL*NCs{LTM}ZI8f> z0xuW>FSz9!|0r}P@I-;_?l7Gm`+1Yo)R8#cKX!{tHG6KR>9C(`P1V0D)Tzz9&msMJ zx1HjHylFF6@eG0O?!V55-L{Ghjd>pnjwKu)F=G#qXm4X}hg}WnXX9Y4C&ushb6-OZ zsYZ1^P85YVb3EnQD--omr!^j*?%Z-MNrM1^`voE(rqeZCr82}S!6IblP2}M|8vFSz zi=t0O-?BoLipG#{b!s>sONel&7|b=CjlN;JVc?ZGim5Y^vTQD(Pg-lsMt7*r@5#Mk zYgKkQKCJx8maBpW0Rj&Z$a|+sxx6;(>b^8ZAJyAu`=9Nw41o&LEE2I$G1$vywTi@y z!RmP>_lCfXnpvvG_F1Aml*-N}Gn~!-RqC-@9v0>$0Rndl3|DBrtW-H$Jo{8k4HeD~ zi5sozpBejxS#M zm#6Z``|tOn+A!l#vldqKzGutTS%Uz9)dJVA%_v(JWAPv2DO8PzLC6xZ$LF#Av^dPdpmJiN@#t8=d} zc&J>f?c40_Ten;VH3$&6Qy?$=xPJ3d`H*3f2YdL``^q?#oiA0Wh4oTz)11aGLm={J z-pBX%;x_8|=<`;!YQ%k1b{l%edg3l|cZd{?e~*u$P6kw-%CF?D&b><$J!#9ecMSpr z?i3jAmsV7}zru=1A2MXf-iOpwgaCoBFK~Zq-CyCel;qxL$(xtJ=L+Oo*LsJ$VlnF~ ze1**U;5B^kbSr+9h7cg|RDrJ$0w27F51#I+zdpqY5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs O0RjXF5FkKcDey0%p|(2! literal 0 HcmV?d00001 diff --git a/codes/java_dataStructure_luozhaoyong/2.zip b/codes/java_dataStructure_luozhaoyong/2.zip new file mode 100644 index 0000000000000000000000000000000000000000..555cd8d3ec4818d2a07464c96e03a0ae993864a2 GIT binary patch literal 79515 zcmeI$e@xV69KiAC4vt@@#vf!70mjOPjes(xKfuAF`a|W9QXCDqJk*Q??heH!a!NCo zj=A}xxz&!Xe=JEGTS+TDu{JQ8fNX)Utus`144aYs- z&-e3vKCkEVJjZPNUD)cK!dh0?_UD4pn7EhvtwJ=^3d_^cZL>(dACUf z^G1p)?iMf$_n70%ApZ{?0|mn7826tQF+~+!`64cA$3z8PDlt85_+Dqy-8r>k6vcA8Y$`n|@3(ut zboJ*Z2MVlXzUjkUQad4DCGy5$<$ z&oA?Mz%B_=$WZ0PbW`% zXVSru(nkYLy5SzNmFdswxeqdJW#*)mx=Yn21H;btCbbZ1p8b7#oC8~f*b|AW3wP^%WeaRAO;?-kQsq16Rd%BjUnzDh z)muh&*@DZu*TnK=)2~doacIen%62vO&Csl;lScQRS1(fVLiCxzVOMjL>Nle@qvnaq zZraLJK3}s(muhaI3(;#<-_*y9(XtgiiQc-=@Zn;lF>dOeIPU*0bJoi`k&&AmRENd} zqaXE#Qx)h&x@?>rjnc+jimYxdUlb^1HTk8U&8$*kdc=r~)xObrIoq;%bI7z^C8BQ{35 zhLa8&$7#ywed<^-JJ&cfJAJ*kY!0b+sBtcK0qqbAPy2 zELof~Dun(@3vIo&eMWgh&6&GJ)U^UBZ{~W${0?j3x`c&pf@SzT7y=rw-5Ji2AyZ zV2pzZ8EvnF@7;BWCBA*g_}k{*&5$=EfB*srAbg6p5SdTkTo(?$@fbUa-41t+dzLVt?xV>Ve9OQNmg*5~^$Lj$-?Ica8H! z5%1pQta5FtsdhBf7OYVJoi9Z8wm9|g3iXq!lFc)cRol00%qraOu6l1(WZ@gON+|zdW;W>x;_gRH#s1bfAn4w8yIcD6k$XIqxIQ@f> zF+Gvc#9AX`D$X2BS2cw1+jTu=&h>5)rJf8u__JF?Po%DL3)`gPHmHw!)@H)T-C|C- zu1JC(BX3p{Gy}Ix(#ukn>y+Ua)`UNsu?LI^gr9VV?nY{Lg+H6o`y;fGg!N`f_yy1W TW0vM~+rvTT=VwD@XE*!}2ylgp literal 0 HcmV?d00001 diff --git a/codes/java_dataStructure_luozhaoyong/3.bmp b/codes/java_dataStructure_luozhaoyong/3.bmp new file mode 100644 index 0000000..8d17a2a --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/3.bmp @@ -0,0 +1 @@ +aanaannaannaannnnnnannnnannnanaannnnaaannnnnnnannnnnnnnanaannnnnnnnnnnnnnnnnananannnaananannnaananannnaananannnaananannnaananannnaananannnaananannnaaannnnnnnaaannannnnnnnnnnannnaanannnnnnnannnaaaaannnnnnnaaannananannnnnnnnnnnnnnnnnnaannananannnnaananannnanaannnnnnnnnaaaanannannnnnnnaaannnanannnaananannaananannnaaananannnnnnannnaaaaannnannnnaaananannnnnnnnnaaaannnananananannaananannnaaananannnnnnnnnnnnnnnnnnaannananannnnaananannnanaannnnnnnnnaaaannananaannnnaaannanaannanaaanaaaanaanannnaaaaannananaaananannnnaaaananannnnaanannnnannnaaannnnaaaannanananannnnannnaananannaananannnaaananannnaaaaananannnnnnnaaannnnaaannaananannnnanananannaananannnaaaananannnnaaaananannnnaanannnnannnaaannnnaaaanannanaaannaananananaanannanaaannanannanaaannanannanaaannaananannnnaananannnaaaananannnaaanannanaaaannannnnaananannaananannnaaannananaanannanannnaananannaaanannanaanananannaananannnaaanannanaaannaananannnnaananannnaaaananannnaaanannanaaannanannanaaaanannanannnaaaaanannanaaannananaannnaaaaaananannnnaananannnaaanannnaaaaannanaannnanannnaananannaananannnaaanannanaaaaananannnnaaaananannnnaaaananananananannaananannnaaananaannnaaaaaananannnnaananannnaaanannnaaaaanannanaaannanannannnnnnnnnnnnnnnnnnnaaaanannannnnannnaaaaanannanaaannaananannnnaaaananannnnaananannnaaannnnaaaannnnnnnannaananannnaananannaananannnaaanannanaaaaananannnnaaaananannnnaaaananananananannaananannnaaaananannnnaaaananannnnaananannnaaannnnaaaanannanaaannanannanaaannanannanaannnannnaaanannanaaannanannanaaannaananannnnaananannnaaanannnaaaaannannnnnnnaananannaananannnaaanannanaaannaananannnnaaaananannnnaaaananananananannaananannnaaanannanaaannaananannnnaananannnaaanannnaaaaanannanaaannaananannnnaaanannnaaannannanaaaanannanaaannananaannnaaaaaananannnnaananannnaaaaananaannaaaananannnnaananannnaaaaaananannnnaaaananananaannannnnaaaananannnnaaaananananananannnaaaaaananannnnaaananaannnaaaaaananannnnaananannnaaaaananaannaaanannanaaannanannanaaannannananaannananaannaaanannanaaannaananannnnaaaananannnnaanannnnannaaanannanaanaanaaannanannanaaannnannnnannaaannnnaaannannnnaaannnannnnannnaaaananannnnaaaanananananannnnannaaannnnaaannaananannnnaaaananannnnaanannnnannaaanannanaananannnnnnnnnnnnnaaannanannannnnnnnaanaannannnnnnnaannnannnnnnnnnnnnnaaannanannannnnnnnnnnnnnnnnaaannaananannnnaananannnanaaannannnnnnnaanaananannnnnnnnnaanananannnannannnnnnnanaannnnnnnnnnaaaannnannnnaaaananannnnaaaananananananannnannannnnnnnanaanannannnnnnnnnnnnnnnnaaannaananannnnaananannnanaaannannnnnnnaanaanannanaaannanannanaaannaananannnnaaanannanaaannanannanaaannaananannnnaaannanaannannanaannaananannnnaaaananannnnaaaananannnnaaaananannnnaaaananannnnaaaananannnnaa \ No newline at end of file diff --git a/codes/java_dataStructure_luozhaoyong/README.md b/codes/java_dataStructure_luozhaoyong/README.md new file mode 100644 index 0000000..3711a75 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/README.md @@ -0,0 +1,937 @@ +>本课程为 DT 课堂颜群发布在 Bilibili 上的免费视频 +《数据结构与算法基础-java版(罗召勇)》 +https://www.bilibili.com/video/BV1Zt411o7Rn + +# 1. 数据结构概述 + +## 概念 +* 数据结构:数据与数据之间的关系 +* 两方面讨论: + * 存储结构 + * 顺序存储:存储在连续的存储单元 + * 链式存储:不连续,每次存储都有数据和指针 + * 逻辑结构 + * 数据和数据本身之间的关系 + * 集合结构:数据同属于一个集合 + * 线性结构:元素之间一对一的关系 + * 数组 + * 栈 + * 队列 + * 单链表 + * 循环链表 + * 双链表 + * 递归 + * 排序算法 + * 树形结构:元素之间一对多的关系 + * 图形结构:元素之间多对多的关系 + +# 2. 算法概述 +* 算法定义:解决问题的思路 +* 算法的特性: + * 输入:0 到多个输入 + * 输出:至少 1 个输出 + * 有穷性:有限的步骤里算出结果 + * 确定性:一个输入对应一个输出,结果确定 + * 可行性:能够解决实际问题 +* 算法的基本要求: + * 正确性:能够得出正确的结果 + * 可读性:能够被看懂 + * 健壮性:对于各种情形算法都有效 + * 时间复杂度:消耗的时间 + * 空间复杂度:占用的内存 + +# 3. 数组的基本作用 +>顺序存储的线性结构称为数组 + +## 数组的使用 +* 下标从 0 开始,下标最大值为(数组长度-1) +* 数组创建方式: + * int[] arr = new int[3]; + * int 规定了数组中元素的类型 + * 3 规定了数组的长度 + * arr[0] = 1; // 为数组中指定位置赋值 + * int[] arr = new int[]{1, 2, 3 }; + * 创建数组的同时给数组赋值 + +# 4. 数组元素的添加 + +## 动态扩容 +>解决数组元素不可变的问题 + +* 1) 新建一个数组,长度为原数组长度+1 +* 2) 将原数组中的元素逐个赋值到新数组 +* 3) 将目标元素添加到新数组的末尾 +* 4) 用新数组替换原数组 + +# 5. 数组元素的删除 +* 1) 创建一个新数组,长度为原数组长度-1 +* 2) 将原数组中除要删除元素之外的元素,逐个赋值给新数组 +* 3) 用新数组替换原数组 + +# 6. 面向对象的数组 +* 在对象数组中创建一个数组成员变量,实际操作都在这个成员变量中进行 +* 主要操作: + * 向数组末尾添加元素 + * 删除指定位置的元素 + * 获取指定位置的元素 + * 插入一个元素到指定位置 + * 为数组中指定位置赋值 + +# 7. 查找算法之线性查找 +* 遍历每一个元素,依次与目标值对比 + +# 8. 查找算法之二分法查找 +* 适用范围:有序数组 +* 步骤: + * 1) 数组开始位置为 0,结束位置为数组长度 -1 + * 2) 通过开始位置和结束位置获取中间位置的值 + * 3) 将中间值与目标值对比 + * 中间值 > 目标值:将结束位置左移到中间位置-1,继续向左查找更小的值 + * 中间值 < 目标值:将开始位置右移到中间位置+1,继续向右查找更小的值 + * 中间值 = 目标值:中间值就是要查找的值,返回中间值下标 + * 4) 重复步骤 2 和 3,直至找出目标位置或者遍历完数组 + +# 10. 栈 + +## 数组实现栈的思路 +* 向数组末尾添加元素 +* 从数组末尾取元素 +* 依次实现下列方法: + * push + * pop + * peek + * isEmpty + +# 11. 队列 + +## 数组实现队列的思路 +* 在数组末尾加入元素 +* 在数组开头取出元素 +* 依次实现下列方法 + * add + * poll + * isEmpty + +# 12. 单链表 +* 定义节点类 Node,包含以下成员变量 + * int data:节点内容/数据 + * Node next:下一个节点,类型也是节点 +* 为节点类添加下列方法 + * append // 向链表末尾添加 + * next // 获取当前节点的下一个节点 + * getData // 获取节点的数据 + * isLast // 判断当前节点是否为最后一个节点 + +# 13. 删除单链表中的节点 +* 删除当前节点的后继节点 + * 获取后继节点的后继节点 + * 将当前节点的后继节点指向新的后继节点 + * 原有后继节点与前置和后继节点都失去了联系,达到了删除效果 + +# 14. 在单链表中插入一个节点 +* 让当前节点的后继节点指向要插入的节点 +* 要插入的节点后继节点指向原后继节点 +* 新的连接关系:当前节点-->插入节点-->原后继节点 + +# 15. 循环链表 +* 链表最后一个节点的后继节点指向链表的头节点 +* 实现下列方法 + * next 获取后继节点 + * getData 获取当前节点值 + * after 插入一个新节点 + +# 16. 循环双链表 +* 每一个节点都会记录其前置节点和后继节点 +* 三个成员变量 + * 上一个节点 + * 下一个节点 + * 当前节点数据 +* 实现下列方法 + * after 新增节点 + * next 获取后继节点 + * pre 获取前驱节点 + * getData 获取当前节点值 + +# 17. 递归和斐波那契数列 +* 递归就是在函数内部调用该函数本身 +* 斐波那契数列:1 1 2 3 ... + * 从第三项起,每一项的值都是前两项之和 + +# 18. 汉诺塔问题 +* 三根柱子 + n 个盘子 +* n 个盘子一开始都在第一根柱子上 +* 每次只能移动一个盘子 +* 用最少的步数将 n 个盘子从第一根柱子移动到第三根柱子 +* 解决思路 + * 求出只有 1 个盘子的情况 + * 求出只有 2 个盘子的情况 + * n 个盘子的情况都可以简化成 2 个盘子的情况 + +# 19. 算法的时间复杂度和空间复杂度 +* 时间复杂度:运行时占用时间 +* 空间复杂度:运行时占用内存 +* 一个算法中语句需要执行的次数,称为语句频度,记为 T(N) +* 随着执行次数增多,时间复杂度估算时可以忽略以下内容 + * 忽略常数项 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 2n+20 和 2n 两条曲线会趋向重合 + * 3n+10 和 3n 两条曲线会趋向重合 + * 在 n 较大时,常数项的影响可以忽略 + * 忽略低次项 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 2n^2 + 3n + 10 和 2n^2 两条曲线都趋向 n^2 + * n^2 + 5n + 20 和 n^2 两条曲线都趋向 n^2 + * 在 n 较大时,低次项的影响可以忽略 + * 忽略系数 + * 在坐标轴上画出曲线 + * 随着 n 的增大 + * 3n^2 + 2n 和 5n^2 + 7n 两条曲线趋向重合 + * n^3 + 5n 和 6n^3 + 4n 两条曲线趋向重合 + * 在 n 较大时,稀疏的影响可以忽略 +* 大 O 表示法 + * T(n) 表示算法中基本操作语句的重复执行次数是问题规模 n 的函数 + * 如果有一个辅助函数 f(n) + * 使得 n 趋近于无穷大时,T(n) 和 f(n) 的极限值为不等于 0 的常数 + * 则称 f(n) 是 T(n) 的同数量级函数,记做 T(n) = O(f(n)) + * O(f(n)) 称为算法的渐进时间复杂度,简称时间复杂度 +* 常见的时间复杂度 + * 常数阶 O(1) + * 对数阶 O(log2n) + * 线性阶 O(n) + * 线性对数阶 O(nlog2n) + * 平方阶 O(n^2) + * 立方阶 O(n^3) + * 次方阶 O(n^k) + * 指数阶 O(2^n) + * 随着问题规模 n 的不断增大,上述时间复杂度不断增大,算法执行效率越低 +* 计算时间复杂度的方法 + * 常数 1 代替所有加法常数 + * 只保留最高阶项 + * 去掉最高阶项的系数 +* 平均时间复杂度和最坏时间复杂度 + * 通常只讨论最坏时间复杂度 + +# 20. 排序算法之冒泡排序 + +## 常见排序算法总结 +* 交换排序 + * 冒泡排序 + * 快速排序 +* 插入排序 + * 直接插入排序 + * 希尔排序 +* 选择排序 + * 简单选择排序 + * 堆排序 +* 归并排序 +* 基数排序 + +## 冒泡排序 +* 第一轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到最大的元素移动到数组末尾 +* 第二轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到本轮最大的元素移动到数组倒数第二个位置 +* 第三轮 + * 从第 1 个元素开始,比较相邻两个元素,将较大的元素后移,直到本轮最大的元素移动到数组倒数第三个位置 +* 第 n 轮 + * 每轮都从第 1 个元素开始,比较相邻两个元素,将较大的元素后移 + * 前一轮的最大元素不再参与下一轮比较,所以每一轮参与比较的元素都比上一轮少 1 个 + * 每一轮中最大元素都会从前往后移,类似气泡冒出水面,所以称为冒泡排序 + +# 21. 排序算法之快速排序 +* 1) 从数组中找出一个基准数 +* 2) 数组定义左右两个指针分别向中间移动 +* 3) 数组左侧的值比基准值大,则移到数组右侧 +* 4) 数组右侧的值比基准值小,则移到数组左侧 +* 5) 当左右两个指针重合时,当前轮排序结束 +* 6) 指针重合的位置将数组分为两部分,分别对两部分递归调用快速排序 +* 7) 重复上述步骤,直到排序完成 + +# 22. 排序算法之插入排序 +* 将数组分为未排序和已排序两部分 +* 从数组第二个元素位置开始 +* 每次从未排序部分取出第一个数字 +* 将其按规定顺序插入已排序部分 +* 同时插入位置之后的数字依次后移 1 位 +* 重复上述步骤,已排序部分逐渐向右扩大,直到所有数字都正确排序为止 + +# 23. 排序算法之希尔排序 +* 插入排序的问题 + * 如果待插入的数字,比已排序部分所有数字都小 + * 那么已排序部分就要进行大量的元素后移操作,效率较低 +* 希尔排序 + * 取某个数字作为步长,按步长对数组进行插入排序 + * 排序完成后,步长按规律递减 + * 用新步长进行下一轮插入排序 + * 重复上述步骤,直到步长变成 1,进行最后一轮普通的插入排序为止 + +# 24. 排序算法之选择排序 +* 将数组看作有序和无序两部分 +* 从第一个元素开始,在无序部分找出最小的元素 +* 将最小的元素与无序部分的第一个元素交换位置 +* 重复上述步骤,直到数组完全有序为止 + +# 25. 排序算法之归并排序 +* 归并方法 + * 原数组已经被分为两部分,每部分都各自有序 + * 创建一个与原数组等长的临时数组 + * 依次从两部分中取出元素进行对比,按照顺序放入临时数组 + * 所有元素都放入新数组后,整个数组已经排好序 + * 将临时数组重新赋值给原有数组 +* 递归部分 + * 将原数组折半划分为两部分 + * 依次对两部分递归调用递归算法 + * 直到数组不可再分 + +# 26. 排序算法之基数排序 +* 思路 + * 第一轮按所有元素的个位数字排序 + * 第二轮按所有元素的十位数字排序 + * 以此类推 + * 当按照数组中元素的最大位数排序之后,最终得到 1 个有序的数组 +* 举例 + * 例如数组 [5, 1, 72, 36, 101] + * 为便于理解,想象元素空缺的位数上都是 0 + * 把数组写成如下形式 + * 排序前的原始数组 [005, 001, 072, 036, 101] + * 第一轮按个位排序 [001, 101, 072, 005, 036] + * 第二轮按十位排序 [001, 101, 005, 036, 072] + * 第三轮按百位排序 [001, 005, 036, 072, 101] + * 每轮排序后,位数相同的数字,相对顺序不会改变 + * 如第一次按照个位排序后,两个个位数字 1 和 5 + * 1 在接下来的几轮排序过程中,总是位于 5 的前面 + * 所有排序结束后,就得到了按照数字整体大小排列的数组 + +# 27. 基数排序之队列实现 +* 26 节的基数排序中,我们使用二维数组来表示桶 +* 桶中的元素有先进先出的特点,可以将二维数组换成队列 + +# 28. 树结构概述 +## 数据结构的特点: +* 线性结构: + * 顺序存储:添加删除耗时 + * 链式存储:查找耗时 +* 树结构: + * 解决了顺序存储和链式存储的上述问题 + +## 树的基本概念: +* 根结点:起始节点 +* 双亲节点(即父节点):有子节点的节点 +* 子节点:向上溯源,有双亲节点的节点 +* 路径:从根结点到指定节点所要经过的所有节点 +* 节点的度:子节点的个数 +* 节点的权:节点的数值 +* 叶子节点:没有子节点的节点,即度为 0 的树 +* 子树:树中包含的树 +* 层:把根结点看作第一层,根结点的子树为第二层,树有多少代,就有多少层 +* 树的高度:树的最大层数 +* 森林:多棵树组成一个森林 + +# 29. 二叉树概述: +* 概念: + * 任何一个节点,子节点的数量不超过 2,这棵树就是二叉树 + * 二叉树的左右节点顺序不同,视为不同的两棵树 + +* 满二叉树: + * 所有叶子节点都在最后一层 + * 且总的节点个数为 2^n-1 + * n 是树的高度 + +* 完全二叉树: + * 所有叶子节点都在最后一层或倒数第二层 + * 且最后一层的叶子节点在左边连续 + * 倒数第二层的叶子节点在右边连续 + * 数节点确认: + * 从左向右从上到下数节点 + * 数到最后一个节点 + * 完全连续没有间断就是完全二叉树 + +# 30. 创建二叉树 +## 二叉树的存储结构 +* 链式存储 + * 创建二叉树 + * 添加节点 + * 查找节点 + * 树的遍历 + * 删除节点 +* 顺序存储 + +## 二叉树的形态 +* 空树:无节点 +* 左斜树:所有节点都在左侧 +* 右斜树:所有节点都在右侧 + +# 31. 树的遍历 +* 三种遍历形式: + * 根据根结点的位置确定顺序 + * 前序:根结点-->左节点-->右节点 + * 中序:左结点-->根节点-->右节点 + * 后序:左结点-->右节点-->根节点 + +# 32. 二叉树中节点的查找(链式存储) +* 与二叉树遍历方法类似 + +# 33. 删除二叉树的子树(链式存储) +* 递归删除 + +# 34. 顺序存储的二叉树介绍 +* 顺序存储二叉树通常只考虑完全二叉树 + +## 性质 +* 第 n 个元素的左子节点是 2*n+1 +* 第 n 个元素的右子节点是 2*n+2 +* 第 n 个节点的父节点是 (n-1)/2 + +# 35. 顺序二叉树的遍历 +* 与链式存储二叉树的遍历相似,以前序遍历为例 + * 双亲节点 index + * 左子节点 2*index+1 + * 右子节点 2*index+2 +* 需要传入一个参数,确定遍历的起点 + +# 36. 常用排序算法之堆排序 +## 堆的概念 +* 大顶堆:每个节点都大于等于其左右孩子节点的值 +* 小顶堆:每个节点都小于等于其左右孩子节点的值 + +## 堆排序的应用 +* 升序使用大顶堆 +* 降序使用小顶堆 + +## 如何将顺序存储的二叉树转成大顶堆 +>从左至右,从上至下调整 + +* 0) 从最后一个非叶子节点开始调整 +* 1) 将这个非叶子节点与其子节点对比,检查是否最大 +* 2) 如果不是,交换二者位置 +* 3) 交换位置后原有的堆结构发生了变化 +* 4) 对调整后的最大非叶子节点重复步骤 1~3 +* 5) 循环遍历一个顺序存储的二叉树,对每一个非叶子节点执行步骤 1~4 + +## 堆排序的步骤(以大顶堆为例) +* 1) 将大小为 n 的顺序存储二叉树调整成一个大顶堆 +* 2) 将数组第 0 个数和第 n 个数交换 +* 3) 将数组大小递减 1,对递减后的数组重复执行 1~2 + +# 37. 线索二叉树 +* 顺序存储二叉树遍历到某个节点时,无法知道它的前驱节点和后续节点 +* 利用二叉树节点的空链域存储前驱或者后继节点的指针,这些指针就称为线索 +* 当某个节点没有左子节点时,将左指针指向它的前一个节点 +* 当某个节点没有右子节点时,将右指针指向它的后一个节点 +* 线索化二叉树时,可以通过标记的方式,说明指向的是前驱/后继节点还是孩子节点 + +# 38. 线索二叉树的代码实现 +* 1) 创建两个变量,分别用于标识左子节点和右子节点的类型 + * 默认 0 表示指针指向孩子节点 + * 1 表示当前指针指向前驱或后继节点 +* 2) 创建一个变量,临时存储前驱节点 +* 3) 对左子节点和右子节点递归调用线索化方法 +* 4) 对当前节点的进行线索化: + * 如果左子节点为空,将空指针指向前驱节点,左指针类型标识改为 1 + * 如果前驱节点的右子节点为空,将空指针指向当前节点,前驱节点的右指针类型标识改为 1 +* 5) 线索化结束后,让前驱节点指向当前节点,供下一轮使用 + +# 39. 线索化二叉树的遍历 + +## 思路: +* 中序遍历,向左前溯,找到第一个被线索化的节点 +* 不断输出后继节点的值,直到没有后继节点 +* 找到最后一个后继节点的右子节点,继续下一轮查找和输出 + +## 步骤 +* 1) 不断前溯左子节点,直至找到第一个被线索化的节点 +* 2) 从这个节点开始,不断查找后继节点并输出节点的值 +* 3) 找到最后一个后继节点的右子节点,重复步骤 1 和 2,直到节点为空 + +# 40. 赫夫曼树概述 +* 赫夫曼编码是数据压缩的重要方法 +* 叶结点的带权路径: + * 从根结点出发,到达某个叶结点时,经过的节点数量,乘以叶结点的权值 + * 如叶子节点 A 的权值为 9,从根结点到达 A 节点,经过了 2 个节点,A 的权值就是 2*9=18 +* 树的带权路径长度: + * WPL:weighted path length + * 树中所有叶子节点带权路径之和 +* 最优二叉树: + * WPL 最小时,称为最优二叉树,也叫赫夫曼树 + * 权值越大的节点离根结点越近,这样才能保证带权路径尽可能小 + +# 41. 赫夫曼树的流程分析 +* 1) 将数组中的每个元素都转化为二叉树,初始状态每棵二叉树只有一个节点 +* 2) 将数组中的二叉树按根结点的权值正序排列 +* 3) 从数组中取出根结点权值最小的两棵二叉树 + * 将这两棵二叉树的根结点视为孩子节点,为它们创建一个父节点 + * 父节点的权值是两个孩子节点的权值之和 + * 新的父节点和原先的两棵二叉树组成了一棵新的二叉树 +* 4) 将新创建的二叉树插入数组 +* 5) 重复步骤 2~4,每次取出两个元素,放回一个元素,直到数组剩下一个元素为止 + * 剩下的这个元素,就是整棵赫夫曼树的根结点 + +# 42. 代码实现赫夫曼树 +* 1) 将数组中的所有元素转化为二叉树 +* 2) 取出数组中根结点权值最小的两棵二叉树 +* 3) 用两棵二叉树的根结点作为孩子节点,创建一棵新的二叉树 + * 二叉树根结点的权值是两棵孩子节点权值之和 +* 4) 移除数组中取出的两棵二叉树 +* 5) 将新创建的二叉树放入数组 +* 6) 当数组中的元素大于 1 时,循环执行步骤 2~5 + +# 43. 赫夫曼编码原理分析 +* 通信和压缩领域应用非常广泛 +``` +can you can a can as a can canner can a can +``` +* 通信领域中信息的处理 + * 定长编码: + * ```99 97 110 32 121 ... 32 97 32 99 97 110 46``` + * 单词-->ASIIC 编码-->每个数字都转成 8 位的字节 + * ```01100011 01100001 ... 00101110``` + * 缺点:固定长度,传输内容太多 + * 非定长编码: + * 计数:```r:1 s:1 .. n:8 :11 a:11``` + * ```0=a, 1= , 10=n, 11=c ... 10=r``` + * 将字符串中每个字符出现的次数表示出来 + * 编码: + * 出现次数多的字符用较少位的字节来表示 + * 出现次数少的字符用较多位的字节来表示 + * 前缀编码:字符的编码都不能是其他字符编码的前缀 + * 前缀编码才能进行解码 + * 赫夫曼编码: + * 将字符串中每个字符出现的次数表示出来 + *```r:1 s:1 .. a:11``` + * 将字符作为节点的数据,出现次数作为节点的权值 + * 出现次数多的字符靠近根结点,编码长度较短 + * 将左连接定义为 0,右连接定义为 1,树的路径就有了编码 + * 赫夫曼树的路径是唯一的,因此每个字符的编码都是唯一的 + +# 44~45. 数据压缩之创建赫夫曼树 + +## 创建节点类 Node: +* 属性: + * int weight 权值,某个字符出现了多少次 + * Node left 左子节点 + * Node right 右子节点 + * Byte data 当前节点对应的字符 + * 采用包装类 Byte 可以定义空值 +* 构造方法: + *public Node(Byte data, int weight) + +## 赫夫曼编码方法: +* 共经历了 6 次形态转换 +* 1) 字符串 --> 未压缩的 byte 数组 +* 2) 未压缩的 byte 数组 --> 二叉树节点列表 +* 3) 二叉树节点列表 --> 赫夫曼树 +* 4) 赫夫曼树 --> 赫夫曼编码表 +* 5) 字符数组 + 赫夫曼编码表 --> 二进制字符串 +* 6) 二进制字符串 --> 压缩后的 byte 数组 + +### 1. 字符串 --> byte 数组 +* 调用 String 对象的 getBytes() 方法 + +### 2. byte 数组 --> 二叉树节点列表 +* 创建一个 HashMap,键类型是 Byte,值类型是 Integer +* 遍历 byte 数组,通过 HashMap 存储并统计单个 byte 出现的次数 +* 从 HashMap 中取出对应的键值对 +* 以 Byte 值作为节点数据,出现次数作为节点权值 +* 每个键值对都转为一个二叉树根节点 Node +* 将所有二叉树节点存入列表备用 + +### 3. 二叉树节点列表 --> 赫夫曼树 +* 1) 遍历 Node 列表 +* 2) 按 Node 权值 weight 降序对列表排序 +* 3) 取出列表中权值最小的两个元素,即列表倒数两个元素 +* 4) 将两个元素作为孩子节点创建一个父节点,父节点的权值是两个孩子节点权值之和 +* 6) 同时将父节点的左右指针指向两个孩子节点 +* 7) 从原列表中删除第 3 步中取出的两个权值最小的元素 +* 8) 将新建的节点存入列表 +* 9) 当列表中元素数量大于 1 时,重复步骤 2~6 +* 10) 最终列表中只剩下一个元素,这个元素就是赫夫曼树的根结点 + +### 4. 赫夫曼树 --> 赫夫曼编码表 +* 1) 新建一个 HashMap 对象记录赫夫曼编码表 + * 键:赫夫曼树上某个节点的键,即字符 + * 值:赫夫曼树根节点到达当前字符的路径 + * 到达左子树的路径用 0 表示,到达右子树的路径用 1 表示 + * 路径变成一个由 0 和 1 组成的二进制字符串 + * 这样每个节点得到的二进制字符串都是唯一的 +* 2) 遍历赫夫曼树,将赫夫曼树上节点的相关信息转录到赫夫曼编码表 + +### 5. 字符数组 + 赫夫曼编码表 --> 二进制字符串 +* 1) 遍历原字符数组 +* 2) 对照赫夫曼编码表,获取每个字符对应的赫夫曼编码 +* 3) 将获取到的编码拼接到单个字符串 +* 4) 最终字符数组转成了一个遵循赫夫曼编码表的二进制字符串 + +### 6. 二进制字符串 --> 压缩后的 byte 数组 +* 1) 以 8 为步长遍历二进制字符串 + * 8 位二进制字符串 --> 十进制数字 --> byte 字符 + * 将新的 byte 字符存入新的字符数组中 +* 2) 最终得到一个按赫夫曼编码表压缩后的字符数组 + +# 46. 使用赫夫曼编码进行解码 +* 共进行了 2 次形态变化 +* 1) 字符数组 --> 二进制字符串 + * 1.1) 遍历字符数组 + * 1.2) 将每个字符都转为 8 位的二进制字符串 + * 如果正整数不够 8 位,数字前用 0 填充 + * 1.3) 将所有字符的二进制字符串拼接成一个完整的二进制字符串 +* 2) 二进制字符串 + 赫夫曼编码表 --> 原字符数组 + * 2.1) 将原赫夫曼编码表的键和值互换 + * 即原先键是 Byte,值是 String + * 互换后键是 String,值是 Byte + * 2.2) 遍历二进制字符串,以各种可能的组合在赫夫曼编码表中查找原 byte + * 2.3) 将 byte 存入列表后转成数组 + +# 47 使用赫夫曼编码压缩文件 +* 1) 文件来源路径 --> 创建输入流 + * new FileInputStream(文件来源路径) +* 2) 创建和输入流指向文件大小一致的 byte 数组 + * byte[] b = new byte[FileInputStream 对象.available()] + * available() 在操作前得知数据流大小 +* 3) 读取文件,关闭输入流 +* 4) 调用赫夫曼编码方法对 byte 数组编码 +* 5) 文件输出路径 --> 创建输出流 + * new FileOutputStream(文件输出路径) + * new ObjectOutputStream(FileOutputStream 对象) +* 6) 将压缩后的 byte 数组写入文件 +* 7) 将赫夫曼编码表写入文件 +* 8) 关闭输出流 + +# 48. 文件的解压 +* 1) 创建一个输入流对象,读取压缩文件 + * new FileInputStream(压缩文件路径) + * new ObjectInputStream(FileInputStream 对象) +* 2) 读取压缩文件中的 byte 数组 + * byte[] b = (byte[]) ObjectInputStream 对象.readObject() +* 3) 读取压缩文件中的赫夫曼编码 + * Map codes = (Map) ObjectInputStream 对象.readObject() +* 4) 关闭输入流 +* 5) 通过赫夫曼编码将读取出来的 byte 数组解码为原 byte 数组 +* 6) 创建一个输出流对象 + * new FileOutputStream(输出文件路径) +* 7) 将解码后的 byte 数组写入文件 + * FileOutputStream 对象.write(byte 数组) +* 8) 关闭输出流 + +# 49. 二叉排序树 + +## 线性结构 +* 顺序存储,不排序 + * 查找困难 +* 顺序存储,排序 + * 二分查找效率高 + * 删除插入困难 +* 链式存储 + * 无论是否排序,查找都困难 + +## 树形结构 +* 二叉排序树,BST + * 概念 + * 也叫二叉查找树,二叉搜索树 + * 对于排序树中的任何一个非叶子节点 + * 左子节点比当前节点小 + * 右子节点比当前节点大 + * 查找和插入删除性能都较高 + +# 50. 创建二叉排序树 & 添加节点 +* 待添加的节点 + * 1) 如果当前节点为空 --> 赋给当前节点 + * 2) 如果值比当前节点小 + * 左子节点为空 --> 赋给左子节点 + * 左子节点非空 --> 递归调用左子节点的添加方法 + * 3) 如果值比当前节点大 + * 右子节点为空 --> 赋给右子节点 + * 右子节点非空 --> 递归调用右子节点的添加方法 +* 二叉排序树的中序遍历正好是从小到大排列 + +# 51. 二叉排序树中查找节点 +* 要查找的值 == 当前节点的值 --> 返回当前节点 +* 要查找的值 < 当前节点的值 --> 递归调用左子节点的查找方法 +* 要查找的值 > 当前节点的值 --> 递归调用右子节点的查找方法 + +# 52. 删除叶子节点 +* 目标节点没有孩子节点 +* 查找目标节点 +* 查找目标节点的父节点 +* 将目标节点与父节点断开连接 + +# 53. 删除只有一棵子树的节点 +* 查找目标节点 +* 查找目标节点的父节点 +* 将目标节点的子树与父节点建立连接 + +# 54. 删除有两棵子树的节点 +* 查找目标节点 +* 查找目标节点的最小子树 +* 删除目标节点的最小子树,并返回最小子树的值 +* 用最小子树的值替换目标节点的值 + +# 55. 平衡二叉树概述 +* 二叉排序树的问题 + * 如果将连续递增或递减的数组转为二叉排序树 + * 二叉排序树的节点都在同一边,查询效率与链表差不多 +* 平衡二叉树 + * 首先平衡二叉树是一棵二叉排序树 + * 左子树和右子树高度差的绝对值不超过 1 + * 左子树和右子树也是平衡二叉树 + +# 56. 构建二叉平衡树之单旋转 +* 根据左右节点高度差的绝对值,判断当前节点是否为平衡二叉树 +* 左左:(左子树高度 - 右子树高度) > 1 + * 顺时针右旋 + * 1) node --> newNode + * 2) node.right --> newNode.right + * 3) node.left.right --> newNode.left + * 4) node.left.value --> node.value + * 5) node.left.left --> node.left + * 6) newNode --> node.right +* 右右:(右子树高度 - 左子树高度) > 1 + * 顺时针左旋 + * 1) node --> newNode + * 2) node.left --> newNode.left + * 3) node.right.left --> newNode.right + * 4) node.right.value --> node.value + * 5) node.right.right --> node.right + * 6) newNode --> node + +# 57. 构建平衡二叉树之双旋转 +* node.left.left 高度 < node.left.right 高度 + * 1) left 左旋转 + * 2) node 右旋转 +* node.right.right 高度 < node.right.left 高度 + * 1) right 右旋转 + * 2) node 左旋转 + +# 58. 多路查找树-计算机数据的存储原理 +* 应用于内存,小数据量的树结构 + * 二叉树 + * 线索二叉树 + * 赫夫曼树 + * 二叉排序树 + * AVL 树 +* 应用于磁盘存储,数据量大的树结构 + * 多路查找树 + * 2-3 树和 2-3-4 树 + * B 树和 B+ 树 + +## 数据存储方式 +* 内存 + * 优点: + * 电信号保存信息,不存在机器操作 + * 访问速度快 + * 缺点: + * 造价高 + * 断电后数据丢失 + * 一般作为 CPU 告诉缓存 +* 磁盘: + * 优点 + * 造价低,容量大 + * 断电数据不丢失 + * 缺点: + * 存储介质特性和机械运动耗费时间,磁盘速度慢 + * 磁盘的预读 + * 为了减少 I/O 操作,磁盘通常不是按需读取 + * 每次都会预读,顺序向后读取一定长度的数据放入内存 + * 计算机科学中的局部性原理:一个数据被用到时,其附近的数据通常也会被用到 + * 预读的长度一般为页(page)的整数倍 + * 页 + * 页是计算机管理存储的逻辑块 + * 硬件及操作系统将主存和磁盘存储区分割为连续的大小相等的块 + * 每个存储块为一页 + * 页的大小一般为 4k + * 主存和磁盘以页为单位交换数据 + * B 树存储 + * 利用磁盘预读原理,将一个节点的大小设为一个页 + * 单个节点进行横向扩展 + * 每个节点只需一次 I/O 就可以完全载入 + * 二叉树与 B 树对比 + * 二叉树 + * 树高为 5 的二叉树 + * 节点数=2^5-1 = 31 个 + * B 树 + * 树高为 2 + * 第一层 1 个节点,横向扩展为 3 个节点 + * 第二层 4 个节点,每个节点横向扩展为 7 个节点 + * 节点树=1×3 + 4×7 = 31 + * 同样的节点树,B 树只需要两层即可 + * 如果将树的度,即子节点的个数,设为 1024 + * 树高 2:1024^2 = 1,048,576 ≈ 100 万 + * 树高 3:1024^3 = 1,073,741,824 ≈ 1 亿 + * 树高 4:1024^4 = 1,099,511,627,776 ≈ 1000 亿 + * 600 亿 < 1000 亿,至多 4 次 I/O 即可查询到 + +# 59. 2-3 树的插入原理 +* B 树中所有的叶节点都在同一层 +* 2-3 树是 B 树的一种特例 + * 有两个子节点的节点叫做二节点 + * 有三个子节点的节点叫做三节点 + * 二节点要么有两个子节点,要么没有子节点 + * 三节点要么有三个子节点,要么没有子节点 + * 2-3 树有二节点和三节点 2 种情况 + * 2-3-4 树有二节点、三节点和四节点 3 种情况 +* 添加新节点 + * 如果叶节点无法在同一层 + * 先向上一层拆解 + * 如果现有层都满了,则增加一层 + +# 60. B 树和 B+ 树原理 + +## 概念 +* 2-3 树、2-3-4 树、2-3-4-5 树,等等,统称为 B 树 +* B 树中最大节点的数字,称为 B 树的阶 +* 2-3 树是 3 阶 B 树,2-3-4 树是 4 阶 B 树 + +## B+ 树 +* 在 B 树之上的改变 + * 非叶节点只存储索引信息,不存储数据 + * 叶子节点最右边的指针指向下一个相邻的叶节点 + * 所有叶节点组成一个有序链表 +* 设计原理 + * 更多的索引 --> 更快的查询 + +# 61. 哈希表概述 +* 线性查找 + * 逐个对比,数据量大时效率低 +* 二分查找: + * 效率更高 + * 要求数组有序 +* 存储位置 <--> 关键字 + * 通过散列函数建立对应关系 + +# 62. 散列函数的设计 +* 设计原则 + * 计算简单 + * 分布均匀 +## 常用方法 +* 直接定址法 + * 直接把关键字作为存储地址 + * 可能有空间分布不均匀的问题 + * 如果数字过大,甚至会超出编程语言的有效整数范围 +* 数字分析法 + * 通过特定规律,将数字转换成更方便存储的格式作为关键字 + * 需要事先知道数字的格式 + * 如手机号码只存后四位 +* 平方取中法 + * 将数字平方后取结果中间的数字作为关键字 + * 如 13*13 = 169,取中间数字 6 +* 取余法 + * 对数字取余数作为关键字 + * 按预计压缩范围来确定模数 +* 随机数法 + * 随机数函数产生数字作为关键字 + * 一般不用,数字随机,不便归类 + +# 63. 散列冲突的解决方案 + +## 开放地址法 +* 遇到冲突时,从当前地址后面查找合适的位置 +* 三种方式 + * 线性探测法 + * 在紧邻的位置放冲突的元素 + * 举例 + * x 位置已有元素,向后查找 x+1 + * x+1 位置有元素,再向后找 x+2 + * 问题:元素容易聚集在相邻的内存地址 + * 二次探测法 + * 第一次探测紧邻的位置 + * 第二次探测地址数字的平方 + * 举例: + * x 位置被占用,向后查找 x+1 + * x+1 位置被占用,再向后找 (x+1)^2 + * 拓宽了探测步长,元素不容易聚集在一起 + * 再哈希法 + * 多个散列函数 + * 通常 3 个散列函数可以解决大部分的冲突 + * 如果仍然有冲突,可以再使用探测法 + +## 链地址法 +* 将冲突的元素在同个地址上存储为链表形式 + * 节点内容:元素本身 + * 节点指针:下一个元素的地址 +* 优点:存储地址就是散列表计算结果,更为直观 +* 实际应用中更多采用链地址法 + +# 64. 图结构 +* 点和线构成 +* 顶点 Vertex + * 可以存储数据 +* 边 edge + * 连接顶点,表示点之间的关系 +* 邻接顶点 + * 两个顶点通过一条边就可以连接 +* 路径 + * 从某一个顶点出发,经过的所有顶点 +* 无向图 + * 边没有方向 +* 有向图 + * 边有方向 +* 带权图 + * 边加上有意义的值 + * 如 A 城市到 B 城市的距离 + * A --> B 是一个有向带权图 + +# 65. 图结构代码实现 +## 图的存储方式 +* 链表 + * 如果数据是对象,指针很难定义 +* 数组 + * 用列表存储顶点 + * 用邻接表存储顶点之间的关系 + * 类似链表的实现 + * 节点内容代表顶点 + * 指针指向下一个顶点 + * 类似矩阵的实现 + * 将顶点放到行列式中,任意两个顶点都能在矩阵中找到交叉点 + * 用数字表示两个顶点之间的关系 + * 如 0 表示不通,1 表示连通 + +# 66. 图的遍历原理 + +## 深度优先 +* 顺着路径一直查找,直到路径不通,再返回从第一个分叉的顶点处继续查找 +* 栈实现 + * 1) A 入栈,A 标记为已访问 + * 2) 按顺序查找连接 + * A --> B,连通,B 入栈,B 标记为已访问 + * B --> C,连通,C 入栈,C 标记为已访问 + * C --> D,不通,查找下一个 + * C --> E,不通,E 之后没有其他顶点 + * C 是栈顶元素,出栈 + * B --> D,连通,D 标记为已访问,D 入栈 + * D --> E,不通,E 之后没有其他顶点 + * D 是栈顶元素,出栈 + * B --> E,连通,E 入栈,E 标记为已访问 + * E 之后没有其他元素 + * E 是栈顶元素,出栈 + * B 是栈顶元素,检查 B 有无其他可能的连接 + * B 没有其他连接,出栈 + * A 是栈顶元素,检查 A 有无其他可能的连接 + * A 没有其他连接,出栈 + +## 广度优先 +* 把一个顶点所有的连接都找出来,再继续下一个顶点 +* 队列实现 + * 1) A 入队 + * 2) 查找 A 的所有连接,按顺序入队 + * A --> B,连通,B 入队 + * A --> C,连通,C 入队 + * A 无其他连接,A 出队 + * 3) A 出队后,B 是队首元素,从 B 开始查找 + * 4) 重复步骤 2~3,依次查找 B、C、D、E 所有顶点的所有连接 + +# 67. 图的遍历代码实现 +* 1) 从第 0 个顶点开始查找 + * 将第 0 个顶点标记为已访问 + * 将第 0 个顶点压入栈中 +* 2) 遍历顶点数组,按序检查邻近两个顶点之间的连通关系 + * 如果邻近顶点连通 + * 将目标顶点压入栈中,标记为已访问 + * 出发顶点和目标顶点同时后移 1 位 + * 如 A --> B 连通 + * 将出发顶点从 A 顺延到 B,检查 B --> C 是否连通 + * 如果邻近两个顶点不通,出发顶点不变,将目标顶点的指针后移一位 + * 如 C --> D 不通,将目标顶点 D 后移一位,检查 C --> E 是否连通 +* 3) 如果单条路径检查完毕,则弹出栈顶元素 +* 4) 如果栈此时非空,将出发顶点指针指向新的栈顶元素 +* 5) 重复执行步骤 2~4,直到栈为空 \ No newline at end of file diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/AddOneToHundred.java b/codes/java_dataStructure_luozhaoyong/src/demo1/AddOneToHundred.java new file mode 100644 index 0000000..e6aa662 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/AddOneToHundred.java @@ -0,0 +1,31 @@ +package demo1; + +/** + * 计算从 1 加到 100 的和 + * @author admin + */ +public class AddOneToHundred { + public static void main(String[] args) { + int total = 0; + int end = 100; + + // 使用 for 循环计算 + for (int i = 1; i <= end; i++) { + // total 记录总和 + // 每次都累加当前自然数 i 的值 + // 这条语句执行了 end 次 + total += i; + } + //打印结果 + System.out.println("普通 for 循环:" + total); + + // 将 end 变量还原为初始值 + end = 100; + // 通过等差数列求和公式计算 1 加到 100 的总和 + // 这条语句执行了 1 次 + total = (1 + end) * end / 2; + + //打印结果 + System.out.println("等差数列求和公式:" + total); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestArray.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestArray.java new file mode 100644 index 0000000..ea7a1a2 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestArray.java @@ -0,0 +1,45 @@ +package demo1; + +/** + * 数组的基本使用 + * @author admin + */ +public class TestArray { + public static void main(String[] args) { + // 创建数组 + // int 是数组内元素的类型;3 是数组的大小 + int[] arr1 = new int[3]; + + // 获取数组长度 + int length1 = arr1.length; + // 打印结果 3 + System.out.println("arr1's length:" + length1); + + // 访问数组中的元素:数组名[下标] + // 注意:下标从 0 开始,下标最大可以取到 (数组长度 - 1) + // 获取数组第 1 个元素,即下标为 0 的元素 + int element0 = arr1[0]; + // 打印结果 0 + System.out.println("element0: " + element0); + + // 为数组中的元素赋值 + arr1[0] = 99; + element0 = arr1[0]; + // 打印结果 99 + System.out.println("element0: " + element0); + + arr1[1] = 98; + arr1[2] = 97; + + // 遍历数组,从下标 0 开始,到 (数组长度 - 1) 结束 + for (int i = 0; i < length1; i++) { + // 打印第 i 个元素 + System.out.println("arr1 element " + i + ": " + arr1[i]); + } + + // 创建数组的同时为元素赋值 + int[] arr2 = new int[]{90, 80, 70, 60, 50}; + // 打印结果 5 + System.out.println("arr2's length:" + arr2.length); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestBinarySearch.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestBinarySearch.java new file mode 100644 index 0000000..6e76cab --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestBinarySearch.java @@ -0,0 +1,48 @@ +package demo1; + +/** + * 测试二分查找 + * @author admin + */ +public class TestBinarySearch { + public static void main(String[] args) { + // 目标数组 + int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; + // 目标元素 + int target = 3; + // 记录开始位置 + int begin = 0; + // 记录结束位置 + int end = arr.length - 1; + // 记录中间位置 + int mid = begin + (end - begin) / 2; + // 目标元素在数组中的下标,初始值为 -1 + int index = -1; + + // 当开始位置小于或等于结束位置时,循环继续 + // begin == end 时,即二者重合时 + // mid = begin + (end - begin)/2 == begin + // 即 begin 位置本身还没有检查,需要再进入循环一次 + while (begin <= end) { + // 如果 mid 位置刚好等于目标值 + if (arr[mid] == target) { + // 结束循环 + index = mid; + break; + } + // 如果 mid 位置元素大于目标值 + if (arr[mid] > target) { + // 将结束位置左移到 mid 位置前一个位置 + end = mid - 1; + } else { + // 如果 mid 位置元素小于目标值 + // 说明目标值在 mid 的右边 + // 将开始位置右移到 mid 后一个位置 + begin = mid + 1; + } + // 重新计算 mid 位置的值 + mid = begin + (end - begin) / 2; + } + System.out.println(index); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArray.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArray.java new file mode 100644 index 0000000..f35fb3a --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArray.java @@ -0,0 +1,57 @@ +package demo1; + +import demo1.util.MyArray; + +/** + * 测试可变数组 + * @author admin + */ +public class TestMyArray { + + public static void main(String[] args) { + // 创建一个可变数组 + MyArray ma = new MyArray(); + // 获取数组长度 + int size = ma.size(); + System.out.println(size); + // 显示可变数组中的所有元素到控制台 + ma.show(); + + // 向可变数组末尾添加一个元素 + ma.add(99); + ma.add(98); + ma.add(97); + ma.show(); + + // 测试删除元素,删除下标为 1 的元素 + ma.delete(1); + ma.show(); + + // 获取指定下标的元素 + int element = ma.get(1); + System.out.println(element); + + System.out.println("============="); + ma.add(96); + ma.add(95); + ma.add(94); + ma.show(); + + // 向指定位置插入元素 + ma.insert(3, 33); + ma.show(); + System.out.println("============="); + + // 测试替换指定位置的值 + ma.set(0, 100); + ma.show(); + + // 打印数组长度,set 方法对原数组操作,数组长度没有变化 + // 打印结果为 6 + System.out.println(ma.size()); + + // 测试下标越界 + // 会抛出越界异常 + ma.set(-1,100); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArraySearch.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArraySearch.java new file mode 100644 index 0000000..b7b2d60 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestMyArraySearch.java @@ -0,0 +1,25 @@ +package demo1; + +import demo1.util.MyArray; + +/** + * 测试查找方法 + * @author admin + */ +public class TestMyArraySearch { + public static void main(String[] args) { + MyArray ma = new MyArray(); + ma.add(1); + ma.add(2); + ma.add(3); + ma.add(4); + ma.add(5); + // 线性查找 + int index = ma.search(4); + System.out.println("index: " + index); + + // 调用二分法查找 + int index2 = ma.binarySearch(-1); + System.out.println("index2: " + index2); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray.java new file mode 100644 index 0000000..d58aebb --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray.java @@ -0,0 +1,41 @@ +package demo1; + +import java.util.Arrays; + +/** + * 数组动态扩容 + * 解决数组长度不可变的问题 + * @author admin + */ +public class TestOpArray { + public static void main(String[] args) { + // 原数组 + int[] arr = new int[]{9, 8, 7}; + + // 直接调用 java.util.Arrays 中的方法,将数组元素转为 String 格式用于打印和查看 + System.out.println(Arrays.toString(arr)); + + // 要加入数组的新元素 + int dst = 6; + + // 1. 创建一个新数组,长度是原数组长度 + 1 + int[] newArr = new int[arr.length + 1]; + // 2. 把原数组中的元素复制到新数组中 + for (int i = 0; i < arr.length; i++) { + // 将原数组中的第 i 个元素 arr[i] + // 赋值给新数组第 i 个位置 + newArr[i] = arr[i]; + } + // 打印新数组中的所有元素 + System.out.println(Arrays.toString(newArr)); + // 3. 将目标元素放入新数组的最后 + // 新数组最后一个位置的下标是 newArr.length - 1 + // 教学视频中使用了 arr.length,两者是相等的,newArr.length - 1 更容易理解 + newArr[newArr.length - 1] = dst; + // 4. 新数组替换原数组,即原数组的变量 arr,指向新数组 + arr = newArr; + System.out.println(Arrays.toString(arr)); + } + + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray2.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray2.java new file mode 100644 index 0000000..17299f3 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestOpArray2.java @@ -0,0 +1,51 @@ +package demo1; + +import java.util.Arrays; + +/** + * 删除数组中的元素 + * @author admin + */ +public class TestOpArray2 { + public static void main(String[] args) { + // 原数组 + int[] arr = new int[]{9, 8, 7, 6, 5, 4}; + + // 要删除元素的下标 + // 即 arr 中下标为 3 的元素,arr[3] = 6 + int dst = 3; + + // 1. 创建一个新数组,长度是原数组的的长度 -1 + int[] newArr = new int[arr.length - 1]; + + // 2. 复制原数组中除了要删除的元素以外的其他元素 + // 方法1:视频中老师使用的方法,一个循环中加判断 +// for (int i = 0; i < arr.length - 1; i++) { +// if (i < dst) { +// // 下标比要删除的下标小,可以直接一对一拷贝 +// newArr[i] = arr[i]; +// } else { +// // 下标大于要删除的下标,需要在原下标 i 的基础上 + 1 +// // 即跳过了要删除的下标 +// newArr[i] = arr[i + 1]; +// } +// } + // 方法2:将数组分为两段,分别用循环遍历,正好跳过了要删除的下标 dst + // 数组中下标小于要删除的下标 + for (int i = 0; i < dst; i++) { + // 直接通过相等的下标赋值 + newArr[i] = arr[i]; + } + // 数组中下标大于要删除的下标 + for (int i = dst; i < arr.length - 1; i++) { + // 在原有下标的基础上 +1,因为跳过了要删除的下标,之后每个下标都要 +1 + newArr[i] = arr[i + 1]; + } + + // 3. 用新数组替换原数组 + arr = newArr; + + // 打印结果 + System.out.println(Arrays.toString(arr)); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/TestSearch.java b/codes/java_dataStructure_luozhaoyong/src/demo1/TestSearch.java new file mode 100644 index 0000000..dd51cb5 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/TestSearch.java @@ -0,0 +1,27 @@ +package demo1; + +/** + * 线性查找 + * @author admin + */ +public class TestSearch { + public static void main(String[] args) { + // 目标数组 + int[] arr = new int[]{2, 3, 5, 6, 8, 4, 9, 0}; + // 目标值 + int target = 0; + // 目标值的下标,初始值为 -1 + int index = -1; + // 遍历数组,查找目标值在数组中的位置 + for (int i = 0; i < arr.length; i++) { + // 如果当前值与目标值相等 + if (arr[i] == target) { + // 将目标值下标指向当前位置 + index = i; + break; + } + } + // 打印目标值下标 + System.out.println(index); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo1/util/MyArray.java b/codes/java_dataStructure_luozhaoyong/src/demo1/util/MyArray.java new file mode 100644 index 0000000..4d5dbc2 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo1/util/MyArray.java @@ -0,0 +1,206 @@ +package demo1.util; + +import java.util.Arrays; + +/** + * 可变的数组 + * + * @author admin + */ +public class MyArray { + /** + * 用于存储数据的数组 + */ + private int[] elements; + + /** + * 构造方法 + */ + public MyArray() { + // 初始化元素数量为 0 + elements = new int[0]; + } + + /** + * 获取数组长度 + */ + public int size() { + return elements.length; + } + + /** + * 向数组末尾添加元素 + * + * @param element + */ + public void add(int element) { + int[] newArr = new int[elements.length + 1]; + + // 将原数组中的元素逐个赋值给新数组 + for (int i = 0; i < elements.length; i++) { + newArr[i] = elements[i]; + } + // 在新数组末尾添加新元素 + newArr[newArr.length - 1] = element; + + // 用新数组替换原始数组 + elements = newArr; + } + + /** + * 显示数组中的所有元素到控制台 + */ + public void show() { + System.out.println(Arrays.toString(elements)); + } + + /** + * 删除指定位置的元素 + * + * @param index + */ + public void delete(int index) { + // 判断下标是否越界 + if (index < 0 || index > elements.length - 1) { + throw new RuntimeException("下标越界"); + } + // 创建新数组,长度比原数组小 1 + int[] newArr = new int[elements.length - 1]; + + // 将要删除元素下标之前的元素拷贝给新数组 + for (int i = 0; i < index; i++) { + newArr[i] = elements[i]; + } + + // 将要删除元素下标之后的元素拷贝给新数组 + for (int i = index; i < newArr.length; i++) { + // 跳过要删除的元素 index,原数组 elements 中每个下标都 +1 + newArr[i] = elements[i + 1]; + } + + // 新数组替换老数组 + elements = newArr; + } + + /** + * 获取指定位置的元素 + * + * @param index + * @return + */ + public int get(int index) { + // 判断下标是否越界 + if (index < 0 || index > elements.length - 1) { + throw new RuntimeException("下标越界"); + } + // 从数组中取出指定下标的元素 + return elements[index]; + } + + /** + * 插入一个元素到指定位置 + * + * @param index + * @param element + */ + public void insert(int index, int element) { + // 判断下标是否越界 + if (index < 0 || index > elements.length - 1) { + throw new RuntimeException("下标越界"); + } + // 创建新数组,长度是原数组长度+1 + int[] newArr = new int[elements.length + 1]; + // 将指定下标之前的元素复制给新数组 + for (int i = 0; i < index; i++) { + newArr[i] = elements[i]; + } + // 将指定下标之后的元素赋值给新数组 + for (int i = index; i < elements.length; i++) { + // 跳过了指定下标 index,新数组每个下标都 +1 + newArr[i + 1] = elements[i]; + } + // 将目标值赋给新数组 index 位置 + newArr[index] = element; + // 新数组替换原数组 + elements = newArr; + } + + /** + * 为数组中指定位置赋值 + * + * @param index + * @param element + */ + public void set(int index, int element) { + // 判断下标是否越界 + if (index < 0 || index > elements.length - 1) { + throw new RuntimeException("越界"); + } + // 直接赋值 + elements[index] = element; + } + + /** + * 线性查找 + * + * @param target + * @return + */ + public int search(int target) { + // 遍历数组 + for (int i = 0; i < elements.length; i++) { + // 如果当前元素与目标值相等 + if (elements[i] == target) { + // 返回当前元素下标 + return i; + } + } + // 否则返回 -1 + return -1; + } + + /** + * 二分查找 + * + * @param target + * @return + */ + public int binarySearch(int target) { + // 起始位置,默认值为数组第一个元素下标 + int begin = 0; + // 结束位置,默认值为数组最后一个元素下标 + int end = elements.length - 1; + // 中间位置,begin + (end-begin)/2 代替 (begin+end)/2 + // 如果 (begin + end) > Integer.MAX_VALUE 时,会造成程序溢出 + int mid = begin + (end - begin) / 2; + + // 当开始位置小于或等于结束位置时,循环继续 + // 当 begin == end 时,end - begin = 0 + // 则 mid = begin + (end - begin)/2 = begin + 0/2 = begin + // 如果 begin 位置还没有被查看 + // begin <= end 需要考虑 begin = end 的情况 + while (begin <= end) { + // 如果 mid 位置刚好等于目标值 + if (elements[mid] == target) { + // 返回下标 mid + return mid; + } + // 如果 mid 位置元素大于目标值 + if (elements[mid] > target) { + // 将结束位置左移到 mid 位置前一个位置 + end = mid - 1; + } else { + // 如果 mid 位置元素小于目标值 + // 说明目标值在 mid 的右边 + // 将开始位置右移到 mid 后一个位置 + begin = mid + 1; + } + // 重新计算 mid 位置的值 + mid = begin + (end - begin) / 2; + } + // 如果没有查询到对应的下标,返回 -1 + return -1; + } + + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo10/Node.java b/codes/java_dataStructure_luozhaoyong/src/demo10/Node.java new file mode 100644 index 0000000..a3abd76 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo10/Node.java @@ -0,0 +1,55 @@ +package demo10; + +/** + * 定义赫夫曼树的节点 + * + * @author admin + */ +public class Node implements Comparable { + /** + * 字符数据 + */ + Byte data; + /** + * 权重 + */ + int weight; + /** + * 左子节点 + */ + Node left; + /** + * 右子节点 + */ + Node right; + + /** + * 构造方法 + * + * @param data + * @param weight + */ + public Node(Byte data, int weight) { + this.data = data; + this.weight = weight; + } + + /** + * 覆写原有比较方法 + * + * @param o + * @return + */ + @Override + public int compareTo(Node o) { + // 返回倒序结果 + return o.weight - this.weight; + } + + @Override + public String toString() { + return "Node{data=" + data + ", weight=" + weight + "}"; + + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo10/TestHuffmanCode.java b/codes/java_dataStructure_luozhaoyong/src/demo10/TestHuffmanCode.java new file mode 100644 index 0000000..434b99d --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo10/TestHuffmanCode.java @@ -0,0 +1,426 @@ +package demo10; + +import java.io.*; +import java.util.*; + +/** + * 测试赫夫曼编码 + * + * @author admin + */ +public class TestHuffmanCode { + + public static void main(String[] args) { + String msg = "can you can a can as a can canner can a can."; + // 1. 字符串 --> 字符数组 + byte[] bytes = msg.getBytes(); + // 使用赫夫曼编码压缩(视频第 45 课) + byte[] b = huffmanZip(bytes); + // 使用赫夫曼编码进行解码 + byte[] newBytes = decode(huffCodes, b); + System.out.println(new String(newBytes)); + + // 源文件,根目录下的 1.bmp 文件 + String src = "1.bmp"; + // 目标路径 + String dst = "2.zip"; + try { + // 压缩文件 + // 成功压缩后会在根目录生成 2.zip 文件 + zipFile(src, dst); + } catch (IOException e) { + e.printStackTrace(); + } + + src = "2.zip"; + dst = "3.bmp"; + try { + // 解压文件 + // 成功解压后会在根目录生成 3.bmp 文件 + // 3.bmp 文件的内容和大小与 1.bmp 文件一致 + // 说明压缩和解压方法正确 + unzip(src, dst); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * 解压文件 + * + * @param src + * @param dst + */ + public static void unzip(String src, String dst) throws IOException, ClassNotFoundException { + // 1. 创建输入流,读取源文件数据 + FileInputStream is = new FileInputStream(src); + // 2. 创建反序列化流对象 + ObjectInputStream ois = new ObjectInputStream(is); + // 3. 从反序列化流获取 bytes 数组 + byte[] b = (byte[]) ois.readObject(); + // 4. 从发序列化流获取赫夫曼编码表 + Map codes = (Map) ois.readObject(); + // 5. 关闭输入流 + is.close(); + // 6. 关闭反序列化流 + ois.close(); + // 7. 通过赫夫曼编码表解码 byte 数组 + byte[] bytes = decode(codes, b); + // 8. 创建输出流对象 + FileOutputStream os = new FileOutputStream(dst); + // 9. 将解码后的 byte 数组写入文件 + os.write(bytes); + // 10. 关闭输出流 + os.close(); + } + + /** + * 压缩文件方法 + * + * @param src + * @param dst + * @throws IOException + */ + public static void zipFile(String src, String dst) throws IOException { + // 1. 创建输入流对象 + InputStream is = new FileInputStream(src); + // 2. 创建与输入流指向文件大小一致的 byte 数组 + byte[] b = new byte[is.available()]; + // 3. 读取文件到 byte 数组 + is.read(b); + // 4. 关闭输入流 + is.close(); + + // 5. 创建输出流对象 + FileOutputStream os = new FileOutputStream(dst); + // 基于输出流创建的序列化流对象 + ObjectOutputStream oos = new ObjectOutputStream(os); + // 6. 调用赫夫曼方法,将原 byte 数组压缩为新的 byte 数组 + byte[] byteZip = huffmanZip(b); + // 7. 将压缩后的字符数组写入目标路径 + oos.writeObject(byteZip); + // 8. 将使用到的赫夫曼编码表写入目标路径 + oos.writeObject(huffCodes); + // 9. 关闭输入流 + os.close(); + // 10. 关闭序列化流 + oos.close(); + } + + /** + * decode 1. 压缩后的字符数组 --> 二进制字符串 + * decode 2. 二进制字符串 + 赫夫曼编码表 --> 原字符数组 + * + * @param huffCodes 赫夫曼编码表 + * @param bytes 压缩后的字符数组 + * @return + */ + private static byte[] decode(Map huffCodes, byte[] bytes) { + // 1. 压缩后的字符数组 --> 二进制字符串 + // 1.1 创建一个可变字符串变量 StringBuilder 对象 + StringBuilder sb = new StringBuilder(); + // 1.2 遍历字符数组 + // 数组的最后一个元素有可能不足 8 位,循环中只处理到倒数第二个 + // 所以 i <= bytes.length - 2 + for (int i = 0; i < bytes.length - 1; i++) { + // 1.3 将每个字符都转为 8 位的二进制字符串 + String str = byteToBitStr(bytes[i]); + sb.append(str); + } + // 最后一个字符单独处理 + String str = Integer.toBinaryString(bytes[bytes.length - 1]); + sb.append(str); + // 打印还原的二进制字符串 + System.out.println(sb); + + // 2. 二进制字符串 + 赫夫曼编码表 --> 原字符数组 + // 2.1 将赫夫曼编码表键值互换 + // 得到新的编码表,键是二进制字符串,值是字符 + Map map = new HashMap<>(huffCodes.size()); + huffCodes.forEach((key, value) -> { + map.put(value, key); + }); + // 创建一个列表用于存储字符 + List list = new ArrayList<>(); + // 2.2 遍历二进制字符串,不断截取子串,从编码表中找出对应的字符 + for (int i = 0; i < sb.length(); ) { + // 临时变量 count 用于确定可用的二进制字符数 + // 初始值从 1 开始 + int count = 1; + // 临时变量存储获取到的字符 + Byte b; + // 视频中 while 循环判断条件为 true + // 应该考虑到 i 不能超出 sb.length() 的限制 + while (i < sb.length()) { + // 在二进制字符串中截取相应长度的键 + String key = sb.substring(i, i + count); + // 通过键查找对应的值 + b = map.get(key); + if (b == null) { + // 如果没有相应的值 + // count 递增,扩大截取的范围 + count++; + } else { + // 将获取到的 byte 字符存入字符列表 + list.add(b); + // 跳出当前循环 + break; + } + } + // 改变控制变量 i 的值,继续下一轮循环 + i += count; + } + // 创建一个新数组 + byte[] b = new byte[list.size()]; + // 将列表的值逐个赋值给新数组 + for (int i = 0; i < b.length; i++) { + b[i] = list.get(i); + } + // 返回数组 + return b; + } + + /** + * 将字符补全为 8 位并转成二进制字符串 + * + * @param b + * @return + */ + private static String byteToBitStr(byte b) { + // 将 byte 转为 int,赋值给临时变量 temp + int temp = b; + // 256 的二进制字符最后 8 位是 0000 0000 + // temp |= 256 可以补全 temp 字符 8 位以内的 0 + temp |= 256; + + // 将补全 0 的 8 位字符 temp 转为二进制字符串 + // 返回二进制字符串 + String str = Integer.toBinaryString(temp); + // 截取后 8 位 + return str.substring(str.length() - 8); + } + + /** + * 进行赫夫曼编码压缩的方法 + * + * @param bytes 待编码的字符数组 + */ + public static byte[] huffmanZip(byte[] bytes) { + // 2. 字符数组 --> 二叉树节点列表 + List nodes = getNodes(bytes); + + // 3. 二叉树节点列表 --> 赫夫曼树 + Node tree = createHuffmanTree(nodes); + // 打印结果 Node{data=null, weight=44} + System.out.println(tree); + // 打印结果 Node{data=null, weight=19} + System.out.println(tree.left); + // 打印结果 Node{data=null, weight=25} + System.out.println(tree.right); + System.out.println("==================="); + // 4. 赫夫曼树 --> 赫夫曼编码表 + // 编码表的 key 是当前节点对应的字符 + // 编码表的 value 是当前节点的路径 + Map huffCodes = getCodes(tree); + System.out.println(huffCodes); + + // 5. 字符数组 + 赫夫曼编码表 --> 二进制字符串 + // 6. 二进制字符串 --> 压缩后的新字符数组 + byte[] b = zip(bytes, huffCodes); + System.out.println(bytes.length); + System.out.println(b.length); + + // 返回字符数组 + return b; + } + + /** + * 5. 字符数组 + 赫夫曼编码表 --> 二进制字符串 + * 6. 二进制字符串 --> 压缩后的新字符数组 + * + * @param bytes 原字符数组 + * @param huffCodes 赫夫曼编码表 + * @return + */ + private static byte[] zip(byte[] bytes, Map huffCodes) { + // 5. 字符数组 + 赫夫曼编码表 --> 二进制字符串 + + // 5.1 创建一个可变字符串 + StringBuilder sb = new StringBuilder(); + // 5.2 遍历原有字符数组 + // 从赫夫曼编码表中逐个获取字符对应的编码 + // 将编码拼接到可变字符串 + for (byte b : bytes) { + String code = huffCodes.get(b); + sb.append(code); + } + // 5.3 最后得到一个二进制字符串 + System.out.println(sb); + + // 6. 二进制字符串 --> 压缩后的新字符数组 + + // 6.1 根据能否整除 8 得到新字符数组的长度 len + // 定义一个常量记录字节长度 8 + final int byteLength = 8; + // 定义一个变量记录新数组长度 + int len; + if (sb.length() % byteLength == 0) { + len = sb.length() / 8; + } else { + len = sb.length() / 8 + 1; + } + // 6.2 创建长度为 len 的字符数组,用于存储压缩后的字符 + byte[] by = new byte[len]; + // 定义新字符数组的索引 + int index = 0; + + // 6.3 对二进制字符串按 8 位一组进行截取,并转为二进制字符 + int i; + for (i = 0; i < (len - 1) * byteLength; i += byteLength) { + // 截取 8 位字符,得到一个字节 + String strByte = sb.substring(i, i + byteLength); + // 将 8 位字节转为二进制整数,再将二进制整数转为字符 + byte byt = (byte) Integer.parseInt(strByte, 2); + // 将字符加入字符数组 + by[index++] = byt; + } + // 截取剩余部分的字符,从 i 起到结尾 + String strByte = sb.substring(i); + // 将剩余部分转为二进制整数,再将二进制整数转为字符 + byte byt = (byte) Integer.parseInt(strByte, 2); + // 将字符加入字符数组 + by[index] = byt; + // 6.4 返回新的字符数组 + return by; + } + + /** + * 可变字符串,用于拼接根结点到达某个节点的路径 + */ + static StringBuilder sb = new StringBuilder(); + /** + * 哈希表,用于存储赫夫曼编码表 + */ + static Map huffCodes = new HashMap<>(); + + /** + * 4. 赫夫曼树 --> 赫夫曼编码表 + * + * @param tree 赫夫曼树 + * @return + */ + private static Map getCodes(Node tree) { + if (tree == null) { + return null; + } + // 对左右孩子节点分别调用编码函数 + getCodes(tree.left, "0", sb); + getCodes(tree.right, "1", sb); + return huffCodes; + } + + /** + * 4. 赫夫曼树 --> 赫夫曼编码表 + * + * @param node 当前节点 + * @param code 当前节点的编码,"0" 代表左节点,"1" 代表右节点 + * @param sb 到达当前节点前所经路径 + */ + private static void getCodes(Node node, String code, StringBuilder sb) { + if (node == null) { + return; + } + // 4.1 创建一个新的可变字符串 + // 创建时拼接上一次的结果,即到达当前节点之前的路径 + StringBuilder sb2 = new StringBuilder(sb); + // 4.2 将当前节点的编码拼接到可变字符串,即形成了到达当前节点的完整路径 + sb2.append(code); + // 4.3 如果当前节点的 data 属性为空,即当前变量没有对应的字符 + // 说明当前变量还有孩子节点,继续递归调用当前方法 + if (node.data == null) { + // 递归调用当前方法,求出左右孩子节点的编码 + getCodes(node.left, "0", sb2); + getCodes(node.right, "1", sb2); + } else { + // 4.4 当前节点有对应的字符,说明已经是叶子节点 + // 将当前节点对应的字符作为 key,到达当前节点所经的路径作为 value,存入赫夫曼编码表 + huffCodes.put(node.data, sb2.toString()); + } + } + + + /** + * 3. 二叉树节点列表 --> 赫夫曼树 + * + * @param nodes + * @return + */ + private static Node createHuffmanTree(List nodes) { + // 列表为空时返回 null + if (nodes == null || nodes.size() == 0) { + return null; + } + // 当列表元素数量大于 1 个时,循环执行 + while (nodes.size() > 1) { + // 3.1 将节点按照权值倒序排列 + Collections.sort(nodes); + // 3.2 取出权值最小的两个节点 + Node left = nodes.get(nodes.size() - 1); + Node right = nodes.get(nodes.size() - 2); + // 3.3 将这两个节点作为孩子节点,创建一个父节点,父节点的权值是两个孩子节点的权值之和 + Node parent = new Node(null, left.weight + right.weight); + // 3.4 将新创建的父节点与孩子节点建立连接 + parent.left = left; + parent.right = right; + // 3.5 从原有列表中删除权值最小的两个节点 + nodes.remove(left); + nodes.remove(right); + // 3.6 将新建的节点加入列表 + nodes.add(parent); + } + + // 3.7 循环结束时,列表只剩下 1 个节点 + // 返回列表中的唯一节点 + // 这个节点就是赫夫曼树的根结点 + return nodes.get(0); + } + + /** + * 2. 字符数组 --> 二叉树节点列表 + * + * @param bytes 字符数组 + * @return + */ + private static List getNodes(byte[] bytes) { + // 2.1 创建一个列表,用于存储二叉树节点 + List nodes = new ArrayList<>(); + // 2.2 创建一个 HashMap,键是字符,值是该字符出现的次数 + // bytes.length 指定 HashMap 大小,原教程视频中没有传入这个参数 + Map counts = new HashMap<>(bytes.length); + // 2.3 遍历字符数组,统计字符出现的次数 + for (byte b : bytes) { + // 获取当前字符 b 的计数 count + Integer count = counts.get(b); + // 如果 count 为空 + if (count == null) { + // 当前字符计数为 1 + counts.put(b, 1); + } else { + // 当前字符的计数在原有基础上加 1 + counts.put(b, count + 1); + } + } + // 2.4 将统计数据转为二叉树节点并存入列表 + // 遍历哈希表中的元素 + for (Map.Entry entry : counts.entrySet()) { + // 将字符和字符出现的次数作为参数传入构造函数,创建一个二叉树节点 + Node node = new Node(entry.getKey(), entry.getValue()); + // 将新创建的节点存入列表 + nodes.add(node); + } + System.out.println(); + // 2.5 返回节点列表 + return nodes; + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo11/BinarySortTree.java b/codes/java_dataStructure_luozhaoyong/src/demo11/BinarySortTree.java new file mode 100644 index 0000000..433249d --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo11/BinarySortTree.java @@ -0,0 +1,150 @@ +package demo11; + +/** + * 二叉排序树 + * + * @author admin + */ +public class BinarySortTree { + /** + * 根结点 + */ + Node root; + + /** + * 添加节点 + * + * @param node + */ + public void add(Node node) { + if (root == null) { + root = node; + } else { + root.add(node); + } + } + + /** + * 中序遍历 + */ + public void midShow() { + if (root != null) { + root.midShow(root); + System.out.println(); + } + } + + /** + * 查找节点 + * + * @param value + * @return + */ + public Node search(int value) { + if (root != null) { + return root.search(value); + } + return null; + } + + /** + * 删除节点 + * + * 课程视频中删除节点的代码判断逻辑比较多,且代码没有复用 + * 这里用另一种思路重新实现了删除节点方法 + * + * @param value + */ + public void delete(int value) { + if (root == null) { + return; + } + // 如果正好等于根结点,则删除根结点 + if (root.value == value) { + // 找到 root 被删除后的替代节点赋值给 root + root = findSuccessor(root); + return; + } + // 1. 查找父节点 + Node parent = root.searchParent(value); + // 如果父节点为空,说明目标值不在树中 + if (parent == null) { + return; + } + + // 2. 删除目标节点 + if (parent.left != null && parent.left.value == value) { + // 如果目标节点是父节点的左子节点 + // 为父节点的左子节点建立新连接 + parent.left = findSuccessor(parent.left); + } else { + // 如果目标节点是父节点的右子节点 + // 为父节点的右子节点建立新连接 + parent.right = findSuccessor(parent.right); + } + } + + /** + * 寻找目标节点被删除后的替代节点 + * + * @param target + */ + private Node findSuccessor(Node target) { + // 3. 分三种情况删除目标节点 + // 3.1 如果目标节点没有孩子节点 + if (target.left == null && target.right == null) { + // 返回 null,直接断开与父节点的连接 + return null; + } + // 3.2 如果目标节点有两个孩子节点 + if (target.left != null && target.right != null) { + // 删除目标节点的最小子节点,并返回最小子节点的值 + // 将最小子节点的值赋给要删除的目标节点 + target.value = deleteMin(target); + // 仍然返回目标节点 + return target; + } + // 3.3 如果目标节点只有一个孩子节点 + // 只有一个左子节点时 + if (target.left != null) { + // 将目标节点的左子节点与父节点建立连接 + return target.left; + } else { // 只有一个右子节点时 + // 将目标节点的左子节点与父节点建立连接 + return target.right; + } + } + + /** + * 删除目标节点的最小子节点 + * 并返回最小子节点的值 + * + * @param target + * @return + */ + private int deleteMin(Node target) { + // 定义临时变量 minNode 用于缓存 target 的最小子节点 + Node minNode = target; + // 定义临时变量 parent + // 用于存储 target 最小子节点的父节点 + Node parent = minNode; + // 查找 target 的最小子节点 + while (minNode.left != null) { + parent = minNode; + minNode = minNode.left; + } + // 循环结束时,minNode 是最小子节点 + // parent 是最小子节点的父节点 + // 如果最小子节点的右子节点为空 + if (minNode.right == null) { + // 直接删除最小子节点 + parent.left = null; + // 最小子节点本身就没有左子节点,无需检查左子节点是否存在 + } else { + // 否则将父节点的左指针指向最小子节点的右子节点 + parent.left = minNode.right; + } + // 返回最小子节点的值 + return minNode.value; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo11/Node.java b/codes/java_dataStructure_luozhaoyong/src/demo11/Node.java new file mode 100644 index 0000000..773984f --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo11/Node.java @@ -0,0 +1,132 @@ +package demo11; + +/** + * 二叉排序树的节点 + * + * @author admin + */ +public class Node { + /** + * 数据 + */ + int value; + /** + * 左子树 + */ + Node left; + /** + * 右子树 + */ + Node right; + + /** + * 构造函数 + * + * @param value + */ + public Node(int value) { + this.value = value; + } + + /** + * 添加节点 + * + * @param node + */ + public void add(Node node) { + // 如果 node 值小于当前节点 + if (node.value < this.value) { + // 如果左子节点为空 + if (this.left == null) { + // 赋值给左子节点 + this.left = node; + } else { + // 否则调用左子节点的添加方法 + this.left.add(node); + } + } else {// 如果 node 值大于当前节点 + // 如果右子节点为空 + if (this.right == null) { + // 赋值给右子节点 + this.right = node; + } else { + // 否则调用右子节点的添加方法 + this.right.add(node); + } + } + } + + /** + * 中序遍历 + * + * @param node + */ + public void midShow(Node node) { + if (node == null) { + return; + } + midShow(node.left); + System.out.print(node.value + " "); + midShow(node.right); + } + + /** + * 查找节点 + * + * @param value + * @return + */ + public Node search(int value) { + if (this.value == value) { + return this; + } + if (this.left != null && this.left.value == value) { + return left; + } + if (this.right != null && this.right.value == value) { + return right; + } + return null; + } + + + /** + * 查找双亲节点 + * + * @param value + * @return + */ + public Node searchParent(int value) { + // 如果左子节点非空 + if (this.left != null) { + // 左子节点的值正好等于目标值 + if (this.left.value == value) { + // 当前节点是目标值的双亲节点,返回当前节点 + return this; + } + // 如果目标值小于当前节点的值 + // 按照二叉查找树的性质,左子节点比双亲节点小 + // 在左子树继续查找 + if (value < this.value) { + return this.left.searchParent(value); + } + } + // 如果右子节点非空 + if (this.right != null) { + // 由子节点的值正好等于目标值 + if (this.right.value == value) { + // 当前节点是目标值的双亲节点,返回当前节点 + return this; + } + // 如果目标值大于当前节点的值 + // 按照二叉查找树的性质,右子节点比双亲节点大 + // 在右子树继续查找 + if (value > this.value) { + return this.right.searchParent(value); + } + } + // 都不符合说明目标值不存在树中,也没有双亲节点 + // 返回 null + return null; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo11/TestBinarySortTree.java b/codes/java_dataStructure_luozhaoyong/src/demo11/TestBinarySortTree.java new file mode 100644 index 0000000..1623198 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo11/TestBinarySortTree.java @@ -0,0 +1,38 @@ +package demo11; + +/** + * 测试二叉排序树 + * @author admin + */ +public class TestBinarySortTree { + public static void main(String[] args) { + int[] arr = new int[]{7, 3, 10, 12, 5, 1, 9}; + BinarySortTree bst = new BinarySortTree(); + // 添加节点 + for (int i : arr) { + bst.add(new Node(i)); + } + // 中序遍历 + bst.midShow(); + + // 查找节点 + Node node1 = bst.search(10); + Node node2 = bst.search(20); + System.out.println(node1); + System.out.println(node2); + + // 删除叶子节点,值为 12 的节点没有孩子节点 + bst.delete(12); + bst.midShow(); + + // 要删除的节点只有一个子节点 + // 上个测试删除的节点 12 就是 10 的子节点 + // 目前 10 只剩下一个子节点 9 + bst.delete(10); + bst.midShow(); + + // 删除的节点有两个孩子节点 + bst.delete(7); + bst.midShow(); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo12/BinarySortTree.java b/codes/java_dataStructure_luozhaoyong/src/demo12/BinarySortTree.java new file mode 100644 index 0000000..bafd3d9 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo12/BinarySortTree.java @@ -0,0 +1,152 @@ +package demo12; + +/** + * 平衡二叉树,重用了 demo 11 的二叉排序树 + * + * @author admin + */ +public class BinarySortTree { + /** + * 根结点 + */ + Node root; + + /** + * 添加节点 + * + * @param node + */ + public void add(Node node) { + if (root == null) { + root = node; + } else { + root.add(node); + } + } + + /** + * 中序遍历 + */ + public void midShow() { + if (root != null) { + root.midShow(root); + System.out.println(); + } + } + + + + /** + * 查找节点 + * + * @param value + * @return + */ + public Node search(int value) { + if (root != null) { + return root.search(value); + } + return null; + } + + /** + * 删除节点 + * + * 课程视频中删除节点的代码判断逻辑比较多,且代码没有复用 + * 这里用另一种思路重新实现了删除节点方法 + * + * @param value + */ + public void delete(int value) { + if (root == null) { + return; + } + // 如果正好等于根结点,则删除根结点 + if (root.value == value) { + // 找到 root 被删除后的替代节点赋值给 root + root = findSuccessor(root); + return; + } + // 1. 查找父节点 + Node parent = root.searchParent(value); + // 如果父节点为空,说明目标值不在树中 + if (parent == null) { + return; + } + + // 2. 删除目标节点 + if (parent.left != null && parent.left.value == value) { + // 如果目标节点是父节点的左子节点 + // 为父节点的左子节点建立新连接 + parent.left = findSuccessor(parent.left); + } else { + // 如果目标节点是父节点的右子节点 + // 为父节点的右子节点建立新连接 + parent.right = findSuccessor(parent.right); + } + } + + /** + * 寻找目标节点被删除后的替代节点 + * + * @param target + */ + private Node findSuccessor(Node target) { + // 3. 分三种情况删除目标节点 + // 3.1 如果目标节点没有孩子节点 + if (target.left == null && target.right == null) { + // 返回 null,直接断开与父节点的连接 + return null; + } + // 3.2 如果目标节点有两个孩子节点 + if (target.left != null && target.right != null) { + // 删除目标节点的最小子节点,并返回最小子节点的值 + // 将最小子节点的值赋给要删除的目标节点 + target.value = deleteMin(target); + // 仍然返回目标节点 + return target; + } + // 3.3 如果目标节点只有一个孩子节点 + // 只有一个左子节点时 + if (target.left != null) { + // 将目标节点的左子节点与父节点建立连接 + return target.left; + } else { // 只有一个右子节点时 + // 将目标节点的左子节点与父节点建立连接 + return target.right; + } + } + + /** + * 删除目标节点的最小子节点 + * 并返回最小子节点的值 + * + * @param target + * @return + */ + private int deleteMin(Node target) { + // 定义临时变量 minNode 用于缓存 target 的最小子节点 + Node minNode = target; + // 定义临时变量 parent + // 用于存储 target 最小子节点的父节点 + Node parent = minNode; + // 查找 target 的最小子节点 + while (minNode.left != null) { + parent = minNode; + minNode = minNode.left; + } + // 循环结束时,minNode 是最小子节点 + // parent 是最小子节点的父节点 + // 如果最小子节点的右子节点为空 + if (minNode.right == null) { + // 直接删除最小子节点 + parent.left = null; + // 最小子节点本身就没有左子节点,无需检查左子节点是否存在 + } else { + // 否则将父节点的左指针指向最小子节点的右子节点 + parent.left = minNode.right; + } + // 返回最小子节点的值 + return minNode.value; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo12/Node.java b/codes/java_dataStructure_luozhaoyong/src/demo12/Node.java new file mode 100644 index 0000000..bb4a2c1 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo12/Node.java @@ -0,0 +1,219 @@ +package demo12; + +/** + * 平衡二叉树的节点 + * 重用了 demo11 二叉排序树的节点 + * + * @author admin + */ +public class Node { + /** + * 数据 + */ + int value; + /** + * 左子树 + */ + Node left; + /** + * 右子树 + */ + Node right; + + /** + * 构造函数 + * + * @param value + */ + public Node(int value) { + this.value = value; + } + + /** + * 获取当前树的高度 + * + * @return + */ + public int height() { + // 取左右子树中高度的最大值,在最大值基础上增加 1 + return Math.max(this.left == null ? 0 : this.left.height(), this.right == null ? 0 : this.right.height()) + 1; + } + + /** + * 获取指定树的高度 + *

+ * 课程视频中分别为左右子树高度写了重复的方法 + * 此处为同一段代码复用 + * + * @param node + * @return + */ + public int height(Node node) { + if (node == null) { + return 0; + } + return node.height(); + } + + /** + * 右旋 + */ + public void rightRotate() { + // 1. node --> newNode + Node newRight = new Node(this.value); + // 2. node.right --> newNode.right + newRight.right = this.right; + // 3. node.left.right --> newNode.left + newRight.left = left.right; + // 4. node.left --> node + this.value = left.value; + // 5. node.left.left --> node.left + this.left = left.left; + // 6. newNode --> node.right + this.right = newRight; + } + + /** + * 左旋 + */ + public void leftRotate() { + // 1. node --> newNode + Node newRight = new Node(this.value); + // 2. node.left --> newNode.left + newRight.left = this.left; + // 3. node.right.left --> newNode.right + newRight.right = right.left; + // 4. node.right --> node + this.value = right.value; + // 5. node.right.right --> node.right + this.right = right.right; + // 6. newNode --> node.left + this.left = newRight; + } + + + /** + * 添加节点 + * + * @param node + */ + public void add(Node node) { + // 如果 node 值小于当前节点 + if (node.value < this.value) { + // 如果左子节点为空 + if (this.left == null) { + // 赋值给左子节点 + this.left = node; + } else { + // 否则调用左子节点的添加方法 + this.left.add(node); + } + } else {// 如果 node 值大于当前节点 + // 如果右子节点为空 + if (this.right == null) { + // 赋值给右子节点 + this.right = node; + } else { + // 否则调用右子节点的添加方法 + this.right.add(node); + } + } + + // 判断是否为平衡二叉树,如果不是平衡树,需要重新调整 + if (height(left) - height(right) > 1) { + // 如果 left.left 高度 < left.right 高度 + // 要进行双旋转 + if (left.left != null && height(left.left) < height(left.right)) { + // 首先对 left 左旋 + left.leftRotate(); + } + // 调用右旋方法 + rightRotate(); + } else if (height(right) - height(left) > 1) { + // 如果 right.right 高度 < right.left 高度 + // 要进行双旋转 + if (right.right != null && height(right.right) < height(right.left)) { + // 首先对 right 右旋 + right.rightRotate(); + } + // 调用左旋方法 + leftRotate(); + } + + } + + + /** + * 中序遍历 + * + * @param node + */ + public void midShow(Node node) { + if (node == null) { + return; + } + midShow(node.left); + System.out.print(node.value + " "); + midShow(node.right); + } + + /** + * 查找节点 + * + * @param value + * @return + */ + public Node search(int value) { + if (this.value == value) { + return this; + } + if (this.left != null && this.left.value == value) { + return left; + } + if (this.right != null && this.right.value == value) { + return right; + } + return null; + } + + + /** + * 查找双亲节点 + * + * @param value + * @return + */ + public Node searchParent(int value) { + // 如果左子节点非空 + if (this.left != null) { + // 左子节点的值正好等于目标值 + if (this.left.value == value) { + // 当前节点是目标值的双亲节点,返回当前节点 + return this; + } + // 如果目标值小于当前节点的值 + // 按照二叉查找树的性质,左子节点比双亲节点小 + // 在左子树继续查找 + if (value < this.value) { + return this.left.searchParent(value); + } + } + // 如果右子节点非空 + if (this.right != null) { + // 由子节点的值正好等于目标值 + if (this.right.value == value) { + // 当前节点是目标值的双亲节点,返回当前节点 + return this; + } + // 如果目标值大于当前节点的值 + // 按照二叉查找树的性质,右子节点比双亲节点大 + // 在右子树继续查找 + if (value > this.value) { + return this.right.searchParent(value); + } + } + // 都不符合说明目标值不存在树中,也没有双亲节点 + // 返回 null + return null; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo12/TestBinarySortTree.java b/codes/java_dataStructure_luozhaoyong/src/demo12/TestBinarySortTree.java new file mode 100644 index 0000000..bd15a3f --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo12/TestBinarySortTree.java @@ -0,0 +1,49 @@ +package demo12; + +/** + * 测试平衡二叉树 + * @author admin + */ +public class TestBinarySortTree { + public static void main(String[] args) { + int[] arr = new int[]{8, 9, 6, 7, 5, 4}; + BinarySortTree bst = new BinarySortTree(); + // 添加节点 + for (int i : arr) { + bst.add(new Node(i)); + } + // 打印结果为 3 + System.out.println(bst.root.height()); + // 打印结果为 6 + System.out.println(bst.root.value); + + System.out.println("======================="); + + // 重新创建一棵平衡二叉树,测试左旋 + arr = new int[]{2, 1, 4, 3, 5, 6}; + bst = new BinarySortTree(); + // 添加节点 + for (int i : arr) { + bst.add(new Node(i)); + } + // 打印结果为 3 + System.out.println(bst.root.height()); + // 打印结果为 4 + System.out.println(bst.root.value); + + System.out.println("======================="); + + // 重新创建一棵平衡二叉树,测试双旋转 + arr = new int[]{8, 9, 5, 4, 6, 7}; + bst = new BinarySortTree(); + // 添加节点 + for (int i : arr) { + bst.add(new Node(i)); + } + // 打印结果为 3 + System.out.println(bst.root.height()); + // 打印结果为 6 + System.out.println(bst.root.value); + + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo13/HashTable.java b/codes/java_dataStructure_luozhaoyong/src/demo13/HashTable.java new file mode 100644 index 0000000..05e4634 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo13/HashTable.java @@ -0,0 +1,44 @@ +package demo13; + +import java.util.Arrays; + +/** + * 自定义哈希表 + * + * @author admin + */ +public class HashTable { + /** + * 存储学生数据的数组 + */ + private StuInfo[] data = new StuInfo[100]; + + /** + * 向散列表中添加元素 + * + * @param stuInfo + */ + public void put(StuInfo stuInfo) { + // 调用散列函数获取存储位置 + int index = stuInfo.hashCode(); + // 在指定位置存入对象 + data[index] = stuInfo; + } + + /** + * 从散列表中获取元素 + * + * @param stuInfo + * @return + */ + public StuInfo get(StuInfo stuInfo) { + return data[stuInfo.hashCode()]; + } + + @Override + public String toString() { + return "HashTable{" + + "data=" + Arrays.toString(data) + + '}'; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo13/StuInfo.java b/codes/java_dataStructure_luozhaoyong/src/demo13/StuInfo.java new file mode 100644 index 0000000..1bda5d0 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo13/StuInfo.java @@ -0,0 +1,59 @@ +package demo13; + +/** + * 学生信息类 + * + * @author admin + */ +public class StuInfo { + int age; + int count; + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + /** + * 自定义散列函数 + * + * @return + */ + @Override + public int hashCode() { + // 1. 直接定址法 + // 将年龄直接返回 + // 2. 取余法 + // 将 age 取模后返回余数 + return age%10; + } + + public StuInfo(int age, int count) { + super(); + this.age = age; + this.count = count; + } + + public StuInfo(int age) { + this.age = age; + } + + @Override + public String toString() { + return "StuInfo{" + + "age=" + age + + ", count=" + count + + '}'; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo13/TestHashTable.java b/codes/java_dataStructure_luozhaoyong/src/demo13/TestHashTable.java new file mode 100644 index 0000000..9a6690a --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo13/TestHashTable.java @@ -0,0 +1,29 @@ +package demo13; + +/** + * 测试散列函数 + * @author admin + */ +public class TestHashTable { + public static void main(String[] args) { + StuInfo s1 = new StuInfo(16, 3); + StuInfo s2 = new StuInfo(17, 11); + StuInfo s3 = new StuInfo(18, 23); + StuInfo s4 = new StuInfo(19, 24); + StuInfo s5 = new StuInfo(20, 9); + + HashTable ht = new HashTable(); + ht.put(s1); + ht.put(s2); + ht.put(s3); + ht.put(s4); + ht.put(s5); + + System.out.println(ht); + + // 获取目标数据 + StuInfo target = new StuInfo(18); + StuInfo info = ht.get(target); + System.out.println(info); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo14/Graph.java b/codes/java_dataStructure_luozhaoyong/src/demo14/Graph.java new file mode 100644 index 0000000..25b27c4 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo14/Graph.java @@ -0,0 +1,140 @@ +package demo14; + +import demo2.MyStack; + +/** + * 图 + * + * @author admin + */ +public class Graph { + /** + * 顶点数组 + */ + Vertex[] vertex; + /** + * 数组下标,作为哈希表地址 + */ + int currentSize; + /** + * 二维数组定义的邻接矩阵 + */ + int[][] adjMat; + /** + * 创建栈用于存储顶点下标 + */ + MyStack stack = new MyStack(); + /** + * 遍历时记录当前访问下标 + */ + int currentIndex; + + /** + * 构造函数 + * + * @param size + */ + public Graph(int size) { + // 定义顶点数组的容量 + this.vertex = new Vertex[size]; + // 根据顶点数量定义邻接矩阵 + this.adjMat = new int[size][size]; + } + + /** + * 添加节点 + * + * @param v + */ + public void addVertex(Vertex v) { + // 直接向数组中添加元素 + this.vertex[currentSize++] = v; + } + + /** + * 添加边 + * 方法与视频课程中稍有不同 + * 在同一个 for 循环里直接查找符合 v1 和 v2 的两个顶点 + * 加上各种判断是否为空的边界条件 + * + * @param v1 + * @param v2 + */ + public void addEdge(String v1, String v2) { + // 矩阵行坐标 + int index1 = -1; + // 矩阵列坐标 + int index2 = -1; + // 遍历数组,查找与指定值 v1 和 v2 相等的顶点 + for (int i = 0; i < vertex.length; i++) { + // 获取当前位置的顶点对象 + Vertex vertex = this.vertex[i]; + // 顶点非空 + if (vertex != null) { + // 找出符合 v1 和 v2 值的顶点 + // 将符合条件的对象在数组的下标赋值给 index1 和 index2 + if (vertex.getValue().equals(v1)) { + index1 = i; + } + if (vertex.getValue().equals(v2)) { + index2 = i; + } + } + } + // 同时找到了两个 index 值再去邻接矩阵查找元素 + if (index1 != -1 && index2 != -1) { + // 将交叉位置赋值为 1,表示两个顶点之间的连接关系 + adjMat[index1][index2] = 1; + adjMat[index2][index1] = 1; + } + } + + /** + * 深度优先遍历方法 + */ + public void dfs() { + // 0. 将访问下标初始值设为 0 + currentIndex = 0; + // 1. 将第 0 个顶点压入栈中,标记为已访问 + stack.push(currentIndex); + vertex[currentIndex].visited = true; + // 5. 重复步骤 2~4,直到栈为空 + while (!stack.isEmpty()) { + // 2. 从当前下标后一个位置起,遍历顶点数组,按序查找当前顶点与其后顶点之间的连接关系 + for (int i = currentIndex + 1; i < vertex.length; i++) { + // adjMat[currentIndex][i] == 1 表示下标为 currentIndex 的顶点和下标为 i 的顶点相通 + // !vertex[i].visited 表示访问时遇到已访问的顶点则跳过 + if (adjMat[currentIndex][i] == 1 && !vertex[i].visited) { + // 打印顶点之间的连接关系 + System.out.println(vertex[currentIndex].getValue() + " --> " + vertex[i].getValue()); + // 将当前顶点下标入栈 + stack.push(i); + // 访问过的顶点标记为已访问 + vertex[i].visited = true; + // A --> B 连通时,currentIndex 对应 A,i 对应 B + // 继续查找时,让 currentIndex 顺延到当前 i 对应的顶点 B 即可 + // 将 i 的值赋给当前下标 currentIndex + currentIndex = i; + /* + 此处对课程视频中的代码做了改进,用 currentIndex = i 代替课程视频中的 continue out + 按照课程视频中的代码 + 不对 currentIndex 修改,直接 continue out 跳出当前循环 + 再次进入 while 循环时,因为 currentIndex 没有变化,会重复执行 for 循环语句 + 执行到上一轮的 i 时,i 已在上一轮被标识位 visited,此时才跳过 i 继续执行 + 即从 continue out 到下一轮执行到 i 位置的操作都是不必要的重复 + */ + } + } + // 3. 查询不到后续顶点的连接关系时,从栈中弹出栈顶元素 + stack.pop(); + // 步骤 4 弹出了栈顶元素,为保证栈非空,需要单独做判断 + if (!stack.isEmpty()) { + // 4. 以新的栈顶元素为顶点继续查找连接关系 + currentIndex = stack.peek(); + } else { + // 否则跳出循环 + break; + } + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo14/TestGraph.java b/codes/java_dataStructure_luozhaoyong/src/demo14/TestGraph.java new file mode 100644 index 0000000..317525c --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo14/TestGraph.java @@ -0,0 +1,51 @@ +package demo14; + +import java.util.Arrays; + +/** + * 测试图 + * + * @author admin + */ +public class TestGraph { + public static void main(String[] args) { + Vertex v1 = new Vertex("A"); + Vertex v2 = new Vertex("B"); + Vertex v3 = new Vertex("C"); + Vertex v4 = new Vertex("D"); + Vertex v5 = new Vertex("E"); + + Graph g = new Graph(5); + g.addVertex(v1); + g.addVertex(v2); + g.addVertex(v3); + g.addVertex(v4); + g.addVertex(v5); + + g.addEdge("A", "C"); + g.addEdge("B", "C"); + g.addEdge("A", "B"); + g.addEdge("B", "D"); + g.addEdge("B", "E"); + + // 遍历打印邻接矩阵,查看添加边的操作是否正确 + // 打印结果: + // [0, 1, 1, 0, 0] + // [1, 0, 1, 1, 1] + // [1, 1, 0, 0, 0] + // [0, 1, 0, 0, 0] + // [0, 1, 0, 0, 0] + for (int[] a : g.adjMat) { + System.out.println(Arrays.toString(a)); + } + + // 执行深度优先遍历 + // 打印结果: + // A --> B + // B --> C + // B --> D + // B --> E + g.dfs(); + + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo14/Vertex.java b/codes/java_dataStructure_luozhaoyong/src/demo14/Vertex.java new file mode 100644 index 0000000..6cd7289 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo14/Vertex.java @@ -0,0 +1,34 @@ +package demo14; + +/** + * 顶点类 + * + * @author admin + */ +public class Vertex { + /** + * 顶点数据内容 + */ + String value; + /** + * 顶点是否已经访问过 + */ + boolean visited; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Vertex(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/DoubleNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/DoubleNode.java new file mode 100644 index 0000000..c823bb1 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/DoubleNode.java @@ -0,0 +1,78 @@ +package demo2; + +/** + * 定义双向链表的节点 + * @author admin + */ +public class DoubleNode { + /** + * 前置节点 + */ + DoubleNode pre = this; + + /** + * 后继节点 + */ + DoubleNode next = this; + + /** + * 节点数据 + */ + int data; + + /** + * 构造函数 + * @param data + */ + public DoubleNode(int data){ + this.data = data; + } + + /** + * 插入节点方法 + * @param node + */ + public void after(DoubleNode node){ + // 获取当前节点的后继节点 + DoubleNode nextNext = this.next; + // 将当前节点的后继节点指向新节点 + this.next = node; + // 新节点的前置节点指向当前节点 + node.pre = this; + + // 新节点的后继节点指向原后继节点 + node.next = nextNext; + // 原后继节点的前置节点指向新节点 + nextNext.pre = node; + + // 上述过程将新节点插入到当前节点和原后继节点之间 + } + + /** + * 获取后继节点 + * @return + */ + public DoubleNode next(){ + // 返回后继节点 + return this.next; + } + + /** + * 获取前置节点 + * @return + */ + public DoubleNode pre(){ + // 返回前置节点 + return this.pre; + } + + /** + * 获取数据 + * @return + */ + public int getData(){ + // 返回当前节点数据 + return this.data; + } +} + diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/LoopNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/LoopNode.java new file mode 100644 index 0000000..2c187cd --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/LoopNode.java @@ -0,0 +1,73 @@ +package demo2; + +/** + * 定义节点类 + * + * @author admin + */ +public class LoopNode { + /** + * 节点数据 + */ + int data; + /** + * 后继节点 + * 尾节点指向头节点 + */ + LoopNode next = this; + + /** + * 构造方法 + * + * @param data + */ + public LoopNode(int data) { + this.data = data; + } + + /** + * 获取后继节点 + * + * @return + */ + public LoopNode next() { + // 直接返回后继节点 + return this.next; + } + + /** + * 获取节点数据 + * + * @return + */ + public int getData() { + return this.data; + } + + + /** + * 删除当前节点的下一个节点 + */ + public void removeNext() { + // 如果当前节点的后继节点为空,直接返回 + if (next == null) { + return; + } + // 将当前节点的后继节点指向下下个节点 + this.next = next.next; + } + + /** + * 插入一个新节点 + * + * @param node + */ + public void after(LoopNode node) { + // 获取当前节点的后继节点 + LoopNode nextNext = this.next; + // 当前节点的后继节点指向新加入的节点 + this.next = node; + // 新节点的后继节点指向原先的后继节点 + node.next = nextNext; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/MyQueue.java b/codes/java_dataStructure_luozhaoyong/src/demo2/MyQueue.java new file mode 100644 index 0000000..0032026 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/MyQueue.java @@ -0,0 +1,77 @@ +package demo2; + +/** + * 数组实现一个队列 + * @author admin + */ +public class MyQueue { + /** + * 存储数据的数组 + */ + int[] elements; + + /** + * 构造方法 + */ + public MyQueue() { + // 初始化数组 + elements = new int[0]; + } + + /** + * 入队 + * @param element + */ + public void add(int element) { + // 新建一个数组,长度是原数组的长度+1 + int[] newArr = new int[elements.length + 1]; + + // 将原数组中的元素赋值逐个给新数组 + for (int i = 0; i < elements.length; i++) { + newArr[i] = elements[i]; + } + + // 将新元素赋值给新数组的最后一个位置 + newArr[newArr.length - 1] = element; + // 新旧数组替换 + elements = newArr; + } + + /** + * 出队 + * @return + */ + public int poll() { + if (elements.length == 0) { + throw new RuntimeException("queue is empty"); + } + // 取出数组的第一个元素 + int element = elements[0]; + + // 创建一个新数组,长度比原数组长度少 1 + int[] newArr = new int[elements.length - 1]; + + // 将原数组除第一个元素以外的所有元素赋值给新数组 + for (int i = 1; i < elements.length; i++) { + // 取原数组元素时,i 从 1开始 + // 新数组下标从 0 开始,所以对应每个下标要在 i 的基础上 -1 + newArr[i - 1] = elements[i]; + } + // 新旧数组替换 + elements = newArr; + + // 返回出队的元素 + return element; + } + + /** + * 判断队列是否为空 + * @return + */ + public boolean isEmpty() { + // 判断队列长度是否为 0 + return elements.length == 0; + } + + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/MyStack.java b/codes/java_dataStructure_luozhaoyong/src/demo2/MyStack.java new file mode 100644 index 0000000..46c8eb3 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/MyStack.java @@ -0,0 +1,94 @@ +package demo2; + + +/** + * 数组实现栈 + * @author admin + */ +public class MyStack { + + /** + * 使用数组存储数据 + */ + int[] elements; + + /** + * 构造函数 + */ + public MyStack() { + // elements 初始化为空数组 + elements = new int[0]; + } + + /** + * 压入元素 + * @param element + */ + public void push(int element) { + // 新建数组,比原数组长度大 1 + int[] newArr = new int[elements.length + 1]; + + // 遍历原数组 + for (int i = 0; i < elements.length; i++) { + // 将元素逐个赋值给新数组 + newArr[i] = elements[i]; + } + + // 将新元素赋值给新数组最后一个位置 + newArr[newArr.length - 1] = element; + + // 新旧数组替换 + elements = newArr; + } + + /** + * 取出栈顶元素 + * @return + */ + public int pop() { + // 如果栈为空,抛出异常 + if (elements.length == 0) { + throw new RuntimeException("stack is empty"); + } + + // 取出数组中最后一个元素 + int element = elements[elements.length - 1]; + + // 创建一个新数组,比原数组小 1 + int[] newArr = new int[elements.length - 1]; + + // 遍历原数组,但是不包括最后一个元素 + // 所以控制变量 i 的最大值小于 elements.length -1 + for (int i = 0; i < elements.length - 1; i++) { + // 将原数组中的值逐个赋值给新数组 + newArr[i] = elements[i]; + } + // 新旧数组替换 + elements = newArr; + // 返回取出的栈顶元素 + return element; + } + + /** + * 查看栈顶元素 + * @return + */ + public int peek() { + // 如果栈为空,抛出异常 + if (elements.length == 0) { + throw new RuntimeException("stack is empty"); + } + // 返回数组最后一个元素,即栈顶元素 + return elements[elements.length - 1]; + } + + /** + * 判断栈是否为空 + * @return + */ + public boolean isEmpty() { + // 判断数组的长度是否为 0 + return elements.length == 0; + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/Node.java b/codes/java_dataStructure_luozhaoyong/src/demo2/Node.java new file mode 100644 index 0000000..34bd559 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/Node.java @@ -0,0 +1,119 @@ +package demo2; + +/** + * 定义节点类 + * @author admin + */ +public class Node { + /** + * 节点数据 + */ + int data; + /** + * 后继节点 + */ + Node next; + + /** + * 构造方法 + * @param data + */ + public Node(int data) { + this.data = data; + } + + /** + * 追加节点 + * @param node + * @return + */ + public Node append(Node node) { + // 定义一个变量 currentNode 指向当前节点 + Node currentNode = this; + + // 教学视频中的写法 +// while (true){ +// // 获取当前节点的后继节点 +// Node nextNode = currentNode.next; +// // 如果后继节点为空,跳出循环 +// if(nextNode==null){ +// break; +// } +// // 当前节点指向后继节点,循环继续 +// currentNode = nextNode; +// } + // 如果后继节点非空,循环继续 + while (currentNode.next != null) { + // 当前节点 currentNode 指向后继节点 + currentNode = currentNode.next; + } + // 循环结束时,currentNode 已经指向链表的尾节点 + // 将参数 node 赋值给 currentNode 的后继节点 + currentNode.next = node; + // 返回当前节点 + return this; + } + + /** + * 获取后继节点 + * @return + */ + public Node next() { + // 直接返回后继节点 + return this.next; + } + + /** + * 获取节点数据 + * @return + */ + public int getData() { + return this.data; + } + + /** + * 判断当前节点是否是最后一个节点 + * @return + */ + public boolean isLast() { + // 判断当前节点的后继节点是否为空 + return this.next == null; + } + + /** + * 删除当前节点的下一个节点 + */ + public void removeNext() { + // 如果当前节点的后继节点为空,直接返回 + if (next == null) { + return; + } + // 将当前节点的后继节点指向下下个节点 + this.next = next.next; + } + + /** + * 插入一个新节点 + * @param node + */ + public void after(Node node) { + // 获取当前节点的后继节点 + Node nextNext = this.next; + // 当前节点的后继节点指向新加入的节点 + this.next = node; + // 新节点的后继节点指向原先的后继节点 + node.next = nextNext; + } + + /** + * 打印所有节点的值 + */ + public void show() { + Node currentNode = this; + while (currentNode != null) { + System.out.print(currentNode.data + " "); + currentNode = currentNode.next; + } + System.out.println(); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/TestLoopNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/TestLoopNode.java new file mode 100644 index 0000000..bd94858 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/TestLoopNode.java @@ -0,0 +1,19 @@ +package demo2; + +/** + * 测试循环链表 + */ +public class TestLoopNode { + public static void main(String[] args) { + // 创建新节点 + LoopNode n1 = new LoopNode(1); + LoopNode n2 = new LoopNode(2); + LoopNode n3 = new LoopNode(3); + LoopNode n4 = new LoopNode(4); + // 插入节点 + n1.after(n2); + // 显示结果 + System.out.println(n1.next().getData()); // 2 + System.out.println(n2.next().getData()); // 1 + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestDoubleNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestDoubleNode.java new file mode 100644 index 0000000..cdfa0fc --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestDoubleNode.java @@ -0,0 +1,41 @@ +package demo2.test; + +import demo2.DoubleNode; + +/** + * 测试双向链表 + * @author admin + */ +public class TestDoubleNode { + public static void main(String[] args) { + // 创建节点 + DoubleNode n1 = new DoubleNode(1); + DoubleNode n2 = new DoubleNode(2); + DoubleNode n3 = new DoubleNode(3); + // 打印节点的值,结果为 1 + System.out.println(n1.pre().getData()); + // 打印结果为 1 + System.out.println(n1.getData()); + // 打印结果为 1 + System.out.println(n1.next().getData()); + System.out.println(); + + // 节点之间建立连接 + n1.after(n2); + n2.after(n3); + // 打印节点的值,打印结果为 1 + System.out.println(n2.pre().getData()); + // 打印结果为 2 + System.out.println(n2.getData()); + // 打印结果为 3 + System.out.println(n2.next().getData()); + System.out.println(); + + // 双向循环链表最后添加的节点,后继节点指向第一个节点,打印结果为 1 + System.out.println(n3.next().getData()); + // 打印结果为 3 + System.out.println(n1.pre().getData()); + + + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestLoopNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestLoopNode.java new file mode 100644 index 0000000..a3b105a --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestLoopNode.java @@ -0,0 +1,31 @@ +package demo2.test; + +import demo2.LoopNode; + +/** + * 测试循环链表 + * + * @author admin + */ +public class TestLoopNode { + public static void main(String[] args) { + LoopNode n1 = new LoopNode(1); + LoopNode n2 = new LoopNode(2); + LoopNode n3 = new LoopNode(3); + LoopNode n4 = new LoopNode(4); + + // 增加节点 + n1.after(n2); + n2.after(n3); + n3.after(n4); + + // 打印结果是 2 + System.out.println(n1.next().getData()); + // 打印结果是 3 + System.out.println(n2.next().getData()); + // 打印结果是 4 + System.out.println(n3.next().getData()); + // 打印结果是 1,循环链表首尾相连 + System.out.println(n4.next().getData()); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyQueue.java b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyQueue.java new file mode 100644 index 0000000..703447e --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyQueue.java @@ -0,0 +1,31 @@ +package demo2.test; + +import demo2.MyQueue; + +/** + * 测试队列 + * @author admin + */ +public class TestMyQueue { + public static void main(String[] args) { + // 创建一个队列 + MyQueue mq = new MyQueue(); + // 添加元素 + mq.add(9); + mq.add(8); + mq.add(7); + // 出队,打印结果为 9 + System.out.println(mq.poll()); + mq.add(6); + // 出队前有新元素入队,不影响出队的顺序,打印结果为 8 + System.out.println(mq.poll()); + // 判断是否为空,打印结果为 false + System.out.println(mq.isEmpty()); + // 继续出队,打印结果为 7 + System.out.println(mq.poll()); + // 大姨结果为 8 + System.out.println(mq.poll()); + // 再判断是否为空,打印结果为 true + System.out.println(mq.isEmpty()); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyStack.java b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyStack.java new file mode 100644 index 0000000..0732807 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestMyStack.java @@ -0,0 +1,45 @@ +package demo2.test; + +import demo2.MyStack; + +/** + * 测试栈 + * + * @author admin + */ +public class TestMyStack { + public static void main(String[] args) { + MyStack ms = new MyStack(); + // 测试栈为空时抛出异常 + try { + ms.pop(); + } catch (RuntimeException e) { + e.printStackTrace(); + } + + // 压入数据 + ms.push(9); + ms.push(8); + ms.push(7); + + // 查看栈顶元素,打印结果为 7 + System.out.println(ms.peek()); + + // 取出栈顶元素,打印结果为 7 + System.out.println(ms.pop()); + + // 再次查看栈顶元素,打印结果为 8 + System.out.println(ms.peek()); + + // 判断栈是否为空,打印结果为 false + System.out.println(ms.isEmpty()); + + // 取出栈顶元素,打印结果为 8 + System.out.println(ms.pop()); + // 打印结果为 9 + System.out.println(ms.pop()); + + // 判断栈是否为空,打印结果为 true + System.out.println(ms.isEmpty()); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestNode.java b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestNode.java new file mode 100644 index 0000000..9a1baf8 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo2/test/TestNode.java @@ -0,0 +1,47 @@ +package demo2.test; + +import demo2.Node; + +/** + * 测试单链表 + * + * @author admin + */ +public class TestNode { + public static void main(String[] args) { + // 创建节点 + Node n1 = new Node(1); + Node n2 = new Node(2); + Node n3 = new Node(3); + // 追加节点 + n1.append(n2).append(n3).append(new Node(4)); + // 获取后继节点,打印结果为 3 + System.out.println(n1.next().next().getData()); + // 判断节点是否为最后一个节点,打印结果为 false + System.out.println(n1.isLast()); + // 打印结果为 true + System.out.println(n1.next().next().next().isLast()); + + // 显示已有节点,打印结果 1 2 3 4 + n1.show(); + // 删除 n3 + n1.next().removeNext(); + // 显示删除后剩余的节点,打印结果 1 2 4 + n1.show(); + + // 创建一个新节点 + Node node = new Node(3); + // 将新节点插入 n2 之后 + n1.next().after(node); + // 重新显示所有节点,打印结果 1 2 3 4 + n1.show(); + + // 再来一次 + // 创建一个新节点 + node = new Node(5); + // 将新节点插入 n2 之后 + n1.next().after(node); + // 重新显示所有节点,打印结果 1 2 5 3 4 + n1.show(); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo3/TestFibonacci.java b/codes/java_dataStructure_luozhaoyong/src/demo3/TestFibonacci.java new file mode 100644 index 0000000..8412e61 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo3/TestFibonacci.java @@ -0,0 +1,33 @@ +package demo3; + +/** + * 测试斐波那契数列 + * @author admin + */ +public class TestFibonacci { + public static void main(String[] args) { + // 斐波那契数列 1 1 2 3 5 8 13 + int i = fibonacci(3); + // 打印结果为 2 + System.out.println(i); + + i = fibonacci(6); + // 打印结果为 8 + System.out.println(i); + } + + /** + * 斐波那契数列求值函数 + * @param i + * @return + */ + public static int fibonacci(int i) { + // 递归函数停止条件,当 i 等于 1 或者 2 时返回数字 1 + if (i == 1 || i == 2) { + return 1; + } + // 其他情况递归调用当前函数 + // 即第 i 项等于前两项之和 + return fibonacci(i - 1) + fibonacci(i - 2); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo3/TestHanoi.java b/codes/java_dataStructure_luozhaoyong/src/demo3/TestHanoi.java new file mode 100644 index 0000000..5b07590 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo3/TestHanoi.java @@ -0,0 +1,53 @@ +package demo3; + +/** + * 测试汉诺塔 + * @author admin + */ +public class TestHanoi { + public static void main(String[] args) { + hanoi(1, 'A', 'B', 'C'); + System.out.println(); + + hanoi(2, 'A', 'B', 'C'); + System.out.println(); + + hanoi(3, 'A', 'B', 'C'); + System.out.println(); + + hanoi(4, 'A', 'B', 'C'); + } + + /** + * 共有 n 个盘子 + * 将上面的 n - 1 个盘子视为 1 个整体 + * 最底下的 1 个盘子视为 1 个整体 + * 3 根柱子中的空闲柱子作为中转 + * 当 n>=3 时,每次递归都将问题转化为 2 个盘子的情况 + * + * @param n 盘子总数 + * @param from 第一根柱子 + * @param in 中间的柱子 + * @param to 最后一根柱子 + */ + public static void hanoi(int n, char from, char in, char to) { + // 只有一个盘子的情况 + if (n == 1) { + // 直接将当前盘子移动到目标位置 + System.out.println("第 1 个盘子从 " + from + " 移动到 " + to); + + // 其他情况都转换成处理 2 个盘子的汉诺塔问题 + } else { + // 将上面的 n-1 个盘子视为 1 个整体,从原位置 from 移动到中间位置 in + // to 此时为空,作为中转的柱子 + hanoi(n - 1, from, to, in); + + // 再将最底下的 1 个盘子,从原位置 from 移动到最终的目标位置 to + System.out.println("第 " + n + " 个盘子从 " + from + " 移动到 " + to); + + // 最后将放在中间位置 in 的盘子,也移动到目标位置 to + // from 此时为空,作为中转的柱子 + hanoi(n - 1, in, from, to); + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo3/TestRecursive.java b/codes/java_dataStructure_luozhaoyong/src/demo3/TestRecursive.java new file mode 100644 index 0000000..3977665 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo3/TestRecursive.java @@ -0,0 +1,23 @@ +package demo3; + +/** + * 测试递归 + * @author admin + */ +public class TestRecursive { + public static void main(String[] args) { + // 调用递归函数 + print(3); + } + + /** + * 递归打印 + * @param i + */ + public static void print(int i) { + if (i > 0) { + System.out.println(i); + print(i - 1); + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/BubbleSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/BubbleSort.java new file mode 100644 index 0000000..20110c9 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/BubbleSort.java @@ -0,0 +1,60 @@ +package demo4; + +import java.util.Arrays; + +/** + * 冒泡排序 + *

+ * 多次遍历数组 + * 每次逐个比较相邻两个元素 + * 如果没有按照指定顺序排列,就互换元素 + * 直到遍历结束或者全部有序为止 + * + * @author admin + */ +public class BubbleSort { + public static void main(String[] args) { + int[] arr = new int[]{5, 7, 2, 9, 4, 1, 0, 5, 7}; + bubbleSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 冒泡排序 + *

+ * 时间复杂度:O(n^2) + * 外循环执行了 n 次 + * 内循环每次都排除上一轮已排好序的末尾元素,因此每轮递减 1 + * (n-1) + (n-2) + ... 1 = (n-1+1)/2 = n/2 + * 外循环 * 内循环 = n*(n/2) = n^2/2 + * O(n^2/2) = O(n^2) + *

+ * 空间复杂度:O(1),没有使用额外空间 + */ + public static void bubbleSort(int[] arr) { + // 如果数组长度小于等于 1,不用排序 + if (arr.length <= 1) { + return; + } + // 临时变量,用于两数交换时做临时存储 + int temp; + for (int i = 0; i < arr.length - 1; i++) { + + // 每轮排序,最大的值都会排到末尾 + // i = 1 时,arr[arr.length-1-1] 已经在上一轮排好序了 + // i = 2 时,arr[arr.length-1-2] 已经在上一轮排好序了 + // 因此内循环控制变量 j 的值,最大应小于 arr.length - 1 - i + // 可以避免重复检查数组末尾已经排好序的部分 + for (int j = 0; j < arr.length - 1 - i; j++) { + if (arr[j] > arr[j + 1]) { + // 临时变量存储 arr[j] 的值 + temp = arr[j]; + // 将 arr[j+1] 的值赋给 arr[j] + arr[j] = arr[j + 1]; + // 将原 arr[j] 的值赋给 arr[j] + arr[j + 1] = temp; + } + } + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/HeapSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/HeapSort.java new file mode 100644 index 0000000..efc0194 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/HeapSort.java @@ -0,0 +1,95 @@ +package demo4; + +import java.util.Arrays; + +/** + * 堆排序 + *

+ * 假设有大小为 n 的顺序排列二叉树 + * 1. 首先将顺序排列二叉树调整为大顶堆 + * 2. 交换堆顶元素和最后一个叶子节点,即数组的第 0 个元素和第 n 个元素交换 + * 3. 数组第 n 个元素已经排好序,数组递减 1,对递减后的数组重复步骤 1~2 + * + * @author admin + */ +public class HeapSort { + + public static void main(String[] args) { + int[] arr = new int[]{9, 6, 8, 7, 0, 1, 10, 4, 2}; + heapSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 堆排序方法 + * + * @param arr + */ + public static void heapSort(int[] arr) { + // 1. 获取最后一个非叶子节点下标 + // 最后一个叶子节点的下标为 arr.length - 1 + // 根据公式,最后一个叶子节点的父节点下标为 (arr.length - 1) / 2 + // 最后一个叶子节点的父节点,就是最后一个非叶子节点 + int start = (arr.length - 1) / 2; + // 2. 从最后一个非叶子节点开始,将整个顺序存储二叉树调整为大顶堆 + for (int i = start; i >= 0; i--) { + // 调用方法将当前位置 i 的子树调整为大顶堆 + maxHeap(arr, arr.length, i); + } + + // 3. 遍历数组,每轮都将大顶堆的堆顶移动到当前轮的最后 + for (int i = arr.length - 1; i > 0; i--) { + // 将堆顶元素 arr[0] 交换到数组当前的末尾位置 i + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + // 交换后堆顶的结构被破坏 + // 重新调用方法将堆顶调整为大顶堆 + maxHeap(arr, i, 0); + } + } + + /** + * 将顺序排列二叉树调整为大顶堆的方法 + * + * @param arr 数组 + * @param size 数组大小 + * @param index 要操作的节点在数组中 arr 中的下标 + */ + public static void maxHeap(int[] arr, int size, int index) { + // 1. 获取当前节点的左右子节点下标 + int leftNode = index * 2 + 1; + int rightNode = index * 2 + 2; + // 定义一个变量 max,用于存储节点中最大节点的下标 + // 初始值为当前元素下标 index + int max = index; + + // 2. 比较当前节点和左右子节点并找出最大值下标 + // 比较 max 节点和左子节点,左子节点下标 leftNode 要小于数组长度 + if (leftNode < size && arr[max] < arr[leftNode]) { + // 如果 leftNode 对应的值更大,将 leftNode 赋值给 max + max = leftNode; + } + + // 比较 max 节点和右子节点,右子节点下标 rightNode 要小于数组长度 + if (rightNode < size && arr[max] < arr[rightNode]) { + // 如果 rightNode 对应的值更大,将 rightNode 赋值给 max + max = rightNode; + } + + // 3. 如果最大值下标 max 与 当前元素下标不相等 + // 说明当前节点不是最大值,需要将最大值交换到当前节点的位置 + if (max != index) { + // 交换 max 位置和 index 位置的元素 + int temp = arr[max]; + arr[max] = arr[index]; + arr[index] = temp; + + // 4. 交换元素后,如果 max 位置的元素是非叶子节点 + // 需要重新调整它的结构,重新调用 maxHeap 方法 + maxHeap(arr, size, max); + } + + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/InsertSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/InsertSort.java new file mode 100644 index 0000000..b59c1b1 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/InsertSort.java @@ -0,0 +1,67 @@ +package demo4; + +import java.util.Arrays; + +/** + * 插入排序 + *

+ * 从第一个元素开始,把数组分成有序和无序两部分 + * 每轮都从无序部分取出一个元素 + * 按照指定顺序插入有序部分 + * 重复上述步骤,有序部分不断向右扩大,直到所有元素排好序 + * + * @author admin + */ +public class InsertSort { + public static void main(String[] args) { + int[] arr = new int[]{5, 3, 2, 8, 5, 9, 1, 0}; + insertSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 插入排序方法 + *

+ * 外循环执行了 n 次 + * 内循环每次都为插入元素,将有序部分的元素移动若干次 + * 最差情况依次执行了 1 次移动、2 次移动、3 次移动,n-1 次移动 + * 但是并非每次都要移动有序部分的所有元素 + * 均摊情况可以视为大致移动了一半的元素 + * 因此内均摊情况依次进行了 1/2 次移动、2/2 次移动、3/2 次移动、 (n-1)/2 次移动 + * 总共执行了 (1/2 + 2/2 + 3/2 + ... (n-1)/2) = (1/2 + (n-1)/2))/2 = n/4 次移动 + * 所以总的时间复杂度是 + * 外循环执行次数 * 内循环时间复杂度 = n * n/4 = n^2/4 + * O(n^2/4) = O(n^2) + * + * @param arr 待排序的数组 + */ + public static void insertSort(int[] arr) { + if (arr.length <= 1) { + return; + } + + // 临时变量,用于存储当前元素的值 + int temp; + // 从下标 1,即第 2 个元素开始遍历 + for (int i = 1; i < arr.length; i++) { + // 将当前元素 arr[i] 的值赋给临时变量 temp + temp = arr[i]; + // 内循环控制变量 j 从 i 的前一个元素开始 + // 满足条件 j >=0 保证数组不越界 + // 同时满足 temp 比内循环当前元素 arr[j] 小 + int j; + for (j = i - 1; j >= 0 && temp < arr[j]; j--) { + // 将当前元素的值赋给后一个元素 + // 即所有比 temp 大的元素都不断后移 + // 直至找到比 temp 小的元素为止 + arr[j + 1] = arr[j]; + } + // 循环结束时,arr[j] < temp + // 此时 arr[j+1] 已经腾出了空间 + // 将 temp 值插入 arr[j + 1] 的位置 + // 满足条件 arr[j] < arr[j+1] = temp < arr[j+2] + arr[j + 1] = temp; + } + + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/MergeSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/MergeSort.java new file mode 100644 index 0000000..394ff98 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/MergeSort.java @@ -0,0 +1,115 @@ +package demo4; + +import java.util.Arrays; + +/** + * 归并排序 + *

+ * 将数组分为两部分 + * 对每部分都递归使用归并排序方法 + * 两部分排好序后 + * 再将数组的两部分合并到一起 + * + * @author admin + */ +public class MergeSort { + public static void main(String[] args) { + int[] arr = new int[]{1, 3, 5, 2, 4, 6, 8, 10}; + mergeSort(arr, 0, arr.length - 1); + System.out.println(Arrays.toString(arr)); + } + + /** + * 归并排序方法 + * 将原数组折半划分为两部分 + * 依次对两部分递归调用递归算法 + * 直到数组不可再分 + * 对排好序的两部分调用归并方法合并为一个数组 + *

+ * 时间复杂度: + * 每轮都将数组折半,直到不可再分,总共是 logN 轮 + * 每一轮的合并方法最多执行 n 次循环 + * 总共的时间复杂度是 O(NlogN) + * + * @param arr 待排序数组 + * @param low 要排序部分的起始位置 + * @param high 要排序部分的结束位置 + */ + public static void mergeSort(int[] arr, int low, int high) { + // 如果起始位置不小于结束位置,结束排序 + if (low >= high) { + return; + } + // 获取中间位置 + int middle = low + (high - low) / 2; + // 为左半部分数组排序 + mergeSort(arr, low, middle); + // 为右半部分数组排序 + mergeSort(arr, middle + 1, high); + // 将排好序的两部分数组合并 + merge(arr, low, middle, high); + } + + /** + * 归并数组的合并方法 + *

+ * 原数组已经被分为两部分,每部分都各自有序 + * 创建一个与原数组等长的临时数组 + * 依次从两部分中取出元素进行对比,按照顺序放入临时数组 + * 所有元素都放入新数组后,整个数组已经排好序 + * 将临时数组重新赋值给原有数组 + * + * @param arr + * @param low + * @param middle + * @param high + */ + public static void merge(int[] arr, int low, int middle, int high) { + // 创建一个新数组,用于存储合并后的元素 + int[] temp = new int[high - low + 1]; + // 临时变量 i 和 j 分别指向两部分数组的起始位置 + // 第一部分数组从 low 开始 + int i = low; + // 第二部分数组从 middle + 1开始 + int j = middle + 1; + + // 定义一个下标用于遍历新数组 + int index = 0; + // 遍历原数组的两部分 + while (i <= middle && j <= high) { + // 归并排序的条件之一就是要合并的两部分数组是各自排好序的 + // 即数组两部分满足 arr[i] <= arr[i+1] 和 arr[j] <= arr[j+1] + // 当 arr[i] <= arr[j] 时,将较小的 arr[i] 放入新数组后 + // 继续向后遍历,数组两部分都不会出现比 arr[i] 更小的数字 + // 同理,如果 arr[j] 较小,继续遍历也不会出现比 arr[j] 更小的数字 + // 所以,这种方式排列出的新数组是有序的 + // 通过比较,将 arr[i] 和 arr[j] 中较小的数字放入新数组 + if (arr[i] <= arr[j]) { + // arr[i] 放入新数组 index 位置后 + // index 和 i 都要递增 + temp[index++] = arr[i++]; + // 上述写法是简便写法,等价于下面的写法 + // newArr[index] = arr[i]; + // index++; + // i++; + } else { + // 同理,将 arr[j] 放入新数组后 + // index 和 j 都递增 + temp[index++] = arr[j++]; + } + } + // 上一个循环结束时,可能会出现 i 或 j 没有遍历到各自结尾的情况 + // 将没有被遍历到的部分依次放入新数组 + while (i <= middle) { + temp[index++] = arr[i++]; + } + while (j <= high) { + temp[index++] = arr[j++]; + } + + // 将合并好的新数组元素,逐个赋值给原数组对应的位置 + for (int k = 0; k < temp.length; k++) { + arr[low + k] = temp[k]; + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/QuickSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/QuickSort.java new file mode 100644 index 0000000..5f8fd10 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/QuickSort.java @@ -0,0 +1,90 @@ +package demo4; + +import java.util.Arrays; + +/** + * 快速排序 + *

+ * 1) 从数组中找出一个基准数 + * 2) 数组定义左右两个指针分别向中间移动 + * 3) 数组左侧的值比基准值大,则移到数组右侧 + * 4) 数组右侧的值比基准值小,则移到数组左侧 + * 5) 当左右两个指针重合时,当前轮排序结束 + * 6) 指针重合的位置将数组分为两部分,分别对两部分递归调用快速排序 + * 7) 重复上述步骤,直到排序完成 + * + * @author admin + */ +public class QuickSort { + public static void main(String[] args) { + // 创建数组 + int[] arr = new int[]{3, 4, 6, 7, 2, 7, 2, 8, 0, 9, 1}; + // 调用快速排序方法 + quickSort(arr, 0, arr.length - 1); + // 打印结果 + System.out.println(Arrays.toString(arr)); + } + + /** + * 时间复杂度:O(NlogN) + * 每一轮都将数组从头到尾遍历和交换,所以每轮的时间复杂度为 O(N) + * 每轮结束时,都将数组分为左右两半,再分别递归 + * 即第一轮 n/2 + * 第二轮 n/2/2 + * 直到不能再分 + * 总共进行了 logN 次减半再分别递归的操作 + * 所以时间复杂度为 O(Nlog(N)) + *

+ * 快速排序 + * + * @param arr 要排序的数组 + * @param start 起始位置 + * @param end 结束位置 + */ + public static void quickSort(int[] arr, int start, int end) { + // 如果起始位置大于或等于结束位置,结束当前方法 + if (start >= end) { + return; + } + + // 将数组中第 0 个位置的数字作为基准值 + int stard = arr[start]; + // 定义一个指针 low,从起始位置向结束位置移动 + int low = start; + // 定义一个指针 high,从结束位置向起始位置移动 + int high = end; + + // 当 low 指针小于 high 指针时 + while (low < high) { + // 从结束位置遍历 + // 如果右侧的值大于等于基准值,符合较大的值在基准值右侧的条件 + // 则将指针 high 递减,即向左移动 + while (low < high && arr[high] >= stard) { + high--; + } + // 循环结束时,说明出现了 arr[high]stard 的情况 + // 此时将比 stard 大的 arr[low] 放到 high 的位置 + arr[high] = arr[low]; + } + // 当循环结束时,low == high,左右两侧的指针重合 + // 把基准值放到 low 和 high 重合的位置 + // 则基准值左侧的数字小于等于基准值 + // 则基准值右侧的数字大于等于基准值 + // low 和 high 重合,下标用哪个都可以 + arr[low] = stard; + + // 把 stard 左右两侧切分为 2 个数组,分别递归调用快速排序方法 + quickSort(arr, start, low); + quickSort(arr, low + 1, end); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/RadixQueueSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/RadixQueueSort.java new file mode 100644 index 0000000..b481f7d --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/RadixQueueSort.java @@ -0,0 +1,133 @@ +package demo4; + +import demo2.MyQueue; + +import java.util.Arrays; + +/** + * 用队列实现基数排序 + *

+ * 思路: + * 第一轮按照所有元素的个位数字为所有元素排序 + * 第二轮按照所有元素的十位数字为所有元素排序 + * 以此类推 + * 当按照数组中元素的最大位数排序之后,最终得到 1 个有序的数组 + *

+ * 例如数组 [5, 1, 72, 36, 101] + * 为便于理解,想象元素空缺的位数上都是 0 + * 把数组写成如下形式 + * 排序前原始数组 [005, 001, 072, 036, 101] + *

+ * 第一轮排序得到 [001, 101, 072, 005, 036] + * 第一轮排序得到 [001, 101, 005, 036, 072] + * 第一轮排序得到 [001, 005, 036, 072, 101] + * 每次按照排序后,位数相同的数字,相对顺序不会改变 + * 如第一次按照个位排序后,两个个位数字 1 和 5 + * 1 在接下来的几轮排序后,总是位于 5 的前面 + * 所有排序结束后,就得到了按照数字整体大小排列的数组 + * + *

+ * 具体操作: + * 1. 为自然数 0 ~ 9 中的每个数字创建 1 个桶,总共 10 个 + *

+ * 2. 第一轮获取每个元素的个位数字,把元素放入与个位数字对应的桶中 + * 所有元素都入桶后,依次从桶中取出元素 + * 先去标号为 0 的桶中的第 1 个数字,再取第 2 个数字 + * 标号为 0 的桶取完之后,再从标号为 1 的桶取数字,以此类推 + * 按照上述顺序取出的数字,依次存入原数组第 0 个位置,第 1 个位置... + * 装满原数组后,原数组就变成了一个按照个位数字排好序的数组 + *

+ * 3. 第二轮获取每个元素的十位数字 + * 按照第二个步骤的方法操作,得到一个按十位数字排好序的数组 + *

+ * 4. 重复以上步骤,直到按照最大的位数排好序 + * 整个数组就是有序的数组 + * + * @author admin + */ +public class RadixQueueSort { + public static void main(String[] args) { + int[] arr = new int[]{23, 6, 189, 45, 9, 287, 56, 1, 798, 34, 65, 652, 5}; + radixSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 基数排序方法 + *

+ * 时间复杂度: + * 假设最大数的位数为 k,总共执行 k 轮比较 + * 每轮比较都遍历一次数组,时间复杂度为 n + * 总的时间复杂度是 O(kn) + * + * @param arr 待排序的数组 + */ + public static void radixSort(int[] arr) { + // 长度小于等于 1 的时候直接返回 + if (arr.length <= 1) { + return; + } + // 1. 计算数组中最大数的位数 + // 定义一个临时遍历 max 用于获取数组中最大的数 + int max = Integer.MIN_VALUE; + // 遍历数组,找到最大的数字 + for (int i = 0; i < arr.length; i++) { + if (arr[i] > max) { + max = arr[i]; + } + } + // 获取最大数字的位数 + int maxLength = (max + "").length(); + + // 2. 定义存放元素的桶 + // 定义一个队列数组,数组长度为 10,表示 0~9 数字对应的 10 个桶 + // 每个桶都是一个先进先出的队列 + MyQueue[] temp = new MyQueue[10]; + // 遍历队列数组 + for (int i = 0; i < temp.length; i++) { + // 数组中每个元素赋值为一个新的队列对象 + temp[i] = new MyQueue(); + } + + // 3. 遍历数组,按照每个元素各个位上的数字为数组进行多轮排序 + // 定义进位基数 10 + int scale = 10; + + // 数组中最大数字的位数是 maxLength,外循环总共循环 maxLength 轮 + // 另外定义一个除数 n,用来获取数字上每一位的数字 + // n 的初始值是 1,即取个位上的数 + // 每一轮结束都递乘 10,即第二轮 n = 10,获取十位上的数字,第三轮 n = 100,以此类推 + for (int i = 1, n = 1; i <= maxLength; i++, n *= scale) { + // 内循环遍历数组 + for (int j = 0; j < arr.length; j++) { + // 获取当前下标 j 在原数组中对应的元素 + int num = arr[j]; + // 计算元素在当前位上的余数 + // 第一轮,i=1, n = 1,((num / 1) % 10) 得到个位上的数字 + // 第二轮,i=2, n = 10,((num / 10) % 10) 得到十位上的数字 + // 依次类推 + int remainder = (num / n) % 10; + // 通过余数 remainder 获取对应数字的桶 + MyQueue bucket = temp[remainder]; + // 将当前元素存入桶中 + bucket.add(num); + } + + // 记录原数组的下标变化,从桶中取出元素放回原数组时,下标递增 + int index = 0; + // 遍历队列数组 + for (int k = 0; k < temp.length; k++) { + // 通过 k 获取对应的桶 + MyQueue bucket = temp[k]; + // 只要桶不为空,就继续遍历 + while (!bucket.isEmpty()) { + // 桶中的元素出列,放入原数组,同时原数组下标 index 递增 + arr[index++] = bucket.poll(); + } + } + System.out.println(Arrays.toString(arr)); + + } + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/RadixSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/RadixSort.java new file mode 100644 index 0000000..a09eaaa --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/RadixSort.java @@ -0,0 +1,138 @@ +package demo4; + +import java.util.Arrays; + +/** + * 基数排序 + *

+ * 思路: + * 第一轮按所有元素的个位数字排序 + * 第二轮按所有元素的十位数字排序 + * 以此类推 + * 当按照数组中元素的最大位数排序之后,最终得到 1 个有序的数组 + *

+ * 例如数组 [5, 1, 72, 36, 101] + * 为便于理解,想象元素空缺的位数上都是 0 + * 把数组写成如下形式 + * 排序前原始数组 [005, 001, 072, 036, 101] + *

+ * 第一轮按个位排序得到 [001, 101, 072, 005, 036] + * 第二轮按十位排序得到 [001, 101, 005, 036, 072] + * 第三轮按百位排序得到 [001, 005, 036, 072, 101] + * 每轮排序后,位数相同的数字,相对顺序不会改变 + * 如第一次按照个位排序后,两个个位数字 1 和 5 + * 1 在接下来的几轮排序过程中,总是位于 5 的前面 + * 所有排序结束后,就得到了按照数字整体大小排列的数组 + * + *

+ * 具体操作: + * 1. 为自然数 0 ~ 9 中的每个数字创建 1 个桶,总共 10 个 + *

+ * 2. 第一轮获取每个元素的个位数字,把元素放入与个位数字对应的桶中 + * 所有元素都入桶后,依次从桶中取出元素 + * 先取标号为 0 的桶中的第 1 个数字,再取第 2 个数字 ... + * 标号为 0 的桶取完之后,再从标号为 1 的桶取数字,以此类推 + * 按照上述顺序取出的数字,依次存入原数组第 0 个位置,第 1 个位置 ... + * 装满原数组后,原数组就变成了一个按照个位数字排好序的数组 + *

+ * 3. 第二轮获取每个元素的十位数字 + * 按照第二个步骤的方法操作,得到一个按十位数字排好序的数组 + *

+ * 4. 重复以上步骤,直到按照最大的位数排好序 + * 整个数组就是有序的数组 + * + * @author admin + */ +public class RadixSort { + public static void main(String[] args) { + int[] arr = new int[]{23, 6, 189, 45, 9, 287, 56, 1, 798, 34, 65, 652, 5}; + radixSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 基数排序方法 + *

+ * 时间复杂度: + * 假设最大数的位数为 k,总共执行 k 轮比较 + * 每轮比较都遍历一次数组,时间复杂度为 n + * 总的时间复杂度是 O(kn) + * + * @param arr + */ + public static void radixSort(int[] arr) { + // 长度小于等于 1 的时候直接返回 + if (arr.length <= 1) { + return; + } + // 1. 计算数组中最大数的位数 + // 定义一个临时变量 max 用于获取数组中最大的数 + int max = Integer.MIN_VALUE; + // 遍历数组,找到最大的数字 + for (int i = 0; i < arr.length; i++) { + if (arr[i] > max) { + max = arr[i]; + } + } + // 获取最大数字的位数 + int maxLength = (max + "").length(); + + // 2. 定义一个 10 行 arr.length 列的二维数组 + // 行数为 10,表示 0~9 数字对应的 10 个桶 + // 列数为 arr.length,考虑到所有元素都在同一个桶中的极端情况 + // 每个桶的容量都需要与数组的长度相等 + int[][] temp = new int[10][arr.length]; + + // 定义一个用于计数的数组 + // 数组中每个元素的数值,代表对应的桶中有多少个元素 + int[] count = new int[10]; + + // 3. 遍历数组,按照每个元素各个位上的数字为数组进行多轮排序 + // 定义进位基数 10 + int scale = 10; + // 数组中最大数字的位数是 maxLength,外循环总共循环 maxLength 轮 + // 另外定义一个除数 n,用来获取数字上每一位的数字 + // n 的初始值是 1,即取个位上的数 + // 每一轮结束都递乘 10,即第二轮 n = 10,获取十位上的数字,第三轮 n = 100,以此类推 + for (int i = 0, n = 1; i < maxLength; i++, n *= scale) { + + // 内循环遍历数组 + for (int j = 0; j < arr.length; j++) { + // 获取当前下标 j 在原数组中对应的元素 + int num = arr[j]; + // 计算元素在当前位上的余数 + // 第一轮,i=1, n = 1,((num / 1) % 10) 得到个位上的数字 + // 第二轮,i=2, n = 10,((num / 10) % 10) 得到十位上的数字 + // 以此类推 + int remainder = (num / n) % 10; + + // 通过余数 remainder 获取对应数字的桶 temp[remainder] + // 向桶中添加当前元素,同时桶对应的计数器 count[remainder] 递增 + temp[remainder][count[remainder]++] = num; + } + + // 记录原数组的下标变化,从桶中取出元素放回原数组时,下标递增 + int index = 0; + // 遍历计数器数组 + for (int k = 0; k < count.length; k++) { + // 获取 k 值对应的桶中有多少个元素 + int volume = count[k]; + // 只要计数器不为 0,说明桶中还有元素 + if (volume > 0) { + // 获取 k 值对应的桶 + int[] bucket = temp[k]; + // 桶内有 volume 个元素,则 l 正好对应下标 0 ~ volume-1 + for (int l = 0; l < volume; l++) { + // 通过下标 l 获取桶内的元素 bucket[l] + // 将桶内元素 bucket[l] 赋值给原数组相应的位置 + arr[index++] = bucket[l]; + // index++ 指针指向下一个位置 + } + // 循环结束后,将当前桶的计数器清零 + count[k] = 0; + } + } + } + } + +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/SelectionSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/SelectionSort.java new file mode 100644 index 0000000..7cce7db --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/SelectionSort.java @@ -0,0 +1,60 @@ +package demo4; + +import java.util.Arrays; + +/** + * 选择排序 + *

+ * 将数组看作有序和无序两部分 + * 每次都从无序部分找出最小的元素,与无序部分的第一个元素交换位置 + * 直到数组完全排序为止 + * + * @author admin + */ +public class SelectionSort { + public static void main(String[] args) { + int[] arr = new int[]{3, 4, 5, 7, 1, 2, 0, 3, 6, 8}; + selectionSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 选择排序方法 + * 时间复杂度: + * 内循环每次都会从无序部分找出最小的元素 + * 依次比较了 n-1 次,n-2 次,n-3 次 ... 1 次 + * 总共比较的次数是 (n-1) + (n-2) + ...+ 1 = (n-1 + 1) /2 = n/2 次 + * 外循环执行了 n 次,总共的时间复杂度是 O(n*n/2) = O(n^2/2) = O(n^2) + * + * @param arr + */ + public static void selectionSort(int[] arr) { + // 当数组元素小于等于 1 时,天然有序,无需进行排序 + if (arr.length <= 1) { + return; + } + // 遍历数组 + for (int i = 0; i < arr.length; i++) { + int minIndex = i; + for (int j = i + 1; j < arr.length; j++) { + // 如果内循环当前元素 arr[j] 比已知最小值还小 + // 则将最小值下标 minIndex 替换为 j + if (arr[j] < arr[minIndex]) { + minIndex = j; + } + } + // 内循环结束时 + // 未排序部分第一个元素是 arr[i] + // 未排序部分最小元素是 arr[minIndex] + // 如果 i 与 minIndex 不相等 + // 则需要交换两者的值 + // 让未排序部分的最小元素排到未排序部分的第一个元素位置 + if (i != minIndex) { + // 交换两者的位置 + int temp = arr[i]; + arr[i] = arr[minIndex]; + arr[minIndex] = temp; + } + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo4/ShellSort.java b/codes/java_dataStructure_luozhaoyong/src/demo4/ShellSort.java new file mode 100644 index 0000000..3111795 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo4/ShellSort.java @@ -0,0 +1,56 @@ +package demo4; + +import java.util.Arrays; + +/** + * 希尔排序 + *

+ * 取某个数字作为步长,按步长对数组进行插入排序 + * 排序完成后,步长按规律递减 + * 用新步长进行下一轮插入排序 + * 重复上述步骤,直到步长变成 1,进行最后一轮普通的插入排序为止 + * + * @author admin + */ +public class ShellSort { + public static void main(String[] args) { + int[] arr = new int[]{3, 5, 2, 7, 8, 1, 2, 0, 4, 7, 4, 3, 8}; + shellSort(arr); + System.out.println(Arrays.toString(arr)); + } + + /** + * 希尔排序方法 + * 数组完全逆序时,接近插入排序的时间复杂度 O(n^2) + * 最优时间复杂度,约为 O(n^1.3) + * + * @param arr + */ + public static void shellSort(int[] arr) { + // 用于记录当前排序次数,与主逻辑无关,仅用于打印结果 + int k = 1; + + // 除数设定为 2,每次步长都是上一次的 1/2 + int divisor = 2; + // 遍历所有步长的情况 + for (int d = arr.length / divisor; d > 0; d /= divisor) { + // 外循环控制变量 i 起始位置为 d + // d 是规定的步长,当 d ==1 时,就变成了插入排序 + for (int i = d; i < arr.length; i++) { + // 内循环控制变量 j + for (int j = i - d; j >= 0; j -= d) { + // 如果 arr[j] 比更靠后的元素 arr[j+d] 大 + // 则交换两者位置,保持前面数字更小的顺序 + if (arr[j] > arr[j + d]) { + // 交换 arr[j] 和 arr[j+d] 的位置 + int temp = arr[j]; + arr[j] = arr[j + d]; + arr[j + d] = temp; + } + } + } + System.out.println("第 " + k + " 次排序结果 " + Arrays.toString(arr)); + k++; + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo5/BinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo5/BinaryTree.java new file mode 100644 index 0000000..39fc877 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo5/BinaryTree.java @@ -0,0 +1,81 @@ +package demo5; + +/** + * 二叉树 + * @author admin + */ +public class BinaryTree { + /** + * 根结点 + */ + TreeNode root; + + + /** + * 设置根结点 + * + * @param node 节点参数 + */ + public void setRoot(TreeNode node) { + root = node; + } + + /** + * 前序遍历 + */ + public void frontShow() { + if (root == null) { + System.out.println("树为空"); + return; + } + // 调用根结点的前序遍历方法 + root.frontShow(); + // 打印一个空行,与主逻辑无关 + System.out.println(); + } + + /** + * 中序遍历 + */ + public void midShow() { + if (root == null) { + return; + } + root.midShow(); + System.out.println(); + } + + /** + * 后序遍历 + */ + public void afterShow() { + if (root == null) { + return; + } + root.afterShow(); + System.out.println(); + } + + /** + * 前序查找 + * + * @param i + * @return + */ + public TreeNode frontSearch(int i) { + return root.frontSearch(i); + } + + /** + * 删除方法 + * + * @param i + */ + public void delete(int i) { + if (root.value == i) { + root = null; + return; + } + root.delete(i); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo5/TestBinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo5/TestBinaryTree.java new file mode 100644 index 0000000..e008d7c --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo5/TestBinaryTree.java @@ -0,0 +1,58 @@ +package demo5; + +/** + * 测试二叉树 + * @author admin + */ +public class TestBinaryTree { + public static void main(String[] args) { + /* 第 30 课,创建二叉树*/ + // 创建一棵二叉树 + BinaryTree binTree = new BinaryTree(); + + // 创建一个节点作为根结点 + TreeNode root = new TreeNode(1); + // 设置根结点 + binTree.setRoot(root); + + // 创建一个左节点 + TreeNode leftNode = new TreeNode(2); + // 设置左节点 + root.setLeftNode(leftNode); + + // 创建一个右节点 + TreeNode rightNode = new TreeNode(3); + // 设置右节点 + root.setRightNode(rightNode); + + /* 第 31 课,遍历二叉树*/ + + // 为第二层的左节点创建左右两个子节点 + leftNode.setLeftNode(new TreeNode(4)); + leftNode.setRightNode(new TreeNode(5)); + + // 为第二层的右节点创建左右两个子节点 + rightNode.setLeftNode(new TreeNode(6)); + rightNode.setRightNode(new TreeNode(7)); + + // 调用前序遍历方法 + binTree.frontShow(); + + // 调用中序遍历方法 + binTree.midShow(); + + // 调用后序遍历方法 + binTree.afterShow(); + + // 调用前序查找方法,查找节点值为 2 的节点 + TreeNode result = binTree.frontSearch(2); + // 检查当前结果是否为根结点的左子节点 + System.out.println(result == leftNode); + + // 测试删除节点的方法 + binTree.delete(5); + // 前序遍历显示节点是否被删除 + // 打印结果是 1 2 4 3 6 7 + binTree.frontShow(); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo5/TreeNode.java b/codes/java_dataStructure_luozhaoyong/src/demo5/TreeNode.java new file mode 100644 index 0000000..2fa8943 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo5/TreeNode.java @@ -0,0 +1,162 @@ +package demo5; + +/** + * 二叉树节点 + * @author admin + */ +public class TreeNode { + /** + * 节点的权值 + */ + int value; + /** + * 左节点 + */ + TreeNode leftNode; + /** + * 右节点 + */ + TreeNode rightNode; + + /** + * 构造方法 + * + * @param value 权值参数 + */ + public TreeNode(int value) { + this.value = value; + } + + public void setLeftNode(TreeNode node) { + leftNode = node; + } + + public void setRightNode(TreeNode node) { + rightNode = node; + } + + /** + * 前序遍历 + *

+ * 当前节点-->左子节点-->右子节点 + */ + public void frontShow() { + // 获取当前节点的值 + System.out.print(value + " "); + // 获取左子节点的值 + if (leftNode != null) { + leftNode.frontShow(); + } + // 获取右子节点的值 + if (rightNode != null) { + rightNode.frontShow(); + } + } + + /** + * 中序遍历 + *

+ * 左子节点-->当前节点-->右子节点 + */ + public void midShow() { + // 获取左子节点的值 + if (leftNode != null) { + leftNode.midShow(); + } + + // 获取当前节点的值 + System.out.print(value + " "); + + // 获取右子节点的值 + if (rightNode != null) { + rightNode.midShow(); + } + } + + /** + * 后序遍历 + *

+ * 左子节点-->右子节点-->当前节点 + */ + public void afterShow() { + // 获取左子节点的值 + if (leftNode != null) { + leftNode.afterShow(); + } + + // 获取右子节点的值 + if (rightNode != null) { + rightNode.afterShow(); + } + + // 获取当前节点的值 + System.out.print(value + " "); + } + + /** + * 前序查找 + * + * @return + */ + public TreeNode frontSearch(int i) { + // 定义一个变量作为返回值 + TreeNode target = null; + // 查看当前值是否与目标值相等 + if (value == i) { + return this; + } + // 如果左子节点不为空 + if (leftNode != null) { + // 在左子节点递归调用当前查找方法 + target = leftNode.frontSearch(i); + } + // 如果左子节点查找结果不为空 + if (target != null) { + // 返回结果 + return target; + } + // 如果右子节点不为空 + if (rightNode != null) { + // 在右子节点递归调用当前查找方法 + target = rightNode.frontSearch(i); + } + // 返回目标结果 + return target; + } + + /** + * 递归删除子树 + * + * @param i + */ + public void delete(int i) { + // 将当前节点作为父节点赋值给变量 parent + TreeNode parent = this; + // 左子节点的值等于指定值,则删除左子节点 + if (parent.leftNode != null && parent.leftNode.value == i) { + // 将左子节点赋值为空,即删除了左子节点 + parent.leftNode = null; + return; + } + // 右子节点的值等于指定值,则删除左子节点 + if (parent.rightNode != null && parent.rightNode.value == i) { + // 将右子节点赋值为空,即删除了左子节点 + parent.rightNode = null; + return; + } + // 将左子节点赋值给父节点变量 + parent = leftNode; + // 如果节点不为空 + if (parent != null) { + // 递归调用删除方法 + parent.delete(i); + } + // 将右子节点赋值给父节点变量 + parent = rightNode; + // 如果节点不为空 + if (parent != null) { + // 递归调用删除方法 + parent.delete(i); + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo6/ArrayBinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo6/ArrayBinaryTree.java new file mode 100644 index 0000000..7e30868 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo6/ArrayBinaryTree.java @@ -0,0 +1,58 @@ +package demo6; + +/** + * 顺序存储二叉树 + * + * @author admin + */ +public class ArrayBinaryTree { + /** + * 数据以数组的形式来存储 + */ + int[] data; + + /** + * 构造方法 + * + * @param data 指定数组参数 + */ + public ArrayBinaryTree(int[] data) { + this.data = data; + } + + /** + * 从根结点开始前序遍历 + */ + public void frontShow() { + // 传入根结点下标 0 + frontShow(0); + } + + /** + * 前序遍历 + * + * @param index 起点的下标 + */ + public void frontShow(int index) { + // 检查边际条件 + if (data == null || data.length == 0) { + return; + } + // 获取当前节点的值 + System.out.print(data[index] + " "); + // 获取左子节点下标 + int leftIndex = index * 2 + 1; + // 处理左子节点 + if (leftIndex < data.length) { + // 左子节点递归调用前序遍历方法 + frontShow(leftIndex); + } + // 获取右子节点下标 + int rightIndex = index * 2 + 2; + // 处理右子节点 + if (rightIndex < data.length) { + // 右子节点递归调用前序遍历方法 + frontShow(rightIndex); + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo6/TestArrayBinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo6/TestArrayBinaryTree.java new file mode 100644 index 0000000..8d86292 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo6/TestArrayBinaryTree.java @@ -0,0 +1,18 @@ +package demo6; + +/** + * 测试顺序存储二叉树 + * @author admin + */ +public class TestArrayBinaryTree { + public static void main(String[] args) { + // 创建数组 + int[] data = new int[]{1, 2, 3, 4, 5, 6, 7}; + // 创建顺序存储二叉树对象 + ArrayBinaryTree binTree = new ArrayBinaryTree(data); + + // 调用前序遍历方法 + // 打印结果是 1 2 4 5 3 6 7 + binTree.frontShow(); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo7/TestThreadedBinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo7/TestThreadedBinaryTree.java new file mode 100644 index 0000000..96390cf --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo7/TestThreadedBinaryTree.java @@ -0,0 +1,57 @@ +package demo7; + + +/** + * 测试线索二叉树 + * @author admin + */ +public class TestThreadedBinaryTree { + public static void main(String[] args) { + /* 第 30 课,创建二叉树*/ + // 创建一棵二叉树 + ThreadedBinaryTree binTree = new ThreadedBinaryTree(); + + // 创建一个节点作为根结点 + ThreadedNode root = new ThreadedNode(1); + // 设置根结点 + binTree.setRoot(root); + + // 创建一个左节点 + ThreadedNode leftNode = new ThreadedNode(2); + // 设置左节点 + root.setLeftNode(leftNode); + + /* 第 31 课,遍历二叉树*/ + // 创建一个右节点 + ThreadedNode rightNode = new ThreadedNode(3); + // 设置右节点 + root.setRightNode(rightNode); + + // 为第二层的左节点创建左右两个子节点 + leftNode.setLeftNode(new ThreadedNode(4)); + ThreadedNode fiveNode = new ThreadedNode(5); + leftNode.setRightNode(fiveNode); + + // 为第二层的右节点创建左右两个子节点 + rightNode.setLeftNode(new ThreadedNode(6)); + rightNode.setRightNode(new ThreadedNode(7)); + + // 调用中序遍历方法 + // 执行结果:4 2 5 1 6 3 7 + binTree.midShow(); + + // 中序线索化二叉树 + binTree.threadNodes(); + + // 找到节点 5 的后继节点 + ThreadedNode afterFive = fiveNode.rightNode; + // 打印后继节点的值 + // 执行结果为 1 + System.out.println(afterFive.value); + + // 线索化二叉树之后,遍历所有节点 + // 执行结果:4 2 5 1 6 3 7 + binTree.threadIterate(); + + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedBinaryTree.java b/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedBinaryTree.java new file mode 100644 index 0000000..8cb26ed --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedBinaryTree.java @@ -0,0 +1,169 @@ +package demo7; + +/** + * 线索二叉树 + * @author admin + */ +public class ThreadedBinaryTree { + /** + * 根结点 + */ + ThreadedNode root; + + /** + * 临时存储前驱节点 + */ + ThreadedNode pre; + + /** + * 中序遍历线索化二叉树 + */ + public void threadIterate() { + // 定义临时变量 node 记录当前节点 + ThreadedNode node = root; + // node 不为空时 + while (node != null) { + // 1. 中序遍历,向左查找第一个被线索化的节点 + // 跳过所有没有线索化的节点,即所有 leftType == 0 的节点 + // 直至找到第一个线索化的节点,即 leftType == 1 的节点 + while (node.leftType == 0) { + // node 指针前移 + node = node.leftNode; + } + + // 2. 通过线索化不断打印后继节点的值 + // while 循环结束后, node 指向的节点就是当前第一个线索化的节点 + // 打印节点的值 + System.out.print(node.value + " "); + + // 循环查找后继节点 + while (node.rightType == 1) { + // 指针后移 + node = node.rightNode; + // 打印后继节点的值 + System.out.print(node.value + " "); + } + // 上个 while 循环结束后 + // 当前有效范围内的所有线索化的节点都已经遍历过 + // 3. 指针后移到右子节点,在下一个有效范围内查找线索化的节点 + node = node.rightNode; + } + } + + /** + * 设置根结点 + * + * @param node 节点参数 + */ + public void setRoot(ThreadedNode node) { + root = node; + } + + /** + * 对根结点应用线索化二叉树方法 + */ + public void threadNodes() { + threadNodes(root); + } + + /** + * 中序遍历 + * 线索化二叉树方法 + * + * @param node + */ + public void threadNodes(ThreadedNode node) { + // 如果节点为空 + if (node == null) { + // 返回不做处理 + return; + } + + // 对左节点递归调用当前方法 + threadNodes(node.leftNode); + + // 对当前节点进行处理 + // 如果左子树为空 + if (node.leftNode == null) { + // 将左指针指向前驱节点 + node.leftNode = pre; + // 改变标识,1 表示 leftNode 指向前驱节点 + node.leftType = 1; + } + + // 中序遍历时,pre 的后继节点就是当前节点 + // 如果前驱节点的右子树为空 + if (pre != null && pre.rightNode == null) { + // 将前驱节点的右指针指向当前节点 + pre.rightNode = node; + // 改变标识,1 表示 rightNode 指向后继节点 + pre.rightType = 1; + } + + // 将当前节点的值赋给前驱节点变量 pre + pre = node; + + // 对右节点递归调用当前方法 + threadNodes(node.rightNode); + } + + + /** + * 前序遍历 + */ + public void frontShow() { + if (root == null) { + System.out.println("树为空"); + return; + } + // 调用根结点的前序遍历方法 + root.frontShow(); + // 打印一个空行,与主逻辑无关 + System.out.println(); + } + + /** + * 中序遍历 + */ + public void midShow() { + if (root == null) { + return; + } + root.midShow(); + System.out.println(); + } + + /** + * 后序遍历 + */ + public void afterShow() { + if (root == null) { + return; + } + root.afterShow(); + System.out.println(); + } + + /** + * 前序查找 + * + * @param i + * @return + */ + public ThreadedNode frontSearch(int i) { + return root.frontSearch(i); + } + + /** + * 删除方法 + * + * @param i + */ + public void delete(int i) { + if (root.value == i) { + root = null; + return; + } + root.delete(i); + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedNode.java b/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedNode.java new file mode 100644 index 0000000..11bcb5d --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo7/ThreadedNode.java @@ -0,0 +1,175 @@ +package demo7; + +/** + * 定义线索二叉树的节点 + * + * @author admin + */ +public class ThreadedNode { + /** + * 节点的权值 + */ + int value; + /** + * 左节点 + */ + ThreadedNode leftNode; + /** + * 右节点 + */ + ThreadedNode rightNode; + + /** + * 标识左指针类型 + */ + int leftType; + + /** + * 标识右指针类型 + */ + int rightType; + + + + /** + * 构造方法 + * + * @param value 权值参数 + */ + public ThreadedNode(int value) { + this.value = value; + } + + public void setLeftNode(ThreadedNode node) { + leftNode = node; + } + + public void setRightNode(ThreadedNode node) { + rightNode = node; + } + + /** + * 前序遍历 + *

+ * 当前节点-->左子节点-->右子节点 + */ + public void frontShow() { + // 获取当前节点的值 + System.out.print(value + " "); + // 获取左子节点的值 + if (leftNode != null) { + leftNode.frontShow(); + } + // 获取右子节点的值 + if (rightNode != null) { + rightNode.frontShow(); + } + } + + /** + * 中序遍历 + *

+ * 左子节点-->当前节点-->右子节点 + */ + public void midShow() { + // 获取左子节点的值 + if (leftNode != null) { + leftNode.midShow(); + } + + // 获取当前节点的值 + System.out.print(value + " "); + + // 获取右子节点的值 + if (rightNode != null) { + rightNode.midShow(); + } + } + + /** + * 后序遍历 + *

+ * 左子节点-->右子节点-->当前节点 + */ + public void afterShow() { + // 获取左子节点的值 + if (leftNode != null) { + leftNode.afterShow(); + } + + // 获取右子节点的值 + if (rightNode != null) { + rightNode.afterShow(); + } + + // 获取当前节点的值 + System.out.print(value + " "); + } + + /** + * 前序查找 + * + * @return + */ + public ThreadedNode frontSearch(int i) { + // 定义一个变量作为返回值 + ThreadedNode target = null; + // 查看当前值是否与目标值相等 + if (value == i) { + return this; + } + // 如果左子节点不为空 + if (leftNode != null) { + // 在左子节点递归调用当前查找方法 + target = leftNode.frontSearch(i); + } + // 如果左子节点查找结果不为空 + if (target != null) { + // 返回结果 + return target; + } + // 如果右子节点不为空 + if (rightNode != null) { + // 在右子节点递归调用当前查找方法 + target = rightNode.frontSearch(i); + } + // 返回目标结果 + return target; + } + + /** + * 递归删除子树 + * + * @param i + */ + public void delete(int i) { + // 将当前节点作为父节点赋值给变量 parent + ThreadedNode parent = this; + // 左子节点的值等于指定值,则删除左子节点 + if (parent.leftNode != null && parent.leftNode.value == i) { + // 将左子节点赋值为空,即删除了左子节点 + parent.leftNode = null; + return; + } + // 右子节点的值等于指定值,则删除左子节点 + if (parent.rightNode != null && parent.rightNode.value == i) { + // 将右子节点赋值为空,即删除了左子节点 + parent.rightNode = null; + return; + } + // 将左子节点赋值给父节点变量 + parent = leftNode; + // 如果节点不为空 + if (parent != null) { + // 递归调用删除方法 + parent.delete(i); + } + // 将右子节点赋值给父节点变量 + parent = rightNode; + // 如果节点不为空 + if (parent != null) { + // 递归调用删除方法 + parent.delete(i); + } + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo9/Node.java b/codes/java_dataStructure_luozhaoyong/src/demo9/Node.java new file mode 100644 index 0000000..c4050e9 --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo9/Node.java @@ -0,0 +1,48 @@ +package demo9; + +/** + * 定义赫夫曼树的节点 + * + * @author admin + */ +public class Node implements Comparable { + /** + * 权值 + */ + int value; + /** + * 左子节点 + */ + Node left; + /** + * 右子节点 + */ + Node right; + + public Node(int value) { + this.value = value; + } + + /** + * 覆写 compareTo 方法 + * + * @param o 用于对比的目标节点 + * @return + */ + @Override + public int compareTo(Node o) { + // 返回倒序结果,让根结点权值较大的二叉树排在前面 + return o.value - this.value; + } + + /** + * 覆写 toString 方法 + * @return + */ + @Override + public String toString() { + return "Node{" + + "value=" + value + + '}'; + } +} diff --git a/codes/java_dataStructure_luozhaoyong/src/demo9/TestHuffmanTree.java b/codes/java_dataStructure_luozhaoyong/src/demo9/TestHuffmanTree.java new file mode 100644 index 0000000..970105b --- /dev/null +++ b/codes/java_dataStructure_luozhaoyong/src/demo9/TestHuffmanTree.java @@ -0,0 +1,63 @@ +package demo9; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * 测试赫夫曼树 + * @author admin + */ +public class TestHuffmanTree { + + public static void main(String[] args) { + int[] arr = new int[]{3, 7, 8, 29, 5, 11, 23, 14}; + Node node = createHuffmanTree(arr); + System.out.println(node); + } + + /** + * 创建赫夫曼树 + * + * @param arr 整数数组 + * @return + */ + public static Node createHuffmanTree(int[] arr) { + // 创建一个列表用于存储二叉树节点 + List nodes = new ArrayList<>(); + // 1. 将整数数组中的元素转化为二叉树 + for (int value : arr) { + // 用 value 作为权值 + // 创建二叉树节点并存入 nodes 列表中 + nodes.add(new Node(value)); + } + + // 当 nodes 列表的元素数目大于 1 时循环执行 + while (nodes.size() > 1) { + // 2. 根据二叉树根结点的权值进行倒序排列 + Collections.sort(nodes); + // 3. 从 nodes 列表中取出根结点权值最小的两个元素 + // 因为是倒序排列,依次取出倒数第 1 个和倒数第 2 个 + // 倒数第 1 个元素作为左子节点 + Node left = nodes.get(nodes.size() - 1); + // 倒数第 2 个元素作为右子节点 + Node right = nodes.get(nodes.size() - 2); + // 4. 创建一个新二叉树,新二叉树根结点的权值是上述两个节点权值的和 + Node parent = new Node(left.value + right.value); + // 5. 新节点与孩子节点建立连接 + // 这一步骤在本节课的课程视频中没有出现,不影响最终结果 + parent.left = left; + parent.right = right; + // 6. 从原有列表中移除刚才使用过的两个权值最小节点 + nodes.remove(left); + nodes.remove(right); + // 7. 将新元素加入 nodes 列表 + nodes.add(parent); + } + // 循环中每次移除 2 个元素,增加 1 个元素 + // 总体元素数量随着循环递减 + // 循环结束后,nodes 列表中只剩下 1 个元素 + // 返回 nodes 列表中的元素 + return nodes.get(0); + } +} diff --git a/solutions/README.md b/solutions/README.md new file mode 100644 index 0000000..ac5cec1 --- /dev/null +++ b/solutions/README.md @@ -0,0 +1,2156 @@ + +### 算法每日一练 + +* 这个专栏是Hollis知识星球的朋友们练习算法的地方,同时也欢迎广大网友参与 +* 所有题目来源是[leetCode](https://leetcode-cn.com/problemset/all/)官方公开题库 + +### 初学者友好的算法题目解答 + +* 算法解答部分的代码注释细致到每一行 +* 希望能为初学者提供最大的便利去理解每道题目和解法 +* 欢迎网友为本项目做贡献,提交你的解题方法和详细解释 + +--- + +### 专题列表 +* 2018年11月27日~2019年01月16日 +>[《算法面试通关40讲》专题](https://time.geekbang.org/course/intro/130) +>[《算法面试通关40讲》官方课件](https://github.com/geektime-geekbang/algorithm-1) + +* 2018年11月16日 +>LeetCode动态规划专题 + +--- + +专题(Begin):《算法面试40讲》 +--- + +2018年11月27日 + +[206. 反转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/206-reverseLinkedList) + +[https://leetcode-cn.com/problems/reverse-linked-list/](https://leetcode-cn.com/problems/reverse-linked-list/) + +英文官方题解: + +[https://leetcode.com/articles/reverse-linked-list/](https://leetcode.com/articles/reverse-linked-list/) + +知识点:数组、链表 + +难度:简单 + +--- + +2018年11月28日 + +[24. 两两交换链表中的节点](https://github.com/hollischuang/algorithm/tree/master/leetcode/024-swapNodesInPairs) + +[https://leetcode-cn.com/problems/swap-nodes-in-pairs/](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) + +无官方题解,网友最高票Java解法: + +[https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.](https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11030/My-accepted-java-code.-used-recursion.) + +知识点:数组、链表 + +难度:中等 + +--- + +2018年11月29日 + +[141. 环形链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/141-linkedListCycle) + +[https://leetcode-cn.com/problems/linked-list-cycle/](https://leetcode-cn.com/problems/linked-list-cycle/) + +官方题解: + +[https://leetcode-cn.com/articles/linked-list-cycle/](https://leetcode-cn.com/articles/linked-list-cycle/) + +知识点:数组、链表 + +难度:简单 + +--- + +2018年11月30日 + +[142. 环形链表 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/142-linkedListCycleII) + +[https://leetcode-cn.com/problems/linked-list-cycle-ii/](https://leetcode-cn.com/problems/linked-list-cycle-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.](https://leetcode.com/problems/linked-list-cycle-ii/discuss/44774/Java-O(1)-space-solution-with-detailed-explanation.) + +知识点:数组、链表 + +难度:中等 + +--- + +2018年12月01日 + +[25. k个一组翻转链表](https://github.com/hollischuang/algorithm/tree/master/leetcode/025-reverseNodesInKGroup) + +[https://leetcode-cn.com/problems/reverse-nodes-in-k-group/](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments](https://leetcode.com/problems/reverse-nodes-in-k-group/discuss/11423/Short-but-recursive-Java-code-with-comments) + +知识点:数组、链表 + +难度:困难 + +--- + +2018年12月02日 + +[20. 有效的括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/020-validParentheses) + +[https://leetcode-cn.com/problems/valid-parentheses/](https://leetcode-cn.com/problems/valid-parentheses/) + +官方题解: + +[https://leetcode-cn.com/articles/valid-parentheses/](https://leetcode-cn.com/articles/valid-parentheses/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月03日 + +[232. 用栈实现队列](https://github.com/hollischuang/algorithm/tree/master/leetcode/232-implementQueueUsingStacks) + +[https://leetcode-cn.com/problems/implement-queue-using-stacks/](https://leetcode-cn.com/problems/implement-queue-using-stacks/) + +英文官方题解: + +[https://leetcode.com/articles/implement-queue-using-stacks/](https://leetcode.com/articles/implement-queue-using-stacks/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月04日 + +[225. 用队列实现栈](https://github.com/hollischuang/algorithm/tree/master/leetcode/225-implementStackUsingQueues) + +[https://leetcode-cn.com/problems/implement-stack-using-queues/](https://leetcode-cn.com/problems/implement-stack-using-queues/) + +英文官方题解: + +[https://leetcode.com/articles/implement-stack-using-queues/](https://leetcode.com/articles/implement-stack-using-queues/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月05日 + +[844. 比较含退格的字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/844-BackspaceStringCompare) + +[https://leetcode-cn.com/problems/backspace-string-compare/](https://leetcode-cn.com/problems/backspace-string-compare/) + +英文官方题解: + +[https://leetcode.com/articles/backspace-string-compare/](https://leetcode.com/articles/backspace-string-compare/) + +知识点:堆栈、队列 + +难度:简单 + +--- + +2018年12月06日 + +[703. 数据流中的第K大元素](https://github.com/hollischuang/algorithm/tree/master/leetcode/703-KthLargestElementInAStream) + +[https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue](https://leetcode.com/problems/kth-largest-element-in-a-stream/discuss/149050/Java-Priority-Queue) + +知识点:优先队列 + +难度:简单 + +--- + +2018年12月07日 + +[692. 前K个高频单词](https://github.com/hollischuang/algorithm/tree/master/leetcode/692-TopKFrequentWords) + +[https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) + +英文官方题解: + +[https://leetcode.com/articles/top-k-frequent-words/](https://leetcode.com/articles/top-k-frequent-words/) + +知识点:优先队列 + +难度:中等 + +--- + +2018年12月08日 + +[239. 滑动窗口最大值](https://github.com/hollischuang/algorithm/tree/master/leetcode/239-slidingWindowMaximum) + +[https://leetcode-cn.com/problems/sliding-window-maximum/](https://leetcode-cn.com/problems/sliding-window-maximum/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation](https://leetcode.com/problems/sliding-window-maximum/discuss/65884/Java-O(n)-solution-using-deque-with-explanation) + +知识点:优先队列 + +难度:困难 + +--- + +2018年12月09日 + +[242. 有效的字母异位词](https://github.com/hollischuang/algorithm/tree/master/leetcode/242-ValidAnagram) + +[https://leetcode-cn.com/problems/valid-anagram/](https://leetcode-cn.com/problems/valid-anagram/) + +英文官方题解: + +[https://leetcode.com/articles/valid-anagram/](https://leetcode.com/articles/valid-anagram/) + +知识点:哈希表和集合 + +难度:简单 + +--- + +2018年12月10日 + +[1. 两数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/001-twoSum) + +[https://leetcode-cn.com/problems/two-sum/](https://leetcode-cn.com/problems/two-sum/) + +官方题解: + +[https://leetcode-cn.com/articles/two-sum/](https://leetcode-cn.com/articles/two-sum/) + +知识点:哈希表和集合 + +难度:简单 + +--- + +2018年12月11日 + +[15. 三数之和](https://github.com/hollischuang/algorithm/tree/master/leetcode/015-threeSum) + +[https://leetcode-cn.com/problems/3sum/](https://leetcode-cn.com/problems/3sum/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution](https://leetcode.com/problems/3sum/discuss/7380/Concise-O(N2)-Java-solution) + +知识点:哈希表和集合 + +难度:中等 + +--- + +2018年12月12日 + +[98. 验证二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/098-validateBinarySearchTree) + +[https://leetcode-cn.com/problems/validate-binary-search-tree/](https://leetcode-cn.com/problems/validate-binary-search-tree/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)](https://leetcode.com/problems/validate-binary-search-tree/discuss/32112/Learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-(Java-Solution)) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines](https://leetcode.com/problems/validate-binary-search-tree/discuss/32109/My-simple-Java-solution-in-3-lines) + +知识点:树、二叉树、二叉搜索树 + +难度:中等 + +--- + +2018年12月13日 + +[236. 二叉树的最近公共祖先](https://github.com/hollischuang/algorithm/tree/master/leetcode/236-lowestCommonAncestorOfABinaryTree) + +[https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) + +英文官方题解: + +[https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/articles/lowest-common-ancestor-of-a-binary-tree/) + +知识点:树、二叉树、二叉搜索树 + +难度:中等 + +--- + +2018年12月14日 + +[50. Pow(x, n)](https://github.com/hollischuang/algorithm/tree/master/leetcode/050-powxN) + +[https://leetcode-cn.com/problems/powx-n/](https://leetcode-cn.com/problems/powx-n/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution](https://leetcode.com/problems/powx-n/discuss/19546/Short-and-easy-to-understand-solution) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers](https://leetcode.com/problems/powx-n/discuss/19544/5-different-choices-when-talk-with-interviewers) + +知识点:递归、分治 + +难度:中等 + +--- + +2018年12月15日 + +[169. 求众数](https://github.com/hollischuang/algorithm/tree/master/leetcode/169-majorityElement) + +[https://leetcode-cn.com/problems/majority-element/](https://leetcode-cn.com/problems/majority-element/) + +英文官方题解: + +[https://leetcode.com/articles/majority-element/](https://leetcode.com/articles/majority-element/) + +知识点:递归、分治 + +难度:简单 + +--- + +2018年12月16日 + +[53. 最大子序和](https://github.com/hollischuang/algorithm/tree/master/leetcode/053-maximumSubarray) + +[https://leetcode-cn.com/problems/maximum-subarray/](https://leetcode-cn.com/problems/maximum-subarray/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts](https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java](https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java) + +知识点:递归、分治、动态规划 + +难度:简单 + +--- + +2018年12月17日 + +[860. 柠檬水找零](https://github.com/hollischuang/algorithm/tree/master/leetcode/860-lemonadeChange) + +[https://leetcode-cn.com/problems/lemonade-change/](https://leetcode-cn.com/problems/lemonade-change/) + +官方题解: + +[https://leetcode-cn.com/articles/lemonade-change/](https://leetcode-cn.com/articles/lemonade-change/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月18日 + +[122. 买卖股票的最佳时机 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/122-bestTimeToBuyAndSellStockII) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) + +官方题解: + +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock-ii/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月19日 + +[455. 分发饼干](https://github.com/hollischuang/algorithm/tree/master/leetcode/455-AssignCookies) + +[https://leetcode-cn.com/problems/assign-cookies/](https://leetcode-cn.com/problems/assign-cookies/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution](https://leetcode.com/problems/assign-cookies/discuss/93987/Simple-Greedy-Java-Solution) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)](https://leetcode.com/problems/assign-cookies/discuss/93997/Array-sort-%2B-Two-pointer-greedy-solution-O(nlogn)) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月20日 + +[874. 模拟行走机器人](https://github.com/hollischuang/algorithm/tree/master/leetcode/874-walkingRobotSimulation) + +[https://leetcode-cn.com/problems/walking-robot-simulation/](https://leetcode-cn.com/problems/walking-robot-simulation/) + +英文官方题解: + +[https://leetcode.com/problems/walking-robot-simulation/solution/](https://leetcode.com/problems/walking-robot-simulation/solution/) + +知识点:贪心算法 + +难度:简单 + +--- + +2018年12月21日 + +[102. 二叉树的层次遍历](https://github.com/hollischuang/algorithm/tree/master/leetcode/102-BinaryTreeLevelOrderTraversal) + +[https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33450/Java-solution-with-a-queue-used) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS](https://leetcode.com/problems/binary-tree-level-order-traversal/discuss/33445/Java-Solution-using-DFS) + +知识点:广度优先搜索 + +难度:中等 + +--- + +2018年12月22日 + +[104. 二叉树的最大深度](https://github.com/hollischuang/algorithm/tree/master/leetcode/104-MaximumDepthOfBinaryTree) + +[https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) + +官方题解: + +[https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/](https://leetcode-cn.com/articles/maximum-depth-of-binary-tree/) + +知识点:深度优先搜索 + +难度:简单 + +--- + +2018年12月23日 + +[51. N-皇后](https://github.com/hollischuang/algorithm/tree/master/leetcode/051-NQueens) + +[https://leetcode-cn.com/problems/n-queens/](https://leetcode-cn.com/problems/n-queens/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution](https://leetcode.com/problems/n-queens/discuss/19805/My-easy-understanding-Java-Solution) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.](https://leetcode.com/problems/n-queens/discuss/19808/Accepted-4ms-c%2B%2B-solution-use-backtracking-and-bitmask-easy-understand.) + +知识点:剪枝 + +难度:困难 + +--- + +2018年12月24日 + +[36. 有效的数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/036-ValidSudoku) + +[https://leetcode-cn.com/problems/valid-sudoku/](https://leetcode-cn.com/problems/valid-sudoku/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings](https://leetcode.com/problems/valid-sudoku/discuss/15472/Short%2BSimple-Java-using-Strings) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code](https://leetcode.com/problems/valid-sudoku/discuss/15450/Shared-my-concise-Java-code) + +知识点:剪枝 + +难度:中等 + +--- + +2018年12月25日 + +[37. 解数独](https://github.com/hollischuang/algorithm/tree/master/leetcode/037-SudokuSolver) + +[https://leetcode-cn.com/problems/sudoku-solver/](https://leetcode-cn.com/problems/sudoku-solver/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking](https://leetcode.com/problems/sudoku-solver/discuss/15752/Straight-Forward-Java-Solution-Using-Backtracking) + +知识点:剪枝 + +难度:困难 + +--- + +2018年12月26日 + +[69. x 的平方根](https://github.com/hollischuang/algorithm/tree/master/leetcode/069-SqrtX) + +[https://leetcode-cn.com/problems/sqrtx/](https://leetcode-cn.com/problems/sqrtx/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution](https://leetcode.com/problems/sqrtx/discuss/25047/A-Binary-Search-Solution) + +知识点:二分查找 + +难度:简单 + +--- + +2018年12月27日 + +[367. 有效的完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) + +[https://leetcode-cn.com/problems/valid-perfect-square/](https://leetcode-cn.com/problems/valid-perfect-square/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code](https://leetcode.com/problems/valid-perfect-square/discuss/83874/A-square-number-is-1%2B3%2B5%2B7%2B...-JAVA-code) + +知识点:二分查找 + +难度:简单 + +--- + +2018年12月28日 + +[208. 实现 Trie (前缀树)](https://github.com/hollischuang/algorithm/tree/master/leetcode/208-implementTriePrefixTree) + +[https://leetcode-cn.com/problems/implement-trie-prefix-tree/](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) + +英文官方题解: + +[https://leetcode.com/articles/implement-trie-prefix-tree/](https://leetcode.com/articles/implement-trie-prefix-tree/) + +知识点:字典树 + +难度:中等 + +--- + +2018年12月29日 + +[212. 单词搜索 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/212-wordSearchII) + +[https://leetcode-cn.com/problems/word-search-ii/](https://leetcode-cn.com/problems/word-search-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)](https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)) + +知识点:字典树 + +难度:困难 + +--- + +2018年12月30日 + +[191. 位1的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/191-NumberOf1Bits) + +[https://leetcode-cn.com/problems/number-of-1-bits/](https://leetcode-cn.com/problems/number-of-1-bits/) + +英文官方题解: + +[https://leetcode.com/articles/number-1-bits/](https://leetcode.com/articles/number-1-bits/) + +知识点:位运算 + +难度:简单 + +--- + +2018年12月31日 + +[338. 比特位计数](https://github.com/hollischuang/algorithm/tree/master/leetcode/338-CountingBits) + +[https://leetcode-cn.com/problems/counting-bits/](https://leetcode-cn.com/problems/counting-bits/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution](https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-Solution) + +知识点:位运算 + +难度:中等 + +--- + +2019年01月01日 + +[231. 2的幂](https://github.com/hollischuang/algorithm/tree/master/leetcode/231-PowerOfTwo) + +[https://leetcode-cn.com/problems/power-of-two/](https://leetcode-cn.com/problems/power-of-two/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount](https://leetcode.com/problems/power-of-two/discuss/63972/One-line-java-solution-using-bitCount) + +知识点:位运算 + +难度:简单 + +--- + +2019年01月02日 + +[52. N皇后 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/052-N-QueensII) + +[https://leetcode-cn.com/problems/n-queens-ii/](https://leetcode-cn.com/problems/n-queens-ii/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution](https://leetcode.com/problems/n-queens-ii/discuss/20058/Accepted-Java-Solution) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)](https://leetcode.com/problems/n-queens-ii/discuss/20048/Easiest-Java-Solution-(1ms-98.22)) + +知识点:位运算 + +难度:困难 + +--- + +2019年01月03日 + +[70. 爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/070-ClimbingStairs) + +[https://leetcode-cn.com/problems/climbing-stairs/](https://leetcode-cn.com/problems/climbing-stairs/) + +英文官方题解: + +[https://leetcode.com/articles/climbing-stairs/](https://leetcode.com/articles/climbing-stairs/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月04日 + +[120. 三角形最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/120-Triangle) + +[https://leetcode-cn.com/problems/triangle/](https://leetcode-cn.com/problems/triangle/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle](https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution](https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月05日 + +[152. 乘积最大子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/152-MaximumProductSubarray) + +[https://leetcode-cn.com/problems/maximum-product-subarray/](https://leetcode-cn.com/problems/maximum-product-subarray/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity](https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time](https://leetcode.com/problems/maximum-product-subarray/discuss/48252/Sharing-my-solution%3A-O(1)-space-O(n)-running-time) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月06日 + +[123. 买卖股票的最佳时机 III](https://github.com/hollischuang/algorithm/tree/master/leetcode/123-BestTimeToBuyAndSellStockIII) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/39611/Is-it-Best-Solution-with-O(n)-O(1).) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/Detail-explanation-of-DP-solution) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月07日 + +[121. 买卖股票的最佳时机](https://github.com/hollischuang/algorithm/tree/master/leetcode/121-bestTimeToBuyAndSellStock) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) + +官方题解: + +[https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/](https://leetcode-cn.com/articles/best-time-to-buy-and-sell-stock/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月08日 + +[188. 买卖股票的最佳时机 IV](https://github.com/hollischuang/algorithm/tree/master/leetcode/188-bestTimeToBuyAndSellStockIV) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月09日 + +[309. 最佳买卖股票时机含冷冻期](https://github.com/hollischuang/algorithm/tree/master/leetcode/309-BestTimeToBuyAndSellStockWithCooldown) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75927/Share-my-thinking-process) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月10日 + +[714. 买卖股票的最佳时机含手续费](https://github.com/hollischuang/algorithm/tree/master/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee) + +[https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +英文官方题解: + +[https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/](https://leetcode.com/articles/best-time-to-buy-and-sell-stock-with-transaction-fee/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月11日 + +[300. 最长上升子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/300-LongestIncreasingSubsequence) + +[https://leetcode-cn.com/problems/longest-increasing-subsequence/](https://leetcode-cn.com/problems/longest-increasing-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/longest-increasing-subsequence/](https://leetcode.com/articles/longest-increasing-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月12日 + +[322. 零钱兑换](https://github.com/hollischuang/algorithm/tree/master/leetcode/322-CoinChange) + +[https://leetcode-cn.com/problems/coin-change/](https://leetcode-cn.com/problems/coin-change/) + +英文官方题解: + +[https://leetcode.com/articles/coin-change/](https://leetcode.com/articles/coin-change/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月13日 + +[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) + +[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) + +英文官方题解: + +[https://leetcode.com/articles/edit-distance/](https://leetcode.com/articles/edit-distance/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年01月14日 + +[200. 岛屿的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/200-numberOfIslands) + +[https://leetcode-cn.com/problems/number-of-islands/](https://leetcode-cn.com/problems/number-of-islands/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution](https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solution) + +知识点:并查集 + +难度:中等 + +--- + +2019年01月15日 + +[547. 朋友圈](https://github.com/hollischuang/algorithm/tree/master/leetcode/547-friendCircles) + +[https://leetcode-cn.com/problems/friend-circles/](https://leetcode-cn.com/problems/friend-circles/) + +无官方题解,网友高票Java解法1(DFS): + +[https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution](https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution) + +无官方题解,网友高票Java解法2(Union Find): + +[https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find](https://leetcode.com/problems/friend-circles/discuss/101336/Java-solution-Union-Find) + +知识点:并查集 + +难度:中等 + +--- + +2019年01月16日 + +[146. LRU缓存机制](https://github.com/hollischuang/algorithm/tree/master/leetcode/146-lruCache) + +[https://leetcode-cn.com/problems/lru-cache/](https://leetcode-cn.com/problems/lru-cache/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)](https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes)) + +知识点:LRU + +难度:困难 + +--- + +专题(End):《算法面试40讲》 +--- + +
+ +专题(Begin):动态规划 +--- + +2019年01月17日 + +[303. 区域和检索 - 数组不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/303-rangeSumQueryImmutable) + +[https://leetcode-cn.com/problems/range-sum-query-immutable/](https://leetcode-cn.com/problems/range-sum-query-immutable/) + +英文官方题解: + +[https://leetcode.com/articles/range-sum-query-immutable/](https://leetcode.com/articles/range-sum-query-immutable/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月18日 + +[746. 使用最小花费爬楼梯](https://github.com/hollischuang/algorithm/tree/master/leetcode/746-minCostClimbingStairs) + +[https://leetcode-cn.com/problems/min-cost-climbing-stairs/](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) + +英文官方题解: + +[https://leetcode.com/articles/min-cost-climbing-stairs/](https://leetcode.com/articles/min-cost-climbing-stairs/) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月19日 + +[198. 打家劫舍](https://github.com/hollischuang/algorithm/tree/master/leetcode/198-houseRobber) + +[https://leetcode-cn.com/problems/house-robber/](https://leetcode-cn.com/problems/house-robber/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.) + +知识点:动态规划 + +难度:简单 + +--- + +2019年01月20日 + +[877. 石子游戏](https://github.com/hollischuang/algorithm/tree/master/leetcode/877-stoneGame) + +[https://leetcode-cn.com/problems/stone-game/](https://leetcode-cn.com/problems/stone-game/) + +官方题解: + +[https://leetcode-cn.com/articles/stone-game/](https://leetcode-cn.com/articles/stone-game/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月21日 + +[64. 最小路径和](https://github.com/hollischuang/algorithm/tree/master/leetcode/064-minimumPathSum) + +[https://leetcode-cn.com/problems/minimum-path-sum/](https://leetcode-cn.com/problems/minimum-path-sum/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space](https://leetcode.com/problems/minimum-path-sum/discuss/23471/My-java-solution-using-DP-and-no-extra-space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月22日 + +[96. 不同的二叉搜索树](https://github.com/hollischuang/algorithm/tree/master/leetcode/096-uniqueBinarySearchTrees) + +[https://leetcode-cn.com/problems/unique-binary-search-trees/](https://leetcode-cn.com/problems/unique-binary-search-trees/) + +英文官方题解: + +[https://leetcode.com/articles/unique-binary-search-trees/](https://leetcode.com/articles/unique-binary-search-trees/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月23日 + +[413. 等差数列划分](https://github.com/hollischuang/algorithm/tree/master/leetcode/413-arithmeticSlices) + +[https://leetcode-cn.com/problems/arithmetic-slices/](https://leetcode-cn.com/problems/arithmetic-slices/) + +英文官方题解: + +[https://leetcode.com/articles/arithmetic-slices/](https://leetcode.com/articles/arithmetic-slices/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月24日 + +[712. 两个字符串的最小ASCII删除和](https://github.com/hollischuang/algorithm/tree/master/leetcode/712-MinimumASCIIDeleteSumforTwoStrings) + +[https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/](https://leetcode-cn.com/problems/minimum-ascii-delete-sum-for-two-strings/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/](https://leetcode.com/articles/minimum-ascii-delete-sum-for-two-strings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月25日 + +[62. 不同路径](https://github.com/hollischuang/algorithm/tree/master/leetcode/062-UniquePaths) + +[https://leetcode-cn.com/problems/unique-paths/](https://leetcode-cn.com/problems/unique-paths/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space](https://leetcode.com/problems/unique-paths/discuss/22958/Math-solution-O(1)-space) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)](https://leetcode.com/problems/unique-paths/discuss/22953/Java-DP-solution-with-complexity-O(n*m)) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月26日 + +[638. 大礼包](https://github.com/hollischuang/algorithm/tree/master/leetcode/638-ShoppingOffers) + +[https://leetcode-cn.com/problems/shopping-offers/](https://leetcode-cn.com/problems/shopping-offers/) + +英文官方题解: + +[https://leetcode.com/articles/shopping-offers/](https://leetcode.com/articles/shopping-offers/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月27日 + +[647. 回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/647-PalindromicSubstrings) + +[https://leetcode-cn.com/problems/palindromic-substrings/](https://leetcode-cn.com/problems/palindromic-substrings/) + +英文官方题解: + +[https://leetcode.com/articles/palindromic-substrings/](https://leetcode.com/articles/palindromic-substrings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月28日 + +[931. 下降路径最小和](https://github.com/hollischuang/algorithm/tree/master/leetcode/931-MinimumFallingPathSum) + +[https://leetcode-cn.com/problems/minimum-falling-path-sum/](https://leetcode-cn.com/problems/minimum-falling-path-sum/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-path-falling-sum/](https://leetcode.com/articles/minimum-path-falling-sum/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月29日 + +[343. 整数拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/343-IntegerBreak) + +[https://leetcode-cn.com/problems/integer-break/](https://leetcode-cn.com/problems/integer-break/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution](https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月30日 + +[95. 不同的二叉搜索树 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/095-UniqueBinarySearchTreesII) + +[https://leetcode-cn.com/problems/unique-binary-search-trees-ii/](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) + +英文官方题解: + +[https://leetcode.com/articles/unique-binary-search-trees-ii/](https://leetcode.com/articles/unique-binary-search-trees-ii/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年01月31日 + +[740. 删除与获得点数](https://github.com/hollischuang/algorithm/tree/master/leetcode/740-DeleteAndEarn) + +[https://leetcode-cn.com/problems/delete-and-earn/](https://leetcode-cn.com/problems/delete-and-earn/) + +英文官方题解: + +[https://leetcode.com/articles/delete-and-earn/](https://leetcode.com/articles/delete-and-earn/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月01日 + +[646. 最长数对链](https://github.com/hollischuang/algorithm/tree/master/leetcode/646-MaximumLengthOfPairChain) + +[https://leetcode-cn.com/problems/maximum-length-of-pair-chain/](https://leetcode-cn.com/problems/maximum-length-of-pair-chain/) + +英文官方题解: + +[https://leetcode.com/articles/maximum-length-of-pair-chain/](https://leetcode.com/articles/maximum-length-of-pair-chain/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月02日 + +[764. 最大加号标志](https://github.com/hollischuang/algorithm/tree/master/leetcode/764-LargestPlusSign) + +[https://leetcode-cn.com/problems/largest-plus-sign/](https://leetcode-cn.com/problems/largest-plus-sign/) + +英文官方题解: + +[https://leetcode.com/articles/largest-plus-sign/](https://leetcode.com/articles/largest-plus-sign/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月03日 + +[279. 完全平方数](https://github.com/hollischuang/algorithm/tree/master/leetcode/279-PerfectSquares) + +[https://leetcode-cn.com/problems/perfect-squares/](https://leetcode-cn.com/problems/perfect-squares/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java](https://leetcode.com/problems/perfect-squares/discuss/71495/An-easy-understanding-DP-solution-in-Java) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月04日 + +[392. 判断子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/392-IsSubsequence) + +[https://leetcode-cn.com/problems/is-subsequence/](https://leetcode-cn.com/problems/is-subsequence/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments](https://leetcode.com/problems/is-subsequence/discuss/87302/Binary-search-solution-for-follow-up-with-detailed-comments) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月05日 + +[377. 组合总和 Ⅳ](https://github.com/hollischuang/algorithm/tree/master/leetcode/377-CombinationSumIV) + +[https://leetcode-cn.com/problems/combination-sum-iv/](https://leetcode-cn.com/problems/combination-sum-iv/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation](https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月06日 + +[486. 预测赢家](https://github.com/hollischuang/algorithm/tree/master/leetcode/486-PredictTheWinner) + +[https://leetcode-cn.com/problems/predict-the-winner/](https://leetcode-cn.com/problems/predict-the-winner/) + +英文官方题解: + +[https://leetcode.com/articles/predict-the-winner/](https://leetcode.com/articles/predict-the-winner/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月07日 + +[357. 计算各个位数不同的数字个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/357-CountNumbersWithUniqueDigits) + +[https://leetcode-cn.com/problems/count-numbers-with-unique-digits/](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.](https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83041/JAVA-DP-O(1)-solution.) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月08日 + +[494. 目标和](https://github.com/hollischuang/algorithm/tree/master/leetcode/494-TargetSum) + +[https://leetcode-cn.com/problems/target-sum/](https://leetcode-cn.com/problems/target-sum/) + +英文官方题解: + +[https://leetcode.com/articles/target-sum/](https://leetcode.com/articles/target-sum/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月09日 + +[516. 最长回文子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/516-LongestPalindromicSubsequence) + +[https://leetcode-cn.com/problems/longest-palindromic-subsequence/](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution](https://leetcode.com/problems/longest-palindromic-subsequence/discuss/99101/Straight-forward-Java-DP-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月10日 + +[688. “马”在棋盘上的概率](https://github.com/hollischuang/algorithm/tree/master/leetcode/688-KnightProbabilityInChessboard) + +[https://leetcode-cn.com/problems/knight-probability-in-chessboard/](https://leetcode-cn.com/problems/knight-probability-in-chessboard/) + +英文官方题解: + +[https://leetcode.com/articles/knight-probability-in-chessboard/](https://leetcode.com/articles/knight-probability-in-chessboard/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月11日 + +[718. 最长重复子数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/718-MaximumLengthOfRepeatedSubarray) + +[https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/) + +英文官方题解: + +[https://leetcode.com/articles/maximum-length-of-repeated-subarray/](https://leetcode.com/articles/maximum-length-of-repeated-subarray/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月12日 + +[650. 只有两个键的键盘](https://github.com/hollischuang/algorithm/tree/master/leetcode/650-2KeysKeyboard) + +[https://leetcode-cn.com/problems/2-keys-keyboard/](https://leetcode-cn.com/problems/2-keys-keyboard/) + +英文官方题解: + +[https://leetcode.com/articles/2-keys-keyboard/](https://leetcode.com/articles/2-keys-keyboard/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月13日 + +[873. 最长的斐波那契子序列的长度](https://github.com/hollischuang/algorithm/tree/master/leetcode/873-LengthOfLongestFibonacciSubsequence) + +[https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) + +官方题解: + +[https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/](https://leetcode-cn.com/articles/length-of-longest-fibonacci-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月14日 + +[139. 单词拆分](https://github.com/hollischuang/algorithm/tree/master/leetcode/139-WordBreak) + +[https://leetcode-cn.com/problems/word-break/](https://leetcode-cn.com/problems/word-break/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways](https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月15日 + +[264. 丑数 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/264-UglyNumberII) + +[https://leetcode-cn.com/problems/ugly-number-ii/](https://leetcode-cn.com/problems/ugly-number-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution](https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月16日 + +[416. 分割等和子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/416-PartitionEqualSubsetSum) + +[https://leetcode-cn.com/problems/partition-equal-subset-sum/](https://leetcode-cn.com/problems/partition-equal-subset-sum/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand](https://leetcode.com/problems/partition-equal-subset-sum/discuss/90627/Java-Solution-similar-to-backpack-problem-Easy-to-understand) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月17日 + +[304. 二维区域和检索 - 矩阵不可变](https://github.com/hollischuang/algorithm/tree/master/leetcode/304-RangeSumQuery2DImmutable) + +[https://leetcode-cn.com/problems/range-sum-query-2d-immutable/](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) + +英文无官方题解: + +[https://leetcode.com/articles/range-sum-query-2d-immutable/](https://leetcode.com/articles/range-sum-query-2d-immutable/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月18日 + +[221. 最大正方形](https://github.com/hollischuang/algorithm/tree/master/leetcode/221-MaximalSquare) + +[https://leetcode-cn.com/problems/maximal-square/](https://leetcode-cn.com/problems/maximal-square/) + +英文官方题解: + +[https://leetcode.com/articles/maximal-square/](https://leetcode.com/articles/maximal-square/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月19日 + +[698. 划分为k个相等的子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/698-PartitionToKEqualSumSubsets) + +[https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/](https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets/) + +英文官方题解: + +[https://leetcode.com/articles/partition-to-k-equal-sum-subsets/](https://leetcode.com/articles/partition-to-k-equal-sum-subsets/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月20日 + +[474. 一和零](https://github.com/hollischuang/algorithm/tree/master/leetcode/474-OnesAndZeroes) + +[https://leetcode-cn.com/problems/ones-and-zeroes/](https://leetcode-cn.com/problems/ones-and-zeroes/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.](https://leetcode.com/problems/ones-and-zeroes/discuss/95807/0-1-knapsack-detailed-explanation.) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space](https://leetcode.com/problems/ones-and-zeroes/discuss/95811/Java-Iterative-DP-Solution-O(mn)-Space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月21日 + +[838. 推多米诺](https://github.com/hollischuang/algorithm/tree/master/leetcode/838-PushDominoes) + +[https://leetcode-cn.com/problems/push-dominoes/](https://leetcode-cn.com/problems/push-dominoes/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/articles/push-dominoes/](https://leetcode.com/articles/push-dominoes/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月22日 + +[790. 多米诺和托米诺平铺](https://github.com/hollischuang/algorithm/tree/master/leetcode/790-DominoAndTrominoTiling) + +[https://leetcode-cn.com/problems/domino-and-tromino-tiling/](https://leetcode-cn.com/problems/domino-and-tromino-tiling/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3](https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1%2Bdpn-3) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月23日 + +[813. 最大平均值和的分组](https://github.com/hollischuang/algorithm/tree/master/leetcode/813-LargestSumOfAverages) + +[https://leetcode-cn.com/problems/largest-sum-of-averages/](https://leetcode-cn.com/problems/largest-sum-of-averages/) + +英文官方题解: + +[https://leetcode.com/articles/largest-sum-of-averages/](https://leetcode.com/articles/largest-sum-of-averages/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月24日 + +[376. 摆动序列变](https://github.com/hollischuang/algorithm/tree/master/leetcode/367-ValidPerfectSquare) + +[https://leetcode-cn.com/problems/wiggle-subsequence/](https://leetcode-cn.com/problems/wiggle-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/wiggle-subsequence/](https://leetcode.com/articles/wiggle-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月25日 + +[801. 使序列递增的最小交换次数](https://github.com/hollischuang/algorithm/tree/master/leetcode/801-MinimumSwapsToMakeSequencesIncreasing) + +[https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/](https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/) + +英文官方题解: + +[https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/](https://leetcode.com/articles/minimum-swaps-to-make-sequences-increasing/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月26日 + +[808. 分汤](https://github.com/hollischuang/algorithm/tree/master/leetcode/808-SoupServings) + +[https://leetcode-cn.com/problems/soup-servings/](https://leetcode-cn.com/problems/soup-servings/) + +英文官方题解: + +[https://leetcode.com/articles/soup-servings/](https://leetcode.com/articles/soup-servings/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月27日 + +[63. 不同路径 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/063-UniquePathsII) + +[https://leetcode-cn.com/problems/unique-paths-ii/](https://leetcode-cn.com/problems/unique-paths-ii/) + +英文官方题解: + +[https://leetcode.com/articles/unique-paths-ii/](https://leetcode.com/articles/unique-paths-ii/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年02月28日 + +[213. 打家劫舍 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/213-HouseRobberII) + +[https://leetcode-cn.com/problems/house-robber-ii/](https://leetcode-cn.com/problems/house-robber-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation](https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月01日 + +[368. 最大整除子集](https://github.com/hollischuang/algorithm/tree/master/leetcode/368-LargestDivisibleSubset) + +[https://leetcode-cn.com/problems/largest-divisible-subset/](https://leetcode-cn.com/problems/largest-divisible-subset/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)](https://leetcode.com/problems/largest-divisible-subset/discuss/84006/Classic-DP-solution-similar-to-LIS-O(n2)) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月02日 + +[467. 环绕字符串中唯一的子字符串](https://github.com/hollischuang/algorithm/tree/master/leetcode/467-UniqueSubstringsInWraparoundString) + +[https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP](https://leetcode.com/problems/unique-substrings-in-wraparound-string/discuss/95439/Concise-Java-solution-using-DP) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月03日 + +[464. 我能赢吗](https://github.com/hollischuang/algorithm/tree/master/leetcode/464-CanIWin) + +[https://leetcode-cn.com/problems/can-i-win/](https://leetcode-cn.com/problems/can-i-win/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation](https://leetcode.com/problems/can-i-win/discuss/95277/Java-solution-using-HashMap-with-detailed-explanation) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation](https://leetcode.com/problems/can-i-win/discuss/95293/Java-easy-strightforward-solution-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月04日 + +[935. 骑士拨号器](https://github.com/hollischuang/algorithm/tree/master/leetcode/935-KnightDialer) + +[https://leetcode-cn.com/problems/knight-dialer/](https://leetcode-cn.com/problems/knight-dialer/) + +英文官方题解: + +[https://leetcode.com/articles/knight-dialer/](https://leetcode.com/articles/knight-dialer/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月05日 + +[787. K 站中转内最便宜的航班](https://github.com/hollischuang/algorithm/tree/master/leetcode/787-CheapestFlightsWithinKStops) + +[https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/115541/JavaPython-Priority-Queue-Solution) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm](https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月06日 + +[576. 出界的路径数](https://github.com/hollischuang/algorithm/tree/master/leetcode/576-OutOfBoundaryPaths) + +[https://leetcode-cn.com/problems/out-of-boundary-paths/](https://leetcode-cn.com/problems/out-of-boundary-paths/) + +英文官方题解: + +[https://leetcode.com/articles/out-of-boundary-paths/](https://leetcode.com/articles/out-of-boundary-paths/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月07日 + +[374. 猜数字大小](https://github.com/hollischuang/algorithm/tree/master/leetcode/374-GuessNumberHigherOrLower) + +[https://leetcode-cn.com/problems/guess-number-higher-or-lower/](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) + +英文官方题解: + +[https://leetcode.com/articles/guess-number-higher-or-lower/](https://leetcode.com/articles/guess-number-higher-or-lower/) + +知识点:二分查找 + +难度:简单 + +--- + +2019年03月08日 + +[375. 猜数字大小 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/375-GuessNumberHigherOrLowerII) + +[https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~](https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/84764/Simple-DP-solution-with-explanation~~) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月09日 + +[967. 连续差相同的数字](https://github.com/hollischuang/algorithm/tree/master/leetcode/967-NumbersWithSameConsecutiveDifferences) + +[https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) + +英文官方题解: + +[https://leetcode.com/articles/numbers-with-same-consecutive-differences/](https://leetcode.com/articles/numbers-with-same-consecutive-differences/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月10日 + +[673. 最长递增子序列的个数](https://github.com/hollischuang/algorithm/tree/master/leetcode/673-NumberOfLongestIncreasingSubsequence) + +[https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) + +英文官方题解: + +[https://leetcode.com/articles/number-of-longest-increasing-subsequence/](https://leetcode.com/articles/number-of-longest-increasing-subsequence/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月11日 + +[131. 分割回文串](https://github.com/hollischuang/algorithm/tree/master/leetcode/131-PalindromePartitioning) + +[https://leetcode-cn.com/problems/palindrome-partitioning/](https://leetcode-cn.com/problems/palindrome-partitioning/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.](https://leetcode.com/problems/palindrome-partitioning/discuss/41963/Java%3A-Backtracking-solution.) + +知识点:回溯算法 + +难度:中等 + +--- + +2019年03月12日 + +[132. 分割回文串II](https://github.com/hollischuang/algorithm/tree/master/leetcode/132-PalindromePartitioningII) + +[https://leetcode-cn.com/problems/palindrome-partitioning-ii/](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.](https://leetcode.com/problems/palindrome-partitioning-ii/discuss/42198/My-solution-does-not-need-a-table-for-palindrome-is-it-right-It-uses-only-O(n)-space.) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月13日 + +[5. 最长回文子串](https://github.com/hollischuang/algorithm/tree/master/leetcode/005-LongestPalindromicSubstring) + +[https://leetcode-cn.com/problems/longest-palindromic-substring/](https://leetcode-cn.com/problems/longest-palindromic-substring/) + +英文官方题解: + +[https://leetcode.com/articles/longest-palindromic-substring/](https://leetcode.com/articles/longest-palindromic-substring/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月14日 + +[523. 连续的子数组和](https://github.com/hollischuang/algorithm/tree/master/leetcode/523-ContinuousSubarraySum) + +[https://leetcode-cn.com/problems/continuous-subarray-sum/](https://leetcode-cn.com/problems/continuous-subarray-sum/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space](https://leetcode.com/problems/continuous-subarray-sum/discuss/99499/Java-O(n)-time-O(k)-space) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月15日 + +[837. 新21点](https://github.com/hollischuang/algorithm/tree/master/leetcode/837-New21Game) + +[https://leetcode-cn.com/problems/new-21-game/](https://leetcode-cn.com/problems/new-21-game/) + +英文官方题解: + +[https://leetcode.com/articles/new-21-game/](https://leetcode.com/articles/new-21-game/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月16日 + +[898. 子数组按位或操作](https://github.com/hollischuang/algorithm/tree/master/leetcode/898-BitwiseORsOfSubarrays) + +[https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/](https://leetcode-cn.com/problems/bitwise-ors-of-subarrays/) + +英文官方题解: + +[https://leetcode.com/articles/bitwise-ors-of-subarrays/](https://leetcode.com/articles/bitwise-ors-of-subarrays/) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月17日 + +[91. 解码方法](https://github.com/hollischuang/algorithm/tree/master/leetcode/091-DecodeWays) + +[https://leetcode-cn.com/problems/decode-ways/](https://leetcode-cn.com/problems/decode-ways/) + +无官方题解,网友高票Java解法1: + +[https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference](https://leetcode.com/problems/decode-ways/discuss/30357/DP-Solution-(Java)-for-reference) + +无官方题解,网友高票Java解法2: + +[https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation](https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanation) + +知识点:动态规划 + +难度:中等 + +--- + +2019年03月18日 + +[312. 戳气球](https://github.com/hollischuang/algorithm/tree/master/leetcode/312-BurstBalloons) + +[https://leetcode-cn.com/problems/burst-balloons/](https://leetcode-cn.com/problems/burst-balloons/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations](https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月19日 + +[72. 编辑距离](https://github.com/hollischuang/algorithm/tree/master/leetcode/072-EditDistance) + +[https://leetcode-cn.com/problems/edit-distance/](https://leetcode-cn.com/problems/edit-distance/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)](https://leetcode.com/problems/edit-distance/discuss/25849/Java-DP-solution-O(nm)) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月20日 + +[975. 奇偶跳](https://github.com/hollischuang/algorithm/tree/master/leetcode/975-OddEvenJump) + +[https://leetcode-cn.com/problems/odd-even-jump/](https://leetcode-cn.com/problems/odd-even-jump/) + +官方题解: + +[https://leetcode-cn.com/articles/odd-even-jump/](https://leetcode-cn.com/articles/odd-even-jump/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月21日 + +[115. 不同的子序列](https://github.com/hollischuang/algorithm/tree/master/leetcode/115-DistinctSubsequences) + +[https://leetcode-cn.com/problems/distinct-subsequences/](https://leetcode-cn.com/problems/distinct-subsequences/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java](https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月22日 + +[940. 不同的子序列 II](https://github.com/hollischuang/algorithm/tree/master/leetcode/940-DistinctSubsequencesII) + +[https://leetcode-cn.com/problems/distinct-subsequences-ii/](https://leetcode-cn.com/problems/distinct-subsequences-ii/) + +英文官方题解: + +[https://leetcode.com/articles/distinct-subsequences-ii/](https://leetcode.com/articles/distinct-subsequences-ii/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月23日 + +[691. 贴纸拼词](https://github.com/hollischuang/algorithm/tree/master/leetcode/691-StickersToSpellWord) + +[https://leetcode-cn.com/problems/stickers-to-spell-word/](https://leetcode-cn.com/problems/stickers-to-spell-word/) + +英文官方题解: + +[https://leetcode.com/articles/stickers-to-spell-word/](https://leetcode.com/articles/stickers-to-spell-word/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月24日 + +[982. 按位与为零的三元组](https://github.com/hollischuang/algorithm/tree/master/leetcode/982-TriplesWithBitwiseANDEqualToZero) + +[https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/](https://leetcode-cn.com/problems/triples-with-bitwise-and-equal-to-zero/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space](https://leetcode.com/problems/triples-with-bitwise-and-equal-to-zero/discuss/226721/Java-DP-O(3-*-216-*-n)-time-O(216)-space) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月25日 + +[546. 移除盒子](https://github.com/hollischuang/algorithm/tree/master/leetcode/546-RemoveBoxes) + +[https://leetcode-cn.com/problems/remove-boxes/](https://leetcode-cn.com/problems/remove-boxes/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions](https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月26日 + +[85. 最大矩形](https://github.com/hollischuang/algorithm/tree/master/leetcode/085-MaximalRectangle) + +[https://leetcode-cn.com/problems/maximal-rectangle/](https://leetcode-cn.com/problems/maximal-rectangle/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution](https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月27日 + +[903. DI 序列的有效排列](https://github.com/hollischuang/algorithm/tree/master/leetcode/903-ValidPermutationsForDISequence) + +[https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/](https://leetcode-cn.com/problems/valid-permutations-for-di-sequence/) + +英文官方题解: + +[https://leetcode.com/articles/valid-permutations-for-di-sequence/](https://leetcode.com/articles/valid-permutations-for-di-sequence/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月28日 + +[629. K个逆序对数组](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/k-inverse-pairs-array/](https://leetcode-cn.com/problems/k-inverse-pairs-array/) + +英文官方题解: + +[https://leetcode.com/articles/k-inverse-pairs-array/](https://leetcode.com/articles/k-inverse-pairs-array/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月29日 + +[956. 最高的广告牌](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/tallest-billboard/](https://leetcode-cn.com/problems/tallest-billboard/) + +英文官方题解: + +[https://leetcode.com/problems/tallest-billboard/solution/](https://leetcode.com/problems/tallest-billboard/solution/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年03月30日 + +[664. 奇怪的打印机](https://github.com/hollischuang/algorithm/tree/master/leetcode/629-KInversePairsArray) + +[https://leetcode-cn.com/problems/strange-printer/](https://leetcode-cn.com/problems/strange-printer/) + +英文官方题解: + +[https://leetcode.com/problems/strange-printer/solution/](https://leetcode.com/problems/strange-printer/solution/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年04月01日 + +[943. 最短超级串](https://github.com/hollischuang/algorithm/tree/master/leetcode/943-FindTheShortestSuperstring) + +[https://leetcode-cn.com/problems/find-the-shortest-superstring/](https://leetcode-cn.com/problems/find-the-shortest-superstring/) + +英文官方题解: + +[https://leetcode.com/articles/find-the-shortest-superstring/](https://leetcode.com/articles/find-the-shortest-superstring/) + +知识点:动态规划 + +难度:困难 + +--- + +2019年04月02日 + +[32. 最长有效括号](https://github.com/hollischuang/algorithm/tree/master/leetcode/032-LongestValidParentheses) + +[https://leetcode-cn.com/problems/longest-valid-parentheses/](https://leetcode-cn.com/problems/longest-valid-parentheses/) + +英文官方题解: + +[https://leetcode.com/articles/longest-valid-parentheses/](https://leetcode.com/articles/longest-valid-parentheses/) + +知识点:动态规划 + +难度:困难 + +--- + + +2019年04月03日 + +[403. 青蛙过河](https://github.com/hollischuang/algorithm/tree/master/leetcode/403-FrogJump) + +[https://leetcode-cn.com/problems/frog-jump/](https://leetcode-cn.com/problems/frog-jump/) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- + + +2019年04月04日 + +[321. 拼接最大数](https://github.com/hollischuang/algorithm/tree/master/leetcode/321-CreateMaximumNumber) + +[https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution](https://leetcode.com/problems/create-maximum-number/discuss/77285/Share-my-greedy-solution) + +无官方题解,网友高票Java解法: + +[https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations](https://leetcode.com/problems/frog-jump/discuss/88824/Very-easy-to-understand-JAVA-solution-with-explanations) + +知识点:动态规划 + +难度:困难 + +--- diff --git a/images/017_Telephone-keypad2.png b/solutions/images/017_Telephone-keypad2.png similarity index 100% rename from images/017_Telephone-keypad2.png rename to solutions/images/017_Telephone-keypad2.png diff --git a/images/160_example_1.png b/solutions/images/160_example_1.png similarity index 100% rename from images/160_example_1.png rename to solutions/images/160_example_1.png diff --git a/images/160_example_2.png b/solutions/images/160_example_2.png similarity index 100% rename from images/160_example_2.png rename to solutions/images/160_example_2.png diff --git a/images/160_example_3.png b/solutions/images/160_example_3.png similarity index 100% rename from images/160_example_3.png rename to solutions/images/160_example_3.png diff --git a/images/160_statement.png b/solutions/images/160_statement.png similarity index 100% rename from images/160_statement.png rename to solutions/images/160_statement.png diff --git a/leetcode/001-twoSum/README.md b/solutions/leetcode/001-twoSum/README.md similarity index 100% rename from leetcode/001-twoSum/README.md rename to solutions/leetcode/001-twoSum/README.md diff --git a/leetcode/001-twoSum/hatrick.md b/solutions/leetcode/001-twoSum/hatrick.md similarity index 100% rename from leetcode/001-twoSum/hatrick.md rename to solutions/leetcode/001-twoSum/hatrick.md diff --git a/leetcode/001-twoSum/woody.md b/solutions/leetcode/001-twoSum/woody.md similarity index 100% rename from leetcode/001-twoSum/woody.md rename to solutions/leetcode/001-twoSum/woody.md diff --git a/leetcode/002-addTwoNumber/README.md b/solutions/leetcode/002-addTwoNumber/README.md similarity index 100% rename from leetcode/002-addTwoNumber/README.md rename to solutions/leetcode/002-addTwoNumber/README.md diff --git a/leetcode/002-addTwoNumber/monkey.md b/solutions/leetcode/002-addTwoNumber/monkey.md similarity index 100% rename from leetcode/002-addTwoNumber/monkey.md rename to solutions/leetcode/002-addTwoNumber/monkey.md diff --git a/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md b/solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md similarity index 100% rename from leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md rename to solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/README.md diff --git a/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md b/solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md similarity index 100% rename from leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md rename to solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/monkey.md diff --git a/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md b/solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md similarity index 100% rename from leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md rename to solutions/leetcode/003-longestSubstringWithoutRepeatingCharacters/zengdiqing1994.md diff --git a/leetcode/005-LongestPalindromicSubstring/hatrick.md b/solutions/leetcode/005-LongestPalindromicSubstring/hatrick.md similarity index 100% rename from leetcode/005-LongestPalindromicSubstring/hatrick.md rename to solutions/leetcode/005-LongestPalindromicSubstring/hatrick.md diff --git a/leetcode/005-LongestPalindromicSubstring/official.md b/solutions/leetcode/005-LongestPalindromicSubstring/official.md similarity index 100% rename from leetcode/005-LongestPalindromicSubstring/official.md rename to solutions/leetcode/005-LongestPalindromicSubstring/official.md diff --git a/leetcode/006-ZigZagConversion/README.md b/solutions/leetcode/006-ZigZagConversion/README.md similarity index 100% rename from leetcode/006-ZigZagConversion/README.md rename to solutions/leetcode/006-ZigZagConversion/README.md diff --git a/leetcode/006-ZigZagConversion/zengdiqing.md b/solutions/leetcode/006-ZigZagConversion/zengdiqing.md similarity index 100% rename from leetcode/006-ZigZagConversion/zengdiqing.md rename to solutions/leetcode/006-ZigZagConversion/zengdiqing.md diff --git a/leetcode/015-threeSum/hatrick.md b/solutions/leetcode/015-threeSum/hatrick.md similarity index 100% rename from leetcode/015-threeSum/hatrick.md rename to solutions/leetcode/015-threeSum/hatrick.md diff --git a/leetcode/015-threeSum/official.md b/solutions/leetcode/015-threeSum/official.md similarity index 100% rename from leetcode/015-threeSum/official.md rename to solutions/leetcode/015-threeSum/official.md diff --git a/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md b/solutions/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md similarity index 100% rename from leetcode/017-LetterCombinationsOfAPhoneNumber/README.md rename to solutions/leetcode/017-LetterCombinationsOfAPhoneNumber/README.md diff --git a/leetcode/020-validParentheses/official.md b/solutions/leetcode/020-validParentheses/official.md similarity index 100% rename from leetcode/020-validParentheses/official.md rename to solutions/leetcode/020-validParentheses/official.md diff --git a/leetcode/023-MergeKSortedLists/README.md b/solutions/leetcode/023-MergeKSortedLists/README.md similarity index 100% rename from leetcode/023-MergeKSortedLists/README.md rename to solutions/leetcode/023-MergeKSortedLists/README.md diff --git a/leetcode/024-swapNodesInPairs/official.md b/solutions/leetcode/024-swapNodesInPairs/official.md similarity index 100% rename from leetcode/024-swapNodesInPairs/official.md rename to solutions/leetcode/024-swapNodesInPairs/official.md diff --git a/leetcode/025-reverseNodesInKGroup/bigablecat.md b/solutions/leetcode/025-reverseNodesInKGroup/bigablecat.md similarity index 100% rename from leetcode/025-reverseNodesInKGroup/bigablecat.md rename to solutions/leetcode/025-reverseNodesInKGroup/bigablecat.md diff --git a/leetcode/025-reverseNodesInKGroup/official.md b/solutions/leetcode/025-reverseNodesInKGroup/official.md similarity index 100% rename from leetcode/025-reverseNodesInKGroup/official.md rename to solutions/leetcode/025-reverseNodesInKGroup/official.md diff --git a/leetcode/032-LongestValidParentheses/official.md b/solutions/leetcode/032-LongestValidParentheses/official.md similarity index 100% rename from leetcode/032-LongestValidParentheses/official.md rename to solutions/leetcode/032-LongestValidParentheses/official.md diff --git a/leetcode/033-SearchInRotatedSortedArray/README.md b/solutions/leetcode/033-SearchInRotatedSortedArray/README.md similarity index 100% rename from leetcode/033-SearchInRotatedSortedArray/README.md rename to solutions/leetcode/033-SearchInRotatedSortedArray/README.md diff --git a/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md b/solutions/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md similarity index 100% rename from leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md rename to solutions/leetcode/033-SearchInRotatedSortedArray/zengdiqing1994.md diff --git a/leetcode/036-ValidSudoku/SpecialYang.md b/solutions/leetcode/036-ValidSudoku/SpecialYang.md similarity index 100% rename from leetcode/036-ValidSudoku/SpecialYang.md rename to solutions/leetcode/036-ValidSudoku/SpecialYang.md diff --git a/leetcode/036-ValidSudoku/official.md b/solutions/leetcode/036-ValidSudoku/official.md similarity index 100% rename from leetcode/036-ValidSudoku/official.md rename to solutions/leetcode/036-ValidSudoku/official.md diff --git a/leetcode/037-SudokuSolver/SpecialYang.md b/solutions/leetcode/037-SudokuSolver/SpecialYang.md similarity index 100% rename from leetcode/037-SudokuSolver/SpecialYang.md rename to solutions/leetcode/037-SudokuSolver/SpecialYang.md diff --git a/leetcode/037-SudokuSolver/official.md b/solutions/leetcode/037-SudokuSolver/official.md similarity index 100% rename from leetcode/037-SudokuSolver/official.md rename to solutions/leetcode/037-SudokuSolver/official.md diff --git a/leetcode/048-RotateImage/README.md b/solutions/leetcode/048-RotateImage/README.md similarity index 100% rename from leetcode/048-RotateImage/README.md rename to solutions/leetcode/048-RotateImage/README.md diff --git a/leetcode/048-RotateImage/zengdiqing.md b/solutions/leetcode/048-RotateImage/zengdiqing.md similarity index 100% rename from leetcode/048-RotateImage/zengdiqing.md rename to solutions/leetcode/048-RotateImage/zengdiqing.md diff --git a/leetcode/050-powxN/bigablecat.md b/solutions/leetcode/050-powxN/bigablecat.md similarity index 100% rename from leetcode/050-powxN/bigablecat.md rename to solutions/leetcode/050-powxN/bigablecat.md diff --git a/leetcode/051-NQueens/melody-l.md b/solutions/leetcode/051-NQueens/melody-l.md similarity index 100% rename from leetcode/051-NQueens/melody-l.md rename to solutions/leetcode/051-NQueens/melody-l.md diff --git a/leetcode/051-NQueens/official.md b/solutions/leetcode/051-NQueens/official.md similarity index 100% rename from leetcode/051-NQueens/official.md rename to solutions/leetcode/051-NQueens/official.md diff --git a/leetcode/052-N-QueensII/hatrick.md b/solutions/leetcode/052-N-QueensII/hatrick.md similarity index 100% rename from leetcode/052-N-QueensII/hatrick.md rename to solutions/leetcode/052-N-QueensII/hatrick.md diff --git a/leetcode/052-N-QueensII/official.md b/solutions/leetcode/052-N-QueensII/official.md similarity index 100% rename from leetcode/052-N-QueensII/official.md rename to solutions/leetcode/052-N-QueensII/official.md diff --git a/leetcode/053-maximumSubarray/BambooYH.md b/solutions/leetcode/053-maximumSubarray/BambooYH.md similarity index 100% rename from leetcode/053-maximumSubarray/BambooYH.md rename to solutions/leetcode/053-maximumSubarray/BambooYH.md diff --git a/leetcode/053-maximumSubarray/README.md b/solutions/leetcode/053-maximumSubarray/README.md similarity index 100% rename from leetcode/053-maximumSubarray/README.md rename to solutions/leetcode/053-maximumSubarray/README.md diff --git a/leetcode/053-maximumSubarray/zengdiqing1994.md b/solutions/leetcode/053-maximumSubarray/zengdiqing1994.md similarity index 100% rename from leetcode/053-maximumSubarray/zengdiqing1994.md rename to solutions/leetcode/053-maximumSubarray/zengdiqing1994.md diff --git a/leetcode/054-SpiralMatrix/README.md b/solutions/leetcode/054-SpiralMatrix/README.md similarity index 100% rename from leetcode/054-SpiralMatrix/README.md rename to solutions/leetcode/054-SpiralMatrix/README.md diff --git a/leetcode/054-SpiralMatrix/zengdiqing1994.md b/solutions/leetcode/054-SpiralMatrix/zengdiqing1994.md similarity index 100% rename from leetcode/054-SpiralMatrix/zengdiqing1994.md rename to solutions/leetcode/054-SpiralMatrix/zengdiqing1994.md diff --git a/leetcode/059-SpiralMatrixII/README.md b/solutions/leetcode/059-SpiralMatrixII/README.md similarity index 100% rename from leetcode/059-SpiralMatrixII/README.md rename to solutions/leetcode/059-SpiralMatrixII/README.md diff --git a/leetcode/059-SpiralMatrixII/zengdiqing1994.md b/solutions/leetcode/059-SpiralMatrixII/zengdiqing1994.md similarity index 100% rename from leetcode/059-SpiralMatrixII/zengdiqing1994.md rename to solutions/leetcode/059-SpiralMatrixII/zengdiqing1994.md diff --git a/leetcode/062-UniquePaths/BambooYH.md b/solutions/leetcode/062-UniquePaths/BambooYH.md similarity index 100% rename from leetcode/062-UniquePaths/BambooYH.md rename to solutions/leetcode/062-UniquePaths/BambooYH.md diff --git a/leetcode/062-UniquePaths/official.md b/solutions/leetcode/062-UniquePaths/official.md similarity index 100% rename from leetcode/062-UniquePaths/official.md rename to solutions/leetcode/062-UniquePaths/official.md diff --git a/leetcode/063-UniquePathsII/SpecialYang.md b/solutions/leetcode/063-UniquePathsII/SpecialYang.md similarity index 100% rename from leetcode/063-UniquePathsII/SpecialYang.md rename to solutions/leetcode/063-UniquePathsII/SpecialYang.md diff --git a/leetcode/063-UniquePathsII/official.md b/solutions/leetcode/063-UniquePathsII/official.md similarity index 100% rename from leetcode/063-UniquePathsII/official.md rename to solutions/leetcode/063-UniquePathsII/official.md diff --git a/leetcode/064-minimumPathSum/README.md b/solutions/leetcode/064-minimumPathSum/README.md similarity index 100% rename from leetcode/064-minimumPathSum/README.md rename to solutions/leetcode/064-minimumPathSum/README.md diff --git a/leetcode/064-minimumPathSum/melody-l.md b/solutions/leetcode/064-minimumPathSum/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/064-minimumPathSum/melody-l.md rename to solutions/leetcode/064-minimumPathSum/melody-l.md diff --git a/leetcode/069-SqrtX/README.md b/solutions/leetcode/069-SqrtX/README.md similarity index 100% rename from leetcode/069-SqrtX/README.md rename to solutions/leetcode/069-SqrtX/README.md diff --git a/leetcode/069-SqrtX/bigablecat.md b/solutions/leetcode/069-SqrtX/bigablecat.md similarity index 100% rename from leetcode/069-SqrtX/bigablecat.md rename to solutions/leetcode/069-SqrtX/bigablecat.md diff --git a/leetcode/070-ClimbingStairs/README.md b/solutions/leetcode/070-ClimbingStairs/README.md similarity index 100% rename from leetcode/070-ClimbingStairs/README.md rename to solutions/leetcode/070-ClimbingStairs/README.md diff --git a/leetcode/070-ClimbingStairs/melody-l.md b/solutions/leetcode/070-ClimbingStairs/melody-l.md similarity index 100% rename from leetcode/070-ClimbingStairs/melody-l.md rename to solutions/leetcode/070-ClimbingStairs/melody-l.md diff --git a/leetcode/072-EditDistance/official.md b/solutions/leetcode/072-EditDistance/official.md similarity index 100% rename from leetcode/072-EditDistance/official.md rename to solutions/leetcode/072-EditDistance/official.md diff --git a/leetcode/075-SortColors/README.md b/solutions/leetcode/075-SortColors/README.md similarity index 100% rename from leetcode/075-SortColors/README.md rename to solutions/leetcode/075-SortColors/README.md diff --git a/leetcode/075-SortColors/bigablecat.md b/solutions/leetcode/075-SortColors/bigablecat.md similarity index 100% rename from leetcode/075-SortColors/bigablecat.md rename to solutions/leetcode/075-SortColors/bigablecat.md diff --git a/leetcode/076-MinimumWindowSubstring/README.md b/solutions/leetcode/076-MinimumWindowSubstring/README.md similarity index 100% rename from leetcode/076-MinimumWindowSubstring/README.md rename to solutions/leetcode/076-MinimumWindowSubstring/README.md diff --git a/leetcode/085-MaximalRectangle/passself.md b/solutions/leetcode/085-MaximalRectangle/passself.md similarity index 100% rename from leetcode/085-MaximalRectangle/passself.md rename to solutions/leetcode/085-MaximalRectangle/passself.md diff --git a/leetcode/087-ScrambleString/official.md b/solutions/leetcode/087-ScrambleString/official.md similarity index 100% rename from leetcode/087-ScrambleString/official.md rename to solutions/leetcode/087-ScrambleString/official.md diff --git a/leetcode/091-DecodeWays/melody-l.md b/solutions/leetcode/091-DecodeWays/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/091-DecodeWays/melody-l.md rename to solutions/leetcode/091-DecodeWays/melody-l.md diff --git a/leetcode/091-DecodeWays/official.md b/solutions/leetcode/091-DecodeWays/official.md similarity index 100% rename from leetcode/091-DecodeWays/official.md rename to solutions/leetcode/091-DecodeWays/official.md diff --git a/leetcode/091-DecodeWays/sandao.md b/solutions/leetcode/091-DecodeWays/sandao.md similarity index 100% rename from leetcode/091-DecodeWays/sandao.md rename to solutions/leetcode/091-DecodeWays/sandao.md diff --git a/leetcode/095-UniqueBinarySearchTreesII/melody-l.md b/solutions/leetcode/095-UniqueBinarySearchTreesII/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/095-UniqueBinarySearchTreesII/melody-l.md rename to solutions/leetcode/095-UniqueBinarySearchTreesII/melody-l.md diff --git a/leetcode/095-UniqueBinarySearchTreesII/official.md b/solutions/leetcode/095-UniqueBinarySearchTreesII/official.md similarity index 100% rename from leetcode/095-UniqueBinarySearchTreesII/official.md rename to solutions/leetcode/095-UniqueBinarySearchTreesII/official.md diff --git a/leetcode/096-uniqueBinarySearchTrees/official.md b/solutions/leetcode/096-uniqueBinarySearchTrees/official.md similarity index 100% rename from leetcode/096-uniqueBinarySearchTrees/official.md rename to solutions/leetcode/096-uniqueBinarySearchTrees/official.md diff --git a/leetcode/097-InterleavingString/official.md b/solutions/leetcode/097-InterleavingString/official.md similarity index 100% rename from leetcode/097-InterleavingString/official.md rename to solutions/leetcode/097-InterleavingString/official.md diff --git a/leetcode/098-validateBinarySearchTree/BambooYH.md b/solutions/leetcode/098-validateBinarySearchTree/BambooYH.md similarity index 100% rename from leetcode/098-validateBinarySearchTree/BambooYH.md rename to solutions/leetcode/098-validateBinarySearchTree/BambooYH.md diff --git a/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md b/solutions/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md similarity index 100% rename from leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md rename to solutions/leetcode/102-BinaryTreeLevelOrderTraversal/SpecialYang.md diff --git a/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md b/solutions/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md similarity index 100% rename from leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md rename to solutions/leetcode/102-BinaryTreeLevelOrderTraversal/hatrick.md diff --git a/leetcode/102-BinaryTreeLevelOrderTraversal/official.md b/solutions/leetcode/102-BinaryTreeLevelOrderTraversal/official.md similarity index 100% rename from leetcode/102-BinaryTreeLevelOrderTraversal/official.md rename to solutions/leetcode/102-BinaryTreeLevelOrderTraversal/official.md diff --git a/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md b/solutions/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md similarity index 100% rename from leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md rename to solutions/leetcode/102-BinaryTreeLevelOrderTraversal/zengdiqing1994.md diff --git a/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md b/solutions/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md similarity index 100% rename from leetcode/104-MaximumDepthOfBinaryTree/melody-l.md rename to solutions/leetcode/104-MaximumDepthOfBinaryTree/melody-l.md diff --git a/leetcode/104-MaximumDepthOfBinaryTree/official.md b/solutions/leetcode/104-MaximumDepthOfBinaryTree/official.md similarity index 100% rename from leetcode/104-MaximumDepthOfBinaryTree/official.md rename to solutions/leetcode/104-MaximumDepthOfBinaryTree/official.md diff --git a/leetcode/110-BalancedBinaryTree/README.md b/solutions/leetcode/110-BalancedBinaryTree/README.md similarity index 100% rename from leetcode/110-BalancedBinaryTree/README.md rename to solutions/leetcode/110-BalancedBinaryTree/README.md diff --git a/leetcode/110-BalancedBinaryTree/bigablecat.md b/solutions/leetcode/110-BalancedBinaryTree/bigablecat.md similarity index 100% rename from leetcode/110-BalancedBinaryTree/bigablecat.md rename to solutions/leetcode/110-BalancedBinaryTree/bigablecat.md diff --git a/leetcode/110-BalancedBinaryTree/zengdiqing1994.md b/solutions/leetcode/110-BalancedBinaryTree/zengdiqing1994.md similarity index 100% rename from leetcode/110-BalancedBinaryTree/zengdiqing1994.md rename to solutions/leetcode/110-BalancedBinaryTree/zengdiqing1994.md diff --git a/leetcode/115-DistinctSubsequences/official.md b/solutions/leetcode/115-DistinctSubsequences/official.md similarity index 100% rename from leetcode/115-DistinctSubsequences/official.md rename to solutions/leetcode/115-DistinctSubsequences/official.md diff --git a/leetcode/120-Triangle/melody-l.md b/solutions/leetcode/120-Triangle/melody-l.md similarity index 100% rename from leetcode/120-Triangle/melody-l.md rename to solutions/leetcode/120-Triangle/melody-l.md diff --git a/leetcode/120-Triangle/official.md b/solutions/leetcode/120-Triangle/official.md similarity index 100% rename from leetcode/120-Triangle/official.md rename to solutions/leetcode/120-Triangle/official.md diff --git a/leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md b/solutions/leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md similarity index 100% rename from leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md rename to solutions/leetcode/121-bestTimeToBuyAndSellStock/bigablecat.md diff --git a/leetcode/121-bestTimeToBuyAndSellStock/official.md b/solutions/leetcode/121-bestTimeToBuyAndSellStock/official.md similarity index 100% rename from leetcode/121-bestTimeToBuyAndSellStock/official.md rename to solutions/leetcode/121-bestTimeToBuyAndSellStock/official.md diff --git a/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md b/solutions/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md similarity index 100% rename from leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md rename to solutions/leetcode/122-bestTimeToBuyAndSellStockII/SpecialYang.md diff --git a/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md b/solutions/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md similarity index 100% rename from leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md rename to solutions/leetcode/122-bestTimeToBuyAndSellStockII/bigablecat.md diff --git a/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md b/solutions/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md similarity index 100% rename from leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md rename to solutions/leetcode/123-BestTimeToBuyAndSellStockIII/SpecialYang.md diff --git a/leetcode/123-BestTimeToBuyAndSellStockIII/official.md b/solutions/leetcode/123-BestTimeToBuyAndSellStockIII/official.md similarity index 100% rename from leetcode/123-BestTimeToBuyAndSellStockIII/official.md rename to solutions/leetcode/123-BestTimeToBuyAndSellStockIII/official.md diff --git a/leetcode/131-PalindromePartitioning/official.md b/solutions/leetcode/131-PalindromePartitioning/official.md similarity index 100% rename from leetcode/131-PalindromePartitioning/official.md rename to solutions/leetcode/131-PalindromePartitioning/official.md diff --git a/leetcode/132-PalindromePartitioningII/official.md b/solutions/leetcode/132-PalindromePartitioningII/official.md similarity index 100% rename from leetcode/132-PalindromePartitioningII/official.md rename to solutions/leetcode/132-PalindromePartitioningII/official.md diff --git a/leetcode/139-WordBreak/official.md b/solutions/leetcode/139-WordBreak/official.md similarity index 100% rename from leetcode/139-WordBreak/official.md rename to solutions/leetcode/139-WordBreak/official.md diff --git a/leetcode/140-WordBreakII/official.md b/solutions/leetcode/140-WordBreakII/official.md similarity index 100% rename from leetcode/140-WordBreakII/official.md rename to solutions/leetcode/140-WordBreakII/official.md diff --git a/leetcode/141-linkedListCycle/official.md b/solutions/leetcode/141-linkedListCycle/official.md similarity index 100% rename from leetcode/141-linkedListCycle/official.md rename to solutions/leetcode/141-linkedListCycle/official.md diff --git a/leetcode/142-linkedListCycleII/bigablecat.md b/solutions/leetcode/142-linkedListCycleII/bigablecat.md similarity index 100% rename from leetcode/142-linkedListCycleII/bigablecat.md rename to solutions/leetcode/142-linkedListCycleII/bigablecat.md diff --git a/leetcode/142-linkedListCycleII/official.md b/solutions/leetcode/142-linkedListCycleII/official.md similarity index 100% rename from leetcode/142-linkedListCycleII/official.md rename to solutions/leetcode/142-linkedListCycleII/official.md diff --git a/leetcode/144-BinaryTreePreorderTraversal/README.md b/solutions/leetcode/144-BinaryTreePreorderTraversal/README.md similarity index 100% rename from leetcode/144-BinaryTreePreorderTraversal/README.md rename to solutions/leetcode/144-BinaryTreePreorderTraversal/README.md diff --git a/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md b/solutions/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md similarity index 100% rename from leetcode/144-BinaryTreePreorderTraversal/bigablecat.md rename to solutions/leetcode/144-BinaryTreePreorderTraversal/bigablecat.md diff --git a/leetcode/146-lruCache/hatrick.md b/solutions/leetcode/146-lruCache/hatrick.md similarity index 100% rename from leetcode/146-lruCache/hatrick.md rename to solutions/leetcode/146-lruCache/hatrick.md diff --git a/leetcode/146-lruCache/official.md b/solutions/leetcode/146-lruCache/official.md similarity index 100% rename from leetcode/146-lruCache/official.md rename to solutions/leetcode/146-lruCache/official.md diff --git a/leetcode/152-MaximumProductSubarray/README.md b/solutions/leetcode/152-MaximumProductSubarray/README.md similarity index 100% rename from leetcode/152-MaximumProductSubarray/README.md rename to solutions/leetcode/152-MaximumProductSubarray/README.md diff --git a/leetcode/152-MaximumProductSubarray/SpecialYang.md b/solutions/leetcode/152-MaximumProductSubarray/SpecialYang.md similarity index 100% rename from leetcode/152-MaximumProductSubarray/SpecialYang.md rename to solutions/leetcode/152-MaximumProductSubarray/SpecialYang.md diff --git a/leetcode/152-MaximumProductSubarray/zengdiqing1994.md b/solutions/leetcode/152-MaximumProductSubarray/zengdiqing1994.md similarity index 100% rename from leetcode/152-MaximumProductSubarray/zengdiqing1994.md rename to solutions/leetcode/152-MaximumProductSubarray/zengdiqing1994.md diff --git a/leetcode/153-FindMinimumInRotatedSortedArray/README.md b/solutions/leetcode/153-FindMinimumInRotatedSortedArray/README.md similarity index 100% rename from leetcode/153-FindMinimumInRotatedSortedArray/README.md rename to solutions/leetcode/153-FindMinimumInRotatedSortedArray/README.md diff --git a/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md b/solutions/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md similarity index 100% rename from leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md rename to solutions/leetcode/153-FindMinimumInRotatedSortedArray/zengdiqing1994.md diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/README.md b/solutions/leetcode/160-IntersectionOfTwoLinkedLists/README.md similarity index 100% rename from leetcode/160-IntersectionOfTwoLinkedLists/README.md rename to solutions/leetcode/160-IntersectionOfTwoLinkedLists/README.md diff --git a/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md b/solutions/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md similarity index 100% rename from leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md rename to solutions/leetcode/160-IntersectionOfTwoLinkedLists/bigablecat.md diff --git a/leetcode/167-TwoSumII/README.md b/solutions/leetcode/167-TwoSumII/README.md similarity index 100% rename from leetcode/167-TwoSumII/README.md rename to solutions/leetcode/167-TwoSumII/README.md diff --git a/leetcode/167-TwoSumII/bigablecat.md b/solutions/leetcode/167-TwoSumII/bigablecat.md similarity index 100% rename from leetcode/167-TwoSumII/bigablecat.md rename to solutions/leetcode/167-TwoSumII/bigablecat.md diff --git a/leetcode/169-majorityElement/README.md b/solutions/leetcode/169-majorityElement/README.md similarity index 100% rename from leetcode/169-majorityElement/README.md rename to solutions/leetcode/169-majorityElement/README.md diff --git a/leetcode/169-majorityElement/SpecialYang.md b/solutions/leetcode/169-majorityElement/SpecialYang.md similarity index 100% rename from leetcode/169-majorityElement/SpecialYang.md rename to solutions/leetcode/169-majorityElement/SpecialYang.md diff --git a/leetcode/169-majorityElement/bigablecat.md b/solutions/leetcode/169-majorityElement/bigablecat.md similarity index 100% rename from leetcode/169-majorityElement/bigablecat.md rename to solutions/leetcode/169-majorityElement/bigablecat.md diff --git a/leetcode/169-majorityElement/zengdiqing1994.md b/solutions/leetcode/169-majorityElement/zengdiqing1994.md similarity index 100% rename from leetcode/169-majorityElement/zengdiqing1994.md rename to solutions/leetcode/169-majorityElement/zengdiqing1994.md diff --git a/leetcode/174-DungeonGame/passself.md b/solutions/leetcode/174-DungeonGame/passself.md similarity index 100% rename from leetcode/174-DungeonGame/passself.md rename to solutions/leetcode/174-DungeonGame/passself.md diff --git a/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md b/solutions/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md similarity index 100% rename from leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md rename to solutions/leetcode/188-bestTimeToBuyAndSellStockIV/BambooYH.md diff --git a/leetcode/188-bestTimeToBuyAndSellStockIV/official.md b/solutions/leetcode/188-bestTimeToBuyAndSellStockIV/official.md similarity index 100% rename from leetcode/188-bestTimeToBuyAndSellStockIV/official.md rename to solutions/leetcode/188-bestTimeToBuyAndSellStockIV/official.md diff --git a/leetcode/191-NumberOf1Bits/README.md b/solutions/leetcode/191-NumberOf1Bits/README.md similarity index 100% rename from leetcode/191-NumberOf1Bits/README.md rename to solutions/leetcode/191-NumberOf1Bits/README.md diff --git a/leetcode/191-NumberOf1Bits/bigablecat.md b/solutions/leetcode/191-NumberOf1Bits/bigablecat.md similarity index 100% rename from leetcode/191-NumberOf1Bits/bigablecat.md rename to solutions/leetcode/191-NumberOf1Bits/bigablecat.md diff --git a/leetcode/198-houseRobber/README.md b/solutions/leetcode/198-houseRobber/README.md similarity index 100% rename from leetcode/198-houseRobber/README.md rename to solutions/leetcode/198-houseRobber/README.md diff --git a/leetcode/198-houseRobber/hatrick.md b/solutions/leetcode/198-houseRobber/hatrick.md similarity index 100% rename from leetcode/198-houseRobber/hatrick.md rename to solutions/leetcode/198-houseRobber/hatrick.md diff --git a/leetcode/200-numberOfIslands/BambooYH.md b/solutions/leetcode/200-numberOfIslands/BambooYH.md similarity index 100% rename from leetcode/200-numberOfIslands/BambooYH.md rename to solutions/leetcode/200-numberOfIslands/BambooYH.md diff --git a/leetcode/200-numberOfIslands/official.md b/solutions/leetcode/200-numberOfIslands/official.md similarity index 100% rename from leetcode/200-numberOfIslands/official.md rename to solutions/leetcode/200-numberOfIslands/official.md diff --git a/leetcode/206-reverseLinkedList/official.md b/solutions/leetcode/206-reverseLinkedList/official.md similarity index 100% rename from leetcode/206-reverseLinkedList/official.md rename to solutions/leetcode/206-reverseLinkedList/official.md diff --git a/leetcode/207-CourseSchedule/README.md b/solutions/leetcode/207-CourseSchedule/README.md similarity index 100% rename from leetcode/207-CourseSchedule/README.md rename to solutions/leetcode/207-CourseSchedule/README.md diff --git a/leetcode/207-CourseSchedule/bigablecat.md b/solutions/leetcode/207-CourseSchedule/bigablecat.md similarity index 100% rename from leetcode/207-CourseSchedule/bigablecat.md rename to solutions/leetcode/207-CourseSchedule/bigablecat.md diff --git a/leetcode/208-implementTriePrefixTree/README.md b/solutions/leetcode/208-implementTriePrefixTree/README.md similarity index 100% rename from leetcode/208-implementTriePrefixTree/README.md rename to solutions/leetcode/208-implementTriePrefixTree/README.md diff --git a/leetcode/208-implementTriePrefixTree/bigablecat.md b/solutions/leetcode/208-implementTriePrefixTree/bigablecat.md similarity index 100% rename from leetcode/208-implementTriePrefixTree/bigablecat.md rename to solutions/leetcode/208-implementTriePrefixTree/bigablecat.md diff --git a/leetcode/212-wordSearchII/official.md b/solutions/leetcode/212-wordSearchII/official.md similarity index 100% rename from leetcode/212-wordSearchII/official.md rename to solutions/leetcode/212-wordSearchII/official.md diff --git a/leetcode/213-HouseRobberII/SpecialYang.md b/solutions/leetcode/213-HouseRobberII/SpecialYang.md similarity index 100% rename from leetcode/213-HouseRobberII/SpecialYang.md rename to solutions/leetcode/213-HouseRobberII/SpecialYang.md diff --git a/leetcode/213-HouseRobberII/official.md b/solutions/leetcode/213-HouseRobberII/official.md similarity index 100% rename from leetcode/213-HouseRobberII/official.md rename to solutions/leetcode/213-HouseRobberII/official.md diff --git a/leetcode/215-KthLargestElementInAnArray/BambooYH.md b/solutions/leetcode/215-KthLargestElementInAnArray/BambooYH.md similarity index 100% rename from leetcode/215-KthLargestElementInAnArray/BambooYH.md rename to solutions/leetcode/215-KthLargestElementInAnArray/BambooYH.md diff --git a/leetcode/215-KthLargestElementInAnArray/README.md b/solutions/leetcode/215-KthLargestElementInAnArray/README.md similarity index 100% rename from leetcode/215-KthLargestElementInAnArray/README.md rename to solutions/leetcode/215-KthLargestElementInAnArray/README.md diff --git a/leetcode/215-KthLargestElementInAnArray/bigablecat.md b/solutions/leetcode/215-KthLargestElementInAnArray/bigablecat.md similarity index 100% rename from leetcode/215-KthLargestElementInAnArray/bigablecat.md rename to solutions/leetcode/215-KthLargestElementInAnArray/bigablecat.md diff --git a/leetcode/221-MaximalSquare/official.md b/solutions/leetcode/221-MaximalSquare/official.md similarity index 100% rename from leetcode/221-MaximalSquare/official.md rename to solutions/leetcode/221-MaximalSquare/official.md diff --git a/leetcode/225-implementStackUsingQueues/hatrick.md b/solutions/leetcode/225-implementStackUsingQueues/hatrick.md similarity index 100% rename from leetcode/225-implementStackUsingQueues/hatrick.md rename to solutions/leetcode/225-implementStackUsingQueues/hatrick.md diff --git a/leetcode/225-implementStackUsingQueues/official.md b/solutions/leetcode/225-implementStackUsingQueues/official.md similarity index 100% rename from leetcode/225-implementStackUsingQueues/official.md rename to solutions/leetcode/225-implementStackUsingQueues/official.md diff --git a/leetcode/230-KthSmallestElementInABST/README.md b/solutions/leetcode/230-KthSmallestElementInABST/README.md similarity index 100% rename from leetcode/230-KthSmallestElementInABST/README.md rename to solutions/leetcode/230-KthSmallestElementInABST/README.md diff --git a/leetcode/230-KthSmallestElementInABST/bigablecat.md b/solutions/leetcode/230-KthSmallestElementInABST/bigablecat.md similarity index 100% rename from leetcode/230-KthSmallestElementInABST/bigablecat.md rename to solutions/leetcode/230-KthSmallestElementInABST/bigablecat.md diff --git a/leetcode/231-PowerOfTwo/hatrick.md b/solutions/leetcode/231-PowerOfTwo/hatrick.md similarity index 100% rename from leetcode/231-PowerOfTwo/hatrick.md rename to solutions/leetcode/231-PowerOfTwo/hatrick.md diff --git a/leetcode/231-PowerOfTwo/official.md b/solutions/leetcode/231-PowerOfTwo/official.md similarity index 100% rename from leetcode/231-PowerOfTwo/official.md rename to solutions/leetcode/231-PowerOfTwo/official.md diff --git a/leetcode/232-implementQueueUsingStacks/README.md b/solutions/leetcode/232-implementQueueUsingStacks/README.md similarity index 100% rename from leetcode/232-implementQueueUsingStacks/README.md rename to solutions/leetcode/232-implementQueueUsingStacks/README.md diff --git a/leetcode/232-implementQueueUsingStacks/hatrick.md b/solutions/leetcode/232-implementQueueUsingStacks/hatrick.md similarity index 100% rename from leetcode/232-implementQueueUsingStacks/hatrick.md rename to solutions/leetcode/232-implementQueueUsingStacks/hatrick.md diff --git a/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md b/solutions/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md similarity index 100% rename from leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md rename to solutions/leetcode/236-lowestCommonAncestorOfABinaryTree/BambooYH.md diff --git a/leetcode/239-slidingWindowMaximum/official.md b/solutions/leetcode/239-slidingWindowMaximum/official.md similarity index 100% rename from leetcode/239-slidingWindowMaximum/official.md rename to solutions/leetcode/239-slidingWindowMaximum/official.md diff --git a/leetcode/241-DifferentWaysToAddParentheses/README.md b/solutions/leetcode/241-DifferentWaysToAddParentheses/README.md similarity index 100% rename from leetcode/241-DifferentWaysToAddParentheses/README.md rename to solutions/leetcode/241-DifferentWaysToAddParentheses/README.md diff --git a/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md b/solutions/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md similarity index 100% rename from leetcode/241-DifferentWaysToAddParentheses/bigablecat.md rename to solutions/leetcode/241-DifferentWaysToAddParentheses/bigablecat.md diff --git a/leetcode/242-ValidAnagram/README.md b/solutions/leetcode/242-ValidAnagram/README.md similarity index 100% rename from leetcode/242-ValidAnagram/README.md rename to solutions/leetcode/242-ValidAnagram/README.md diff --git a/leetcode/242-ValidAnagram/bigablecat.md b/solutions/leetcode/242-ValidAnagram/bigablecat.md similarity index 100% rename from leetcode/242-ValidAnagram/bigablecat.md rename to solutions/leetcode/242-ValidAnagram/bigablecat.md diff --git a/leetcode/242-ValidAnagram/zengdiqing1994.md b/solutions/leetcode/242-ValidAnagram/zengdiqing1994.md similarity index 100% rename from leetcode/242-ValidAnagram/zengdiqing1994.md rename to solutions/leetcode/242-ValidAnagram/zengdiqing1994.md diff --git a/leetcode/260-SingleNumberIII/README.md b/solutions/leetcode/260-SingleNumberIII/README.md similarity index 100% rename from leetcode/260-SingleNumberIII/README.md rename to solutions/leetcode/260-SingleNumberIII/README.md diff --git a/leetcode/260-SingleNumberIII/zengdiqing1994.md b/solutions/leetcode/260-SingleNumberIII/zengdiqing1994.md similarity index 100% rename from leetcode/260-SingleNumberIII/zengdiqing1994.md rename to solutions/leetcode/260-SingleNumberIII/zengdiqing1994.md diff --git a/leetcode/264-UglyNumberII/bigablecat.md b/solutions/leetcode/264-UglyNumberII/bigablecat.md similarity index 100% rename from leetcode/264-UglyNumberII/bigablecat.md rename to solutions/leetcode/264-UglyNumberII/bigablecat.md diff --git a/leetcode/264-UglyNumberII/official.md b/solutions/leetcode/264-UglyNumberII/official.md similarity index 100% rename from leetcode/264-UglyNumberII/official.md rename to solutions/leetcode/264-UglyNumberII/official.md diff --git a/leetcode/279-PerfectSquares/README.md b/solutions/leetcode/279-PerfectSquares/README.md similarity index 100% rename from leetcode/279-PerfectSquares/README.md rename to solutions/leetcode/279-PerfectSquares/README.md diff --git a/leetcode/279-PerfectSquares/bigablecat.md b/solutions/leetcode/279-PerfectSquares/bigablecat.md similarity index 100% rename from leetcode/279-PerfectSquares/bigablecat.md rename to solutions/leetcode/279-PerfectSquares/bigablecat.md diff --git a/leetcode/279-PerfectSquares/zengdiqing1994.md b/solutions/leetcode/279-PerfectSquares/zengdiqing1994.md similarity index 100% rename from leetcode/279-PerfectSquares/zengdiqing1994.md rename to solutions/leetcode/279-PerfectSquares/zengdiqing1994.md diff --git a/leetcode/295-FindMedianFromDataStream/BambooYH.md b/solutions/leetcode/295-FindMedianFromDataStream/BambooYH.md similarity index 100% rename from leetcode/295-FindMedianFromDataStream/BambooYH.md rename to solutions/leetcode/295-FindMedianFromDataStream/BambooYH.md diff --git a/leetcode/300-LongestIncreasingSubsequence/README.md b/solutions/leetcode/300-LongestIncreasingSubsequence/README.md similarity index 100% rename from leetcode/300-LongestIncreasingSubsequence/README.md rename to solutions/leetcode/300-LongestIncreasingSubsequence/README.md diff --git a/leetcode/300-LongestIncreasingSubsequence/melody-l.md b/solutions/leetcode/300-LongestIncreasingSubsequence/melody-l.md similarity index 100% rename from leetcode/300-LongestIncreasingSubsequence/melody-l.md rename to solutions/leetcode/300-LongestIncreasingSubsequence/melody-l.md diff --git a/leetcode/303-rangeSumQueryImmutable/BambooYH.md b/solutions/leetcode/303-rangeSumQueryImmutable/BambooYH.md similarity index 100% rename from leetcode/303-rangeSumQueryImmutable/BambooYH.md rename to solutions/leetcode/303-rangeSumQueryImmutable/BambooYH.md diff --git a/leetcode/303-rangeSumQueryImmutable/README.md b/solutions/leetcode/303-rangeSumQueryImmutable/README.md similarity index 100% rename from leetcode/303-rangeSumQueryImmutable/README.md rename to solutions/leetcode/303-rangeSumQueryImmutable/README.md diff --git a/leetcode/304-RangeSumQuery2DImmutable/official.md b/solutions/leetcode/304-RangeSumQuery2DImmutable/official.md similarity index 100% rename from leetcode/304-RangeSumQuery2DImmutable/official.md rename to solutions/leetcode/304-RangeSumQuery2DImmutable/official.md diff --git a/leetcode/304-RangeSumQuery2DImmutable/woody.md b/solutions/leetcode/304-RangeSumQuery2DImmutable/woody.md similarity index 100% rename from leetcode/304-RangeSumQuery2DImmutable/woody.md rename to solutions/leetcode/304-RangeSumQuery2DImmutable/woody.md diff --git a/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md b/solutions/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md similarity index 100% rename from leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md rename to solutions/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/README.md diff --git a/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md b/solutions/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md similarity index 100% rename from leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md rename to solutions/leetcode/309-BestTimeToBuyAndSellStockWithCooldown/bigablecat.md diff --git a/leetcode/312-BurstBalloons/melody-l.md b/solutions/leetcode/312-BurstBalloons/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/312-BurstBalloons/melody-l.md rename to solutions/leetcode/312-BurstBalloons/melody-l.md diff --git a/leetcode/312-BurstBalloons/official.md b/solutions/leetcode/312-BurstBalloons/official.md similarity index 100% rename from leetcode/312-BurstBalloons/official.md rename to solutions/leetcode/312-BurstBalloons/official.md diff --git a/leetcode/321-CreateMaximumNumber/README.md b/solutions/leetcode/321-CreateMaximumNumber/README.md similarity index 100% rename from leetcode/321-CreateMaximumNumber/README.md rename to solutions/leetcode/321-CreateMaximumNumber/README.md diff --git a/leetcode/322-CoinChange/official.md b/solutions/leetcode/322-CoinChange/official.md similarity index 100% rename from leetcode/322-CoinChange/official.md rename to solutions/leetcode/322-CoinChange/official.md diff --git a/leetcode/338-CountingBits/bigablecat.md b/solutions/leetcode/338-CountingBits/bigablecat.md similarity index 100% rename from leetcode/338-CountingBits/bigablecat.md rename to solutions/leetcode/338-CountingBits/bigablecat.md diff --git a/leetcode/343-IntegerBreak/README.md b/solutions/leetcode/343-IntegerBreak/README.md similarity index 100% rename from leetcode/343-IntegerBreak/README.md rename to solutions/leetcode/343-IntegerBreak/README.md diff --git a/leetcode/343-IntegerBreak/hatrick.md b/solutions/leetcode/343-IntegerBreak/hatrick.md similarity index 100% rename from leetcode/343-IntegerBreak/hatrick.md rename to solutions/leetcode/343-IntegerBreak/hatrick.md diff --git a/leetcode/347-TopKFrequentElements/README.md b/solutions/leetcode/347-TopKFrequentElements/README.md similarity index 100% rename from leetcode/347-TopKFrequentElements/README.md rename to solutions/leetcode/347-TopKFrequentElements/README.md diff --git a/leetcode/347-TopKFrequentElements/bigablecat.md b/solutions/leetcode/347-TopKFrequentElements/bigablecat.md similarity index 100% rename from leetcode/347-TopKFrequentElements/bigablecat.md rename to solutions/leetcode/347-TopKFrequentElements/bigablecat.md diff --git a/leetcode/354-RussianDollEnvelopes/official.md b/solutions/leetcode/354-RussianDollEnvelopes/official.md similarity index 100% rename from leetcode/354-RussianDollEnvelopes/official.md rename to solutions/leetcode/354-RussianDollEnvelopes/official.md diff --git a/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md b/solutions/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md similarity index 100% rename from leetcode/354-RussianDollEnvelopes/zengdiqing1994.md rename to solutions/leetcode/354-RussianDollEnvelopes/zengdiqing1994.md diff --git a/leetcode/357-CountNumbersWithUniqueDigits/official.md b/solutions/leetcode/357-CountNumbersWithUniqueDigits/official.md similarity index 100% rename from leetcode/357-CountNumbersWithUniqueDigits/official.md rename to solutions/leetcode/357-CountNumbersWithUniqueDigits/official.md diff --git a/leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md b/solutions/leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md similarity index 100% rename from leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md rename to solutions/leetcode/363-MaxSumOfRectangleNoLargerThanK/official.md diff --git a/leetcode/367-ValidPerfectSquare/official.md b/solutions/leetcode/367-ValidPerfectSquare/official.md similarity index 100% rename from leetcode/367-ValidPerfectSquare/official.md rename to solutions/leetcode/367-ValidPerfectSquare/official.md diff --git a/leetcode/368-LargestDivisibleSubset/passself.md b/solutions/leetcode/368-LargestDivisibleSubset/passself.md similarity index 100% rename from leetcode/368-LargestDivisibleSubset/passself.md rename to solutions/leetcode/368-LargestDivisibleSubset/passself.md diff --git a/leetcode/374-GuessNumberHigherOrLower/official.md b/solutions/leetcode/374-GuessNumberHigherOrLower/official.md similarity index 100% rename from leetcode/374-GuessNumberHigherOrLower/official.md rename to solutions/leetcode/374-GuessNumberHigherOrLower/official.md diff --git a/leetcode/375-GuessNumberHigherOrLowerII/official.md b/solutions/leetcode/375-GuessNumberHigherOrLowerII/official.md similarity index 100% rename from leetcode/375-GuessNumberHigherOrLowerII/official.md rename to solutions/leetcode/375-GuessNumberHigherOrLowerII/official.md diff --git a/leetcode/376-WiggleSubsequence/melody-l.md b/solutions/leetcode/376-WiggleSubsequence/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/376-WiggleSubsequence/melody-l.md rename to solutions/leetcode/376-WiggleSubsequence/melody-l.md diff --git a/leetcode/376-WiggleSubsequence/official.md b/solutions/leetcode/376-WiggleSubsequence/official.md similarity index 100% rename from leetcode/376-WiggleSubsequence/official.md rename to solutions/leetcode/376-WiggleSubsequence/official.md diff --git a/leetcode/377-CombinationSumIV/official.md b/solutions/leetcode/377-CombinationSumIV/official.md similarity index 100% rename from leetcode/377-CombinationSumIV/official.md rename to solutions/leetcode/377-CombinationSumIV/official.md diff --git a/leetcode/378-KthSmallestElementInASortedMatrix/README.md b/solutions/leetcode/378-KthSmallestElementInASortedMatrix/README.md similarity index 100% rename from leetcode/378-KthSmallestElementInASortedMatrix/README.md rename to solutions/leetcode/378-KthSmallestElementInASortedMatrix/README.md diff --git a/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md b/solutions/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md similarity index 100% rename from leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md rename to solutions/leetcode/378-KthSmallestElementInASortedMatrix/zengdiqing1994.md diff --git a/leetcode/392-IsSubsequence/official.md b/solutions/leetcode/392-IsSubsequence/official.md similarity index 100% rename from leetcode/392-IsSubsequence/official.md rename to solutions/leetcode/392-IsSubsequence/official.md diff --git a/leetcode/392-IsSubsequence/zengdiqing1994.md b/solutions/leetcode/392-IsSubsequence/zengdiqing1994.md similarity index 100% rename from leetcode/392-IsSubsequence/zengdiqing1994.md rename to solutions/leetcode/392-IsSubsequence/zengdiqing1994.md diff --git a/leetcode/403-FrogJump/README.md b/solutions/leetcode/403-FrogJump/README.md similarity index 100% rename from leetcode/403-FrogJump/README.md rename to solutions/leetcode/403-FrogJump/README.md diff --git a/leetcode/409-LongestPalindrome/README.md b/solutions/leetcode/409-LongestPalindrome/README.md similarity index 100% rename from leetcode/409-LongestPalindrome/README.md rename to solutions/leetcode/409-LongestPalindrome/README.md diff --git a/leetcode/409-LongestPalindrome/zengdiqing1994.md b/solutions/leetcode/409-LongestPalindrome/zengdiqing1994.md similarity index 100% rename from leetcode/409-LongestPalindrome/zengdiqing1994.md rename to solutions/leetcode/409-LongestPalindrome/zengdiqing1994.md diff --git a/leetcode/410-SplitArrayLargestSum/hatrick.md b/solutions/leetcode/410-SplitArrayLargestSum/hatrick.md similarity index 100% rename from leetcode/410-SplitArrayLargestSum/hatrick.md rename to solutions/leetcode/410-SplitArrayLargestSum/hatrick.md diff --git a/leetcode/410-SplitArrayLargestSum/official.md b/solutions/leetcode/410-SplitArrayLargestSum/official.md similarity index 100% rename from leetcode/410-SplitArrayLargestSum/official.md rename to solutions/leetcode/410-SplitArrayLargestSum/official.md diff --git a/leetcode/413-arithmeticSlices/official.md b/solutions/leetcode/413-arithmeticSlices/official.md similarity index 100% rename from leetcode/413-arithmeticSlices/official.md rename to solutions/leetcode/413-arithmeticSlices/official.md diff --git a/leetcode/416-PartitionEqualSubsetSum/README.md b/solutions/leetcode/416-PartitionEqualSubsetSum/README.md similarity index 100% rename from leetcode/416-PartitionEqualSubsetSum/README.md rename to solutions/leetcode/416-PartitionEqualSubsetSum/README.md diff --git a/leetcode/416-PartitionEqualSubsetSum/bigablecat.md b/solutions/leetcode/416-PartitionEqualSubsetSum/bigablecat.md similarity index 100% rename from leetcode/416-PartitionEqualSubsetSum/bigablecat.md rename to solutions/leetcode/416-PartitionEqualSubsetSum/bigablecat.md diff --git a/leetcode/446-ArithmeticSlicesIISubsequence/official.md b/solutions/leetcode/446-ArithmeticSlicesIISubsequence/official.md similarity index 100% rename from leetcode/446-ArithmeticSlicesIISubsequence/official.md rename to solutions/leetcode/446-ArithmeticSlicesIISubsequence/official.md diff --git a/leetcode/455-AssignCookies/README.md b/solutions/leetcode/455-AssignCookies/README.md similarity index 100% rename from leetcode/455-AssignCookies/README.md rename to solutions/leetcode/455-AssignCookies/README.md diff --git a/leetcode/455-AssignCookies/SpecialYang.md b/solutions/leetcode/455-AssignCookies/SpecialYang.md similarity index 100% rename from leetcode/455-AssignCookies/SpecialYang.md rename to solutions/leetcode/455-AssignCookies/SpecialYang.md diff --git a/leetcode/455-AssignCookies/bigablecat.md b/solutions/leetcode/455-AssignCookies/bigablecat.md similarity index 100% rename from leetcode/455-AssignCookies/bigablecat.md rename to solutions/leetcode/455-AssignCookies/bigablecat.md diff --git a/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md b/solutions/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md similarity index 100% rename from leetcode/462-MinimumMovesToEqualArrayElementsII/README.md rename to solutions/leetcode/462-MinimumMovesToEqualArrayElementsII/README.md diff --git a/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md b/solutions/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md similarity index 100% rename from leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md rename to solutions/leetcode/462-MinimumMovesToEqualArrayElementsII/zengdiqing1994.md diff --git a/leetcode/464-CanIWin/official.md b/solutions/leetcode/464-CanIWin/official.md similarity index 100% rename from leetcode/464-CanIWin/official.md rename to solutions/leetcode/464-CanIWin/official.md diff --git a/leetcode/467-UniqueSubstringsInWraparoundString/passself.md b/solutions/leetcode/467-UniqueSubstringsInWraparoundString/passself.md similarity index 100% rename from leetcode/467-UniqueSubstringsInWraparoundString/passself.md rename to solutions/leetcode/467-UniqueSubstringsInWraparoundString/passself.md diff --git a/leetcode/472-ConcatenatedWords/official.md b/solutions/leetcode/472-ConcatenatedWords/official.md similarity index 100% rename from leetcode/472-ConcatenatedWords/official.md rename to solutions/leetcode/472-ConcatenatedWords/official.md diff --git a/leetcode/474-OnesAndZeroes/hatrick.md b/solutions/leetcode/474-OnesAndZeroes/hatrick.md similarity index 100% rename from leetcode/474-OnesAndZeroes/hatrick.md rename to solutions/leetcode/474-OnesAndZeroes/hatrick.md diff --git a/leetcode/474-OnesAndZeroes/official.md b/solutions/leetcode/474-OnesAndZeroes/official.md similarity index 100% rename from leetcode/474-OnesAndZeroes/official.md rename to solutions/leetcode/474-OnesAndZeroes/official.md diff --git a/leetcode/486-PredictTheWinner/official.md b/solutions/leetcode/486-PredictTheWinner/official.md similarity index 100% rename from leetcode/486-PredictTheWinner/official.md rename to solutions/leetcode/486-PredictTheWinner/official.md diff --git a/leetcode/494-TargetSum/official.md b/solutions/leetcode/494-TargetSum/official.md similarity index 100% rename from leetcode/494-TargetSum/official.md rename to solutions/leetcode/494-TargetSum/official.md diff --git a/leetcode/504-Base7/README.md b/solutions/leetcode/504-Base7/README.md similarity index 100% rename from leetcode/504-Base7/README.md rename to solutions/leetcode/504-Base7/README.md diff --git a/leetcode/504-Base7/zengdiqing1994.md b/solutions/leetcode/504-Base7/zengdiqing1994.md similarity index 100% rename from leetcode/504-Base7/zengdiqing1994.md rename to solutions/leetcode/504-Base7/zengdiqing1994.md diff --git a/leetcode/513-FindBottomLeftTreeValue/README.md b/solutions/leetcode/513-FindBottomLeftTreeValue/README.md similarity index 100% rename from leetcode/513-FindBottomLeftTreeValue/README.md rename to solutions/leetcode/513-FindBottomLeftTreeValue/README.md diff --git a/leetcode/513-FindBottomLeftTreeValue/bigablecat.md b/solutions/leetcode/513-FindBottomLeftTreeValue/bigablecat.md similarity index 100% rename from leetcode/513-FindBottomLeftTreeValue/bigablecat.md rename to solutions/leetcode/513-FindBottomLeftTreeValue/bigablecat.md diff --git a/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md b/solutions/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md similarity index 100% rename from leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md rename to solutions/leetcode/513-FindBottomLeftTreeValue/zengdiqing1994.md diff --git a/leetcode/514-FreedomTrail/hatrick.md b/solutions/leetcode/514-FreedomTrail/hatrick.md similarity index 100% rename from leetcode/514-FreedomTrail/hatrick.md rename to solutions/leetcode/514-FreedomTrail/hatrick.md diff --git a/leetcode/514-FreedomTrail/official.md b/solutions/leetcode/514-FreedomTrail/official.md similarity index 100% rename from leetcode/514-FreedomTrail/official.md rename to solutions/leetcode/514-FreedomTrail/official.md diff --git a/leetcode/516-LongestPalindromicSubsequence/passself.md b/solutions/leetcode/516-LongestPalindromicSubsequence/passself.md similarity index 100% rename from leetcode/516-LongestPalindromicSubsequence/passself.md rename to solutions/leetcode/516-LongestPalindromicSubsequence/passself.md diff --git a/leetcode/517-SuperWashingMachines/official.md b/solutions/leetcode/517-SuperWashingMachines/official.md similarity index 100% rename from leetcode/517-SuperWashingMachines/official.md rename to solutions/leetcode/517-SuperWashingMachines/official.md diff --git a/leetcode/523-ContinuousSubarraySum/hatrick.md b/solutions/leetcode/523-ContinuousSubarraySum/hatrick.md similarity index 100% rename from leetcode/523-ContinuousSubarraySum/hatrick.md rename to solutions/leetcode/523-ContinuousSubarraySum/hatrick.md diff --git a/leetcode/523-ContinuousSubarraySum/official.md b/solutions/leetcode/523-ContinuousSubarraySum/official.md similarity index 100% rename from leetcode/523-ContinuousSubarraySum/official.md rename to solutions/leetcode/523-ContinuousSubarraySum/official.md diff --git a/leetcode/546-RemoveBoxes/passself.md b/solutions/leetcode/546-RemoveBoxes/passself.md similarity index 100% rename from leetcode/546-RemoveBoxes/passself.md rename to solutions/leetcode/546-RemoveBoxes/passself.md diff --git a/leetcode/547-friendCircles/bigablecat.md b/solutions/leetcode/547-friendCircles/bigablecat.md similarity index 100% rename from leetcode/547-friendCircles/bigablecat.md rename to solutions/leetcode/547-friendCircles/bigablecat.md diff --git a/leetcode/551-StudentAttendanceRecordI/official.md b/solutions/leetcode/551-StudentAttendanceRecordI/official.md similarity index 100% rename from leetcode/551-StudentAttendanceRecordI/official.md rename to solutions/leetcode/551-StudentAttendanceRecordI/official.md diff --git a/leetcode/552-StudentAttendanceRecordII/official.md b/solutions/leetcode/552-StudentAttendanceRecordII/official.md similarity index 100% rename from leetcode/552-StudentAttendanceRecordII/official.md rename to solutions/leetcode/552-StudentAttendanceRecordII/official.md diff --git a/leetcode/557-Reverse Words in a String III/sandao.md b/solutions/leetcode/557-Reverse Words in a String III/sandao.md similarity index 100% rename from leetcode/557-Reverse Words in a String III/sandao.md rename to solutions/leetcode/557-Reverse Words in a String III/sandao.md diff --git a/leetcode/576-OutOfBoundaryPaths/official.md b/solutions/leetcode/576-OutOfBoundaryPaths/official.md similarity index 100% rename from leetcode/576-OutOfBoundaryPaths/official.md rename to solutions/leetcode/576-OutOfBoundaryPaths/official.md diff --git a/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md b/solutions/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md similarity index 100% rename from leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md rename to solutions/leetcode/576-OutOfBoundaryPaths/zengdiqing1994.md diff --git a/leetcode/583-DeleteOperationForTwoStrings/README.md b/solutions/leetcode/583-DeleteOperationForTwoStrings/README.md similarity index 100% rename from leetcode/583-DeleteOperationForTwoStrings/README.md rename to solutions/leetcode/583-DeleteOperationForTwoStrings/README.md diff --git a/leetcode/629-KInversePairsArray/official.md b/solutions/leetcode/629-KInversePairsArray/official.md similarity index 100% rename from leetcode/629-KInversePairsArray/official.md rename to solutions/leetcode/629-KInversePairsArray/official.md diff --git a/leetcode/629-KInversePairsArray/zengdiqing1994.md b/solutions/leetcode/629-KInversePairsArray/zengdiqing1994.md similarity index 100% rename from leetcode/629-KInversePairsArray/zengdiqing1994.md rename to solutions/leetcode/629-KInversePairsArray/zengdiqing1994.md diff --git a/leetcode/638-ShoppingOffers/bigablecat.md b/solutions/leetcode/638-ShoppingOffers/bigablecat.md similarity index 100% rename from leetcode/638-ShoppingOffers/bigablecat.md rename to solutions/leetcode/638-ShoppingOffers/bigablecat.md diff --git a/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md b/solutions/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md similarity index 100% rename from leetcode/646-MaximumLengthOfPairChain/SpecialYang.md rename to solutions/leetcode/646-MaximumLengthOfPairChain/SpecialYang.md diff --git a/leetcode/646-MaximumLengthOfPairChain/official.md b/solutions/leetcode/646-MaximumLengthOfPairChain/official.md similarity index 100% rename from leetcode/646-MaximumLengthOfPairChain/official.md rename to solutions/leetcode/646-MaximumLengthOfPairChain/official.md diff --git a/leetcode/647-PalindromicSubstrings/bigablecat.md b/solutions/leetcode/647-PalindromicSubstrings/bigablecat.md similarity index 100% rename from leetcode/647-PalindromicSubstrings/bigablecat.md rename to solutions/leetcode/647-PalindromicSubstrings/bigablecat.md diff --git a/leetcode/647-PalindromicSubstrings/official.md b/solutions/leetcode/647-PalindromicSubstrings/official.md similarity index 100% rename from leetcode/647-PalindromicSubstrings/official.md rename to solutions/leetcode/647-PalindromicSubstrings/official.md diff --git a/leetcode/650-2KeysKeyboard/mahone.md b/solutions/leetcode/650-2KeysKeyboard/mahone.md similarity index 100% rename from leetcode/650-2KeysKeyboard/mahone.md rename to solutions/leetcode/650-2KeysKeyboard/mahone.md diff --git a/leetcode/650-2KeysKeyboard/official.md b/solutions/leetcode/650-2KeysKeyboard/official.md similarity index 100% rename from leetcode/650-2KeysKeyboard/official.md rename to solutions/leetcode/650-2KeysKeyboard/official.md diff --git a/leetcode/664-StrangePrinter/official.md b/solutions/leetcode/664-StrangePrinter/official.md similarity index 100% rename from leetcode/664-StrangePrinter/official.md rename to solutions/leetcode/664-StrangePrinter/official.md diff --git a/leetcode/673-NumberOfLongestIncreasingSubsequence/README.md b/solutions/leetcode/673-NumberOfLongestIncreasingSubsequence/README.md similarity index 100% rename from leetcode/673-NumberOfLongestIncreasingSubsequence/README.md rename to solutions/leetcode/673-NumberOfLongestIncreasingSubsequence/README.md diff --git a/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md b/solutions/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md similarity index 100% rename from leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md rename to solutions/leetcode/673-NumberOfLongestIncreasingSubsequence/bigablecat.md diff --git a/leetcode/684-RedundantConnection/README.md b/solutions/leetcode/684-RedundantConnection/README.md similarity index 100% rename from leetcode/684-RedundantConnection/README.md rename to solutions/leetcode/684-RedundantConnection/README.md diff --git a/leetcode/684-RedundantConnection/bigablecat.md b/solutions/leetcode/684-RedundantConnection/bigablecat.md similarity index 100% rename from leetcode/684-RedundantConnection/bigablecat.md rename to solutions/leetcode/684-RedundantConnection/bigablecat.md diff --git a/leetcode/688-KnightProbabilityInChessboard/passself.md b/solutions/leetcode/688-KnightProbabilityInChessboard/passself.md similarity index 100% rename from leetcode/688-KnightProbabilityInChessboard/passself.md rename to solutions/leetcode/688-KnightProbabilityInChessboard/passself.md diff --git a/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md b/solutions/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md similarity index 100% rename from leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md rename to solutions/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/bigablecat.md diff --git a/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md b/solutions/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md similarity index 100% rename from leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md rename to solutions/leetcode/689-MaximumSumOf3Non-OverlappingSubarrays/official.md diff --git a/leetcode/691-StickersToSpellWord/official.md b/solutions/leetcode/691-StickersToSpellWord/official.md similarity index 100% rename from leetcode/691-StickersToSpellWord/official.md rename to solutions/leetcode/691-StickersToSpellWord/official.md diff --git a/leetcode/692-TopKFrequentWords/bigablecat.md b/solutions/leetcode/692-TopKFrequentWords/bigablecat.md similarity index 100% rename from leetcode/692-TopKFrequentWords/bigablecat.md rename to solutions/leetcode/692-TopKFrequentWords/bigablecat.md diff --git a/leetcode/695-MaxAreaOfIsland/README.md b/solutions/leetcode/695-MaxAreaOfIsland/README.md similarity index 100% rename from leetcode/695-MaxAreaOfIsland/README.md rename to solutions/leetcode/695-MaxAreaOfIsland/README.md diff --git a/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md b/solutions/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md similarity index 100% rename from leetcode/698-PartitionToKEqualSumSubsets/hatrick.md rename to solutions/leetcode/698-PartitionToKEqualSumSubsets/hatrick.md diff --git a/leetcode/698-PartitionToKEqualSumSubsets/official.md b/solutions/leetcode/698-PartitionToKEqualSumSubsets/official.md similarity index 100% rename from leetcode/698-PartitionToKEqualSumSubsets/official.md rename to solutions/leetcode/698-PartitionToKEqualSumSubsets/official.md diff --git a/leetcode/703-KthLargestElementInAStream/BambooYH.md b/solutions/leetcode/703-KthLargestElementInAStream/BambooYH.md similarity index 100% rename from leetcode/703-KthLargestElementInAStream/BambooYH.md rename to solutions/leetcode/703-KthLargestElementInAStream/BambooYH.md diff --git a/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md b/solutions/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md similarity index 100% rename from leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md rename to solutions/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/BambooYH.md diff --git a/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md b/solutions/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md similarity index 100% rename from leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md rename to solutions/leetcode/712-MinimumASCIIDeleteSumforTwoStrings/official.md diff --git a/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md b/solutions/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md similarity index 100% rename from leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md rename to solutions/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/hatrick.md diff --git a/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md b/solutions/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md similarity index 100% rename from leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md rename to solutions/leetcode/714-BestTimeToBuyAndSellStockWithTransactionFee/official.md diff --git a/leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md b/solutions/leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md similarity index 100% rename from leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md rename to solutions/leetcode/718-MaximumLengthOfRepeatedSubarray/mahone.md diff --git a/leetcode/718-MaximumLengthOfRepeatedSubarray/official.md b/solutions/leetcode/718-MaximumLengthOfRepeatedSubarray/official.md similarity index 100% rename from leetcode/718-MaximumLengthOfRepeatedSubarray/official.md rename to solutions/leetcode/718-MaximumLengthOfRepeatedSubarray/official.md diff --git a/leetcode/730-CountDifferentPalindromicSubsequences/official.md b/solutions/leetcode/730-CountDifferentPalindromicSubsequences/official.md similarity index 100% rename from leetcode/730-CountDifferentPalindromicSubsequences/official.md rename to solutions/leetcode/730-CountDifferentPalindromicSubsequences/official.md diff --git a/leetcode/740-DeleteAndEarn/melody-l.md b/solutions/leetcode/740-DeleteAndEarn/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/740-DeleteAndEarn/melody-l.md rename to solutions/leetcode/740-DeleteAndEarn/melody-l.md diff --git a/leetcode/740-DeleteAndEarn/official.md b/solutions/leetcode/740-DeleteAndEarn/official.md similarity index 100% rename from leetcode/740-DeleteAndEarn/official.md rename to solutions/leetcode/740-DeleteAndEarn/official.md diff --git a/leetcode/746-minCostClimbingStairs/bigablecat.md b/solutions/leetcode/746-minCostClimbingStairs/bigablecat.md similarity index 100% rename from leetcode/746-minCostClimbingStairs/bigablecat.md rename to solutions/leetcode/746-minCostClimbingStairs/bigablecat.md diff --git a/leetcode/746-minCostClimbingStairs/official.md b/solutions/leetcode/746-minCostClimbingStairs/official.md similarity index 100% rename from leetcode/746-minCostClimbingStairs/official.md rename to solutions/leetcode/746-minCostClimbingStairs/official.md diff --git a/leetcode/764-LargestPlusSign/SpecialYang.md b/solutions/leetcode/764-LargestPlusSign/SpecialYang.md similarity index 100% rename from leetcode/764-LargestPlusSign/SpecialYang.md rename to solutions/leetcode/764-LargestPlusSign/SpecialYang.md diff --git a/leetcode/764-LargestPlusSign/official.md b/solutions/leetcode/764-LargestPlusSign/official.md similarity index 100% rename from leetcode/764-LargestPlusSign/official.md rename to solutions/leetcode/764-LargestPlusSign/official.md diff --git a/leetcode/785-IsGraphBipartite/README.md b/solutions/leetcode/785-IsGraphBipartite/README.md similarity index 100% rename from leetcode/785-IsGraphBipartite/README.md rename to solutions/leetcode/785-IsGraphBipartite/README.md diff --git a/leetcode/785-IsGraphBipartite/bigablecat.md b/solutions/leetcode/785-IsGraphBipartite/bigablecat.md similarity index 100% rename from leetcode/785-IsGraphBipartite/bigablecat.md rename to solutions/leetcode/785-IsGraphBipartite/bigablecat.md diff --git a/leetcode/787-CheapestFlightsWithinKStops/official.md b/solutions/leetcode/787-CheapestFlightsWithinKStops/official.md similarity index 100% rename from leetcode/787-CheapestFlightsWithinKStops/official.md rename to solutions/leetcode/787-CheapestFlightsWithinKStops/official.md diff --git a/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md b/solutions/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md similarity index 100% rename from leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md rename to solutions/leetcode/787-CheapestFlightsWithinKStops/zengdiqing1994.md diff --git a/leetcode/790-DominoAndTrominoTiling/mahone.md b/solutions/leetcode/790-DominoAndTrominoTiling/mahone.md similarity index 100% rename from leetcode/790-DominoAndTrominoTiling/mahone.md rename to solutions/leetcode/790-DominoAndTrominoTiling/mahone.md diff --git a/leetcode/790-DominoAndTrominoTiling/official.md b/solutions/leetcode/790-DominoAndTrominoTiling/official.md similarity index 100% rename from leetcode/790-DominoAndTrominoTiling/official.md rename to solutions/leetcode/790-DominoAndTrominoTiling/official.md diff --git a/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md b/solutions/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md similarity index 100% rename from leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md rename to solutions/leetcode/801-MinimumSwapsToMakeSequencesIncreasing/official.md diff --git a/leetcode/808-SoupServings/official.md b/solutions/leetcode/808-SoupServings/official.md similarity index 100% rename from leetcode/808-SoupServings/official.md rename to solutions/leetcode/808-SoupServings/official.md diff --git a/leetcode/813-LargestSumOfAverages/melody-l.md b/solutions/leetcode/813-LargestSumOfAverages/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/813-LargestSumOfAverages/melody-l.md rename to solutions/leetcode/813-LargestSumOfAverages/melody-l.md diff --git a/leetcode/813-LargestSumOfAverages/official.md b/solutions/leetcode/813-LargestSumOfAverages/official.md similarity index 100% rename from leetcode/813-LargestSumOfAverages/official.md rename to solutions/leetcode/813-LargestSumOfAverages/official.md diff --git a/leetcode/837-New21Game/official.md b/solutions/leetcode/837-New21Game/official.md similarity index 100% rename from leetcode/837-New21Game/official.md rename to solutions/leetcode/837-New21Game/official.md diff --git a/leetcode/838-PushDominoes/official.md b/solutions/leetcode/838-PushDominoes/official.md similarity index 100% rename from leetcode/838-PushDominoes/official.md rename to solutions/leetcode/838-PushDominoes/official.md diff --git a/leetcode/844-BackspaceStringCompare/BambooYH.md b/solutions/leetcode/844-BackspaceStringCompare/BambooYH.md similarity index 100% rename from leetcode/844-BackspaceStringCompare/BambooYH.md rename to solutions/leetcode/844-BackspaceStringCompare/BambooYH.md diff --git a/leetcode/844-BackspaceStringCompare/bigablecat.md b/solutions/leetcode/844-BackspaceStringCompare/bigablecat.md similarity index 100% rename from leetcode/844-BackspaceStringCompare/bigablecat.md rename to solutions/leetcode/844-BackspaceStringCompare/bigablecat.md diff --git a/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md b/solutions/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md similarity index 100% rename from leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md rename to solutions/leetcode/847-ShortestPathVisitingAllNodes/bigablecat.md diff --git a/leetcode/847-ShortestPathVisitingAllNodes/official.md b/solutions/leetcode/847-ShortestPathVisitingAllNodes/official.md similarity index 100% rename from leetcode/847-ShortestPathVisitingAllNodes/official.md rename to solutions/leetcode/847-ShortestPathVisitingAllNodes/official.md diff --git a/leetcode/860-lemonadeChange/BambooYH.md b/solutions/leetcode/860-lemonadeChange/BambooYH.md similarity index 100% rename from leetcode/860-lemonadeChange/BambooYH.md rename to solutions/leetcode/860-lemonadeChange/BambooYH.md diff --git a/leetcode/860-lemonadeChange/SpecialYang.md b/solutions/leetcode/860-lemonadeChange/SpecialYang.md similarity index 100% rename from leetcode/860-lemonadeChange/SpecialYang.md rename to solutions/leetcode/860-lemonadeChange/SpecialYang.md diff --git a/leetcode/860-lemonadeChange/official.md b/solutions/leetcode/860-lemonadeChange/official.md similarity index 100% rename from leetcode/860-lemonadeChange/official.md rename to solutions/leetcode/860-lemonadeChange/official.md diff --git a/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md b/solutions/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md similarity index 100% rename from leetcode/873-LengthOfLongestFibonacciSubsequence/official.md rename to solutions/leetcode/873-LengthOfLongestFibonacciSubsequence/official.md diff --git a/leetcode/874-walkingRobotSimulation/SpecialYang.md b/solutions/leetcode/874-walkingRobotSimulation/SpecialYang.md similarity index 100% rename from leetcode/874-walkingRobotSimulation/SpecialYang.md rename to solutions/leetcode/874-walkingRobotSimulation/SpecialYang.md diff --git a/leetcode/874-walkingRobotSimulation/hatrick.md b/solutions/leetcode/874-walkingRobotSimulation/hatrick.md similarity index 100% rename from leetcode/874-walkingRobotSimulation/hatrick.md rename to solutions/leetcode/874-walkingRobotSimulation/hatrick.md diff --git a/leetcode/874-walkingRobotSimulation/official.md b/solutions/leetcode/874-walkingRobotSimulation/official.md similarity index 100% rename from leetcode/874-walkingRobotSimulation/official.md rename to solutions/leetcode/874-walkingRobotSimulation/official.md diff --git a/leetcode/875-KokoEatingBananas/sandao.md b/solutions/leetcode/875-KokoEatingBananas/sandao.md similarity index 100% rename from leetcode/875-KokoEatingBananas/sandao.md rename to solutions/leetcode/875-KokoEatingBananas/sandao.md diff --git a/leetcode/877-stoneGame/melody-l.md b/solutions/leetcode/877-stoneGame/melody-l.md old mode 100755 new mode 100644 similarity index 100% rename from leetcode/877-stoneGame/melody-l.md rename to solutions/leetcode/877-stoneGame/melody-l.md diff --git a/leetcode/877-stoneGame/official.md b/solutions/leetcode/877-stoneGame/official.md similarity index 100% rename from leetcode/877-stoneGame/official.md rename to solutions/leetcode/877-stoneGame/official.md diff --git a/leetcode/898-BitwiseORsOfSubarrays/official.md b/solutions/leetcode/898-BitwiseORsOfSubarrays/official.md similarity index 100% rename from leetcode/898-BitwiseORsOfSubarrays/official.md rename to solutions/leetcode/898-BitwiseORsOfSubarrays/official.md diff --git a/leetcode/903-ValidPermutationsForDISequence/official.md b/solutions/leetcode/903-ValidPermutationsForDISequence/official.md similarity index 100% rename from leetcode/903-ValidPermutationsForDISequence/official.md rename to solutions/leetcode/903-ValidPermutationsForDISequence/official.md diff --git a/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md b/solutions/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md similarity index 100% rename from leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md rename to solutions/leetcode/903-ValidPermutationsForDISequence/zengdiqing1994.md diff --git a/leetcode/920-NumberOfMusicPlaylists/passself.md b/solutions/leetcode/920-NumberOfMusicPlaylists/passself.md similarity index 100% rename from leetcode/920-NumberOfMusicPlaylists/passself.md rename to solutions/leetcode/920-NumberOfMusicPlaylists/passself.md diff --git a/leetcode/931-MinimumFallingPathSum/hatrick.md b/solutions/leetcode/931-MinimumFallingPathSum/hatrick.md similarity index 100% rename from leetcode/931-MinimumFallingPathSum/hatrick.md rename to solutions/leetcode/931-MinimumFallingPathSum/hatrick.md diff --git a/leetcode/931-MinimumFallingPathSum/official.md b/solutions/leetcode/931-MinimumFallingPathSum/official.md similarity index 100% rename from leetcode/931-MinimumFallingPathSum/official.md rename to solutions/leetcode/931-MinimumFallingPathSum/official.md diff --git a/leetcode/935-KnightDialer/official.md b/solutions/leetcode/935-KnightDialer/official.md similarity index 100% rename from leetcode/935-KnightDialer/official.md rename to solutions/leetcode/935-KnightDialer/official.md diff --git a/leetcode/940-DistinctSubsequencesII/official.md b/solutions/leetcode/940-DistinctSubsequencesII/official.md similarity index 100% rename from leetcode/940-DistinctSubsequencesII/official.md rename to solutions/leetcode/940-DistinctSubsequencesII/official.md diff --git a/leetcode/943-FindTheShortestSuperstring/official.md b/solutions/leetcode/943-FindTheShortestSuperstring/official.md similarity index 100% rename from leetcode/943-FindTheShortestSuperstring/official.md rename to solutions/leetcode/943-FindTheShortestSuperstring/official.md diff --git a/leetcode/954-ArrayOfDoubledPairs/bigablecat.md b/solutions/leetcode/954-ArrayOfDoubledPairs/bigablecat.md similarity index 100% rename from leetcode/954-ArrayOfDoubledPairs/bigablecat.md rename to solutions/leetcode/954-ArrayOfDoubledPairs/bigablecat.md diff --git a/leetcode/956-TallestBillboard/official.md b/solutions/leetcode/956-TallestBillboard/official.md similarity index 100% rename from leetcode/956-TallestBillboard/official.md rename to solutions/leetcode/956-TallestBillboard/official.md diff --git a/leetcode/964-LeastOperatorsToExpressNumber/official.md b/solutions/leetcode/964-LeastOperatorsToExpressNumber/official.md similarity index 100% rename from leetcode/964-LeastOperatorsToExpressNumber/official.md rename to solutions/leetcode/964-LeastOperatorsToExpressNumber/official.md diff --git a/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md b/solutions/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md similarity index 100% rename from leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md rename to solutions/leetcode/967-NumbersWithSameConsecutiveDifferences/bigablecat.md diff --git a/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md b/solutions/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md similarity index 100% rename from leetcode/967-NumbersWithSameConsecutiveDifferences/official.md rename to solutions/leetcode/967-NumbersWithSameConsecutiveDifferences/official.md diff --git a/leetcode/968-BinaryTreeCameras/official.md b/solutions/leetcode/968-BinaryTreeCameras/official.md similarity index 100% rename from leetcode/968-BinaryTreeCameras/official.md rename to solutions/leetcode/968-BinaryTreeCameras/official.md diff --git a/leetcode/968-BinaryTreeCameras/zengdiqing1994.md b/solutions/leetcode/968-BinaryTreeCameras/zengdiqing1994.md similarity index 100% rename from leetcode/968-BinaryTreeCameras/zengdiqing1994.md rename to solutions/leetcode/968-BinaryTreeCameras/zengdiqing1994.md diff --git a/leetcode/975-OddEvenJump/official.md b/solutions/leetcode/975-OddEvenJump/official.md similarity index 100% rename from leetcode/975-OddEvenJump/official.md rename to solutions/leetcode/975-OddEvenJump/official.md diff --git a/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md b/solutions/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md similarity index 100% rename from leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md rename to solutions/leetcode/982-TriplesWithBitwiseANDEqualToZero/official.md diff --git a/leetcode/sample/concise.md b/solutions/leetcode/sample/concise.md similarity index 100% rename from leetcode/sample/concise.md rename to solutions/leetcode/sample/concise.md diff --git a/leetcode/sample/concise.png b/solutions/leetcode/sample/concise.png similarity index 100% rename from leetcode/sample/concise.png rename to solutions/leetcode/sample/concise.png diff --git a/leetcode/sample/full.md b/solutions/leetcode/sample/full.md similarity index 100% rename from leetcode/sample/full.md rename to solutions/leetcode/sample/full.md diff --git a/leetcode/sample/full.png b/solutions/leetcode/sample/full.png similarity index 100% rename from leetcode/sample/full.png rename to solutions/leetcode/sample/full.png diff --git "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" "b/solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" rename to "solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/README.md" diff --git "a/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" "b/solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" rename to "solutions/\345\211\221\346\214\207Offer/003-\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" "b/solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" rename to "solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" diff --git "a/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" "b/solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" rename to "solutions/\345\211\221\346\214\207Offer/004-\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" "b/solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" rename to "solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/README.md" diff --git "a/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" "b/solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" rename to "solutions/\345\211\221\346\214\207Offer/005-\346\233\277\346\215\242\347\251\272\346\240\274/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" "b/solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" rename to "solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" diff --git "a/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" "b/solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" rename to "solutions/\345\211\221\346\214\207Offer/006-\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" "b/solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" rename to "solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" diff --git "a/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" "b/solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" rename to "solutions/\345\211\221\346\214\207Offer/007-\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/zengdiqing1994.md" diff --git "a/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" "b/solutions/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" rename to "solutions/\345\211\221\346\214\207Offer/008-\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271/README.md" diff --git "a/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" "b/solutions/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" rename to "solutions/\345\211\221\346\214\207Offer/009-\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/README.md" diff --git "a/\345\211\221\346\214\207Offer/README.md" "b/solutions/\345\211\221\346\214\207Offer/README.md" similarity index 100% rename from "\345\211\221\346\214\207Offer/README.md" rename to "solutions/\345\211\221\346\214\207Offer/README.md"