From 84326d9d6154626f907cddedc59d37f35acb44a6 Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Mon, 6 Mar 2023 01:35:47 -0500 Subject: [PATCH 001/126] =?UTF-8?q?Update=200349.=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 加入python使用数组方法 --- problems/0349.两个数组的交集.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 347d1094..b7365e6e 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -169,6 +169,21 @@ class Solution: val_dict[num] = 0 return ans + +class Solution: # 使用数组方法 + def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: + count1 = [0]*1001 + count2 = [0]*1001 + result = [] + for i in range(len(nums1)): + count1[nums1[i]]+=1 + for j in range(len(nums2)): + count2[nums2[j]]+=1 + for k in range(1001): + if count1[k]*count2[k]>0: + result.append(k) + return result + ``` From 3a16650abe53b59bb9ab99c931993ef1f253d22c Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Mon, 6 Mar 2023 01:49:19 -0500 Subject: [PATCH 002/126] =?UTF-8?q?Update=200202.=E5=BF=AB=E4=B9=90?= =?UTF-8?q?=E6=95=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit python的另一种写法 - 通过字符串来计算各位平方和 --- problems/0202.快乐数.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index 1a7d53a3..2687574f 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -132,6 +132,19 @@ class Solution: else: record.add(n) +# python的另一种写法 - 通过字符串来计算各位平方和 +class Solution: + def isHappy(self, n: int) -> bool: + record = [] + while n not in record: + record.append(n) + newn = 0 + nn = str(n) + for i in nn: + newn+=int(i)**2 + if newn==1: return True + n = newn + return False ``` Go: From 3bc935ccc716f316040e0da5f5370cfcc6ce708c Mon Sep 17 00:00:00 2001 From: StriveDD Date: Mon, 6 Mar 2023 16:32:25 +0800 Subject: [PATCH 003/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A00130.=E8=A2=AB?= =?UTF-8?q?=E5=9B=B4=E7=BB=95=E7=9A=84=E5=8C=BA=E5=9F=9F=E7=9A=84Java?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=20BFS=E3=80=81DFS=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C0797.=E6=89=80=E6=9C=89=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=9A=84=E8=B7=AF=E5=BE=84=E7=9A=84Java=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=9A=84=20DFS=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0130.被围绕的区域.md | 214 +++++++++++++++++++++++++ problems/0797.所有可能的路径.md | 30 ++++ 2 files changed, 244 insertions(+) diff --git a/problems/0130.被围绕的区域.md b/problems/0130.被围绕的区域.md index c2aa5696..7afa71b4 100644 --- a/problems/0130.被围绕的区域.md +++ b/problems/0130.被围绕的区域.md @@ -84,7 +84,221 @@ public: ## 其他语言版本 +### Java + +```Java +// 广度优先遍历 +// 使用 visited 数组进行标记 +class Solution { + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向 + + public void solve(char[][] board) { + // rowSize:行的长度,colSize:列的长度 + int rowSize = board.length, colSize = board[0].length; + boolean[][] visited = new boolean[rowSize][colSize]; + Queue queue = new ArrayDeque<>(); + // 从左侧边,和右侧边遍历 + for (int row = 0; row < rowSize; row++) { + if (board[row][0] == 'O') { + visited[row][0] = true; + queue.add(new int[]{row, 0}); + } + if (board[row][colSize - 1] == 'O') { + visited[row][colSize - 1] = true; + queue.add(new int[]{row, colSize - 1}); + } + } + // 从上边和下边遍历,在对左侧边和右侧边遍历时我们已经遍历了矩阵的四个角 + // 所以在遍历上边和下边时可以不用遍历四个角 + for (int col = 1; col < colSize - 1; col++) { + if (board[0][col] == 'O') { + visited[0][col] = true; + queue.add(new int[]{0, col}); + } + if (board[rowSize - 1][col] == 'O') { + visited[rowSize - 1][col] = true; + queue.add(new int[]{rowSize - 1, col}); + } + } + // 广度优先遍历,把没有被 'X' 包围的 'O' 进行标记 + while (!queue.isEmpty()) { + int[] current = queue.poll(); + for (int[] pos: position) { + int row = current[0] + pos[0], col = current[1] + pos[1]; + // 如果范围越界、位置已被访问过、该位置的值不是 'O',就直接跳过 + if (row < 0 || row >= rowSize || col < 0 || col >= colSize) continue; + if (visited[row][col] || board[row][col] != 'O') continue; + visited[row][col] = true; + queue.add(new int[]{row, col}); + } + } + // 遍历数组,把没有被标记的 'O' 修改成 'X' + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (board[row][col] == 'O' && !visited[row][col]) board[row][col] = 'X'; + } + } + } +} +``` +```Java +// 广度优先遍历 +// 直接修改 board 的值为其他特殊值 +class Solution { + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向 + + public void solve(char[][] board) { + // rowSize:行的长度,colSize:列的长度 + int rowSize = board.length, colSize = board[0].length; + Queue queue = new ArrayDeque<>(); + // 从左侧边,和右侧边遍历 + for (int row = 0; row < rowSize; row++) { + if (board[row][0] == 'O') + queue.add(new int[]{row, 0}); + if (board[row][colSize - 1] == 'O') + queue.add(new int[]{row, colSize - 1}); + } + // 从上边和下边遍历,在对左侧边和右侧边遍历时我们已经遍历了矩阵的四个角 + // 所以在遍历上边和下边时可以不用遍历四个角 + for (int col = 1; col < colSize - 1; col++) { + if (board[0][col] == 'O') + queue.add(new int[]{0, col}); + if (board[rowSize - 1][col] == 'O') + queue.add(new int[]{rowSize - 1, col}); + } + // 广度优先遍历,把没有被 'X' 包围的 'O' 修改成特殊值 + while (!queue.isEmpty()) { + int[] current = queue.poll(); + board[current[0]][current[1]] = 'A'; + for (int[] pos: position) { + int row = current[0] + pos[0], col = current[1] + pos[1]; + // 如果范围越界、该位置的值不是 'O',就直接跳过 + if (row < 0 || row >= rowSize || col < 0 || col >= colSize) continue; + if (board[row][col] != 'O') continue; + queue.add(new int[]{row, col}); + } + } + // 遍历数组,把 'O' 修改成 'X',特殊值修改成 'O' + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (board[row][col] == 'A') board[row][col] = 'O'; + else if (board[row][col] == 'O') board[row][col] = 'X'; + } + } + } +} +``` +```Java +// 深度优先遍历 +// 使用 visited 数组进行标记 +class Solution { + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向 + + public void dfs(char[][] board, int row, int col, boolean[][] visited) { + for (int[] pos: position) { + int nextRow = row + pos[0], nextCol = col + pos[1]; + // 位置越界 + if (nextRow < 0 || nextRow >= board.length || nextCol < 0 || nextCol >= board[0].length) + continue; + // 位置已被访问过、新位置值不是 'O' + if (visited[nextRow][nextCol] || board[nextRow][nextCol] != 'O') continue; + visited[nextRow][nextCol] = true; + dfs(board, nextRow, nextCol, visited); + } + } + + public void solve(char[][] board) { + int rowSize = board.length, colSize = board[0].length; + boolean[][] visited = new boolean[rowSize][colSize]; + // 从左侧遍、右侧遍遍历 + for (int row = 0; row < rowSize; row++) { + if (board[row][0] == 'O' && !visited[row][0]) { + visited[row][0] = true; + dfs(board, row, 0, visited); + } + if (board[row][colSize - 1] == 'O' && !visited[row][colSize - 1]) { + visited[row][colSize - 1] = true; + dfs(board, row, colSize - 1, visited); + } + } + // 从上边和下边遍历,在对左侧边和右侧边遍历时我们已经遍历了矩阵的四个角 + // 所以在遍历上边和下边时可以不用遍历四个角 + for (int col = 1; col < colSize - 1; col++) { + if (board[0][col] == 'O' && !visited[0][col]) { + visited[0][col] = true; + dfs(board, 0, col, visited); + } + if (board[rowSize - 1][col] == 'O' && !visited[rowSize - 1][col]) { + visited[rowSize - 1][col] = true; + dfs(board, rowSize - 1, col, visited); + } + } + // 遍历数组,把没有被标记的 'O' 修改成 'X' + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (board[row][col] == 'O' && !visited[row][col]) board[row][col] = 'X'; + } + } + } +} +``` +```Java +// 深度优先遍历 +// // 直接修改 board 的值为其他特殊值 +class Solution { + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向 + + public void dfs(char[][] board, int row, int col) { + for (int[] pos: position) { + int nextRow = row + pos[0], nextCol = col + pos[1]; + // 位置越界 + if (nextRow < 0 || nextRow >= board.length || nextCol < 0 || nextCol >= board[0].length) + continue; + // 新位置值不是 'O' + if (board[nextRow][nextCol] != 'O') continue; + board[nextRow][nextCol] = 'A'; // 修改为特殊值 + dfs(board, nextRow, nextCol); + } + } + + public void solve(char[][] board) { + int rowSize = board.length, colSize = board[0].length; + // 从左侧遍、右侧遍遍历 + for (int row = 0; row < rowSize; row++) { + if (board[row][0] == 'O') { + board[row][0] = 'A'; + dfs(board, row, 0); + } + if (board[row][colSize - 1] == 'O') { + board[row][colSize - 1] = 'A'; + dfs(board, row, colSize - 1); + } + } + // 从上边和下边遍历,在对左侧边和右侧边遍历时我们已经遍历了矩阵的四个角 + // 所以在遍历上边和下边时可以不用遍历四个角 + for (int col = 1; col < colSize - 1; col++) { + if (board[0][col] == 'O') { + board[0][col] = 'A'; + dfs(board, 0, col); + } + if (board[rowSize - 1][col] == 'O') { + board[rowSize - 1][col] = 'A'; + dfs(board, rowSize - 1, col); + } + } + // 遍历数组,把 'O' 修改成 'X',特殊值修改成 'O' + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (board[row][col] == 'O') board[row][col] = 'X'; + else if (board[row][col] == 'A') board[row][col] = 'O'; + } + } + } +} +``` +

+ diff --git a/problems/0797.所有可能的路径.md b/problems/0797.所有可能的路径.md index eb3f7fb4..89643e04 100644 --- a/problems/0797.所有可能的路径.md +++ b/problems/0797.所有可能的路径.md @@ -161,6 +161,35 @@ public: ## Java +```Java +// 深度优先遍历 +class Solution { + List> ans; // 用来存放满足条件的路径 + List cnt; // 用来保存 dfs 过程中的节点值 + + public void dfs(int[][] graph, int node) { + if (node == graph.length - 1) { // 如果当前节点是 n - 1,那么就保存这条路径 + ans.add(new ArrayList<>(cnt)); + return; + } + for (int index = 0; index < graph[node].length; index++) { + int nextNode = graph[node][index]; + cnt.add(nextNode); + dfs(graph, nextNode); + cnt.remove(cnt.size() - 1); // 回溯 + } + } + + public List> allPathsSourceTarget(int[][] graph) { + ans = new ArrayList<>(); + cnt = new ArrayList<>(); + cnt.add(0); // 注意,0 号节点要加入 cnt 数组中 + dfs(graph, 0); + return ans; + } +} +``` + ## Python ```python class Solution: @@ -192,3 +221,4 @@ class Solution: + From aea8bee9543fd699068fd413167a682d6dd967a8 Mon Sep 17 00:00:00 2001 From: Logen <47022821+Logenleedev@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:50:04 -0600 Subject: [PATCH 004/126] =?UTF-8?q?=E5=88=A0=E9=99=A4typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0494.目标和.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index eec4183d..2e3f4fee 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -162,7 +162,7 @@ dp[j] 表示:填满j(包括j)这么大容积的包,有dp[j]种方法 有哪些来源可以推出dp[j]呢? -只要搞到nums[i]),凑成dp[j]就有dp[j - nums[i]] 种方法。 +只要搞到nums[i],凑成dp[j]就有dp[j - nums[i]] 种方法。 例如:dp[j],j 为5, From 202013fd817e303e14d5f43a324b55b9c9810ead Mon Sep 17 00:00:00 2001 From: Jeremy Feng <44312563+jeremy-feng@users.noreply.github.com> Date: Tue, 7 Mar 2023 17:46:03 +0800 Subject: [PATCH 005/126] =?UTF-8?q?Update=200070.=E7=88=AC=E6=A5=BC?= =?UTF-8?q?=E6=A2=AF.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- problems/0070.爬楼梯.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md index 14aeef01..d4a7881d 100644 --- a/problems/0070.爬楼梯.md +++ b/problems/0070.爬楼梯.md @@ -72,7 +72,7 @@ dp[i]: 爬到第i层楼梯,有dp[i]种方法 3. dp数组如何初始化 -在回顾一下dp[i]的定义:爬到第i层楼梯,有dp[i]中方法。 +再回顾一下dp[i]的定义:爬到第i层楼梯,有dp[i]中方法。 那么i为0,dp[i]应该是多少呢,这个可以有很多解释,但基本都是直接奔着答案去解释的。 From 200e14cbdedff221fe93387e709c8b349986ac60 Mon Sep 17 00:00:00 2001 From: GODVvVZzz <2662446324@qq.com> Date: Wed, 8 Mar 2023 20:07:45 +0800 Subject: [PATCH 006/126] =?UTF-8?q?=E4=BF=AE=E6=94=B9Java=E8=A7=A3?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0070.爬楼梯完全背包版本.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md index 3093c833..41c2e616 100644 --- a/problems/0070.爬楼梯完全背包版本.md +++ b/problems/0070.爬楼梯完全背包版本.md @@ -128,12 +128,12 @@ Java: class Solution { public int climbStairs(int n) { int[] dp = new int[n + 1]; - int[] weight = {1,2}; + int m = 2; dp[0] = 1; - for (int i = 0; i <= n; i++) { - for (int j = 0; j < weight.length; j++) { - if (i >= weight[j]) dp[i] += dp[i - weight[j]]; + for (int i = 1; i <= n; i++) { // 遍历背包 + for (int j = 1; j <= m; j++) { //遍历物品 + if (i >= j) dp[i] += dp[i - j]; } } @@ -227,3 +227,4 @@ function climbStairs(n: number): number { + From 60d585f4eeb2018483b1f80b8697e9ea80ff871e Mon Sep 17 00:00:00 2001 From: dongyunpeng Date: Thu, 9 Mar 2023 01:36:30 +0800 Subject: [PATCH 007/126] =?UTF-8?q?=E5=AE=8C=E5=96=840707.=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E9=93=BE=E8=A1=A8C++=E7=89=88=E6=9C=AC=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8delete=E6=8C=87=E9=92=88=E4=B9=8B=E5=90=8E=E8=B5=8B?= =?UTF-8?q?=E5=80=BC=E4=B8=BAnull=EF=BC=8C=E5=9C=A8=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E4=B8=AD=20=E8=AF=B4=E6=98=8E=E4=BA=86=E9=87=8E=E6=8C=87?= =?UTF-8?q?=E9=92=88=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0707.设计链表.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 43ed2622..de1e7eb4 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -133,6 +133,11 @@ public: LinkedNode* tmp = cur->next; cur->next = cur->next->next; delete tmp; + //delete命令指示释放了tmp指针原本所指的那部分内存, + //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后, + //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针 + //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间 + tmp=nullptr; _size--; } @@ -1447,3 +1452,4 @@ impl MyLinkedList { + From 4164ddbb69da491b05f201a39b7b4c6233fad929 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Fri, 10 Mar 2023 11:11:54 +0800 Subject: [PATCH 008/126] =?UTF-8?q?Update=200122.=E4=B9=B0=E5=8D=96?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA?= =?UTF-8?q?II.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0122.买卖股票的最佳时机II.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md index d094da48..a863afe7 100644 --- a/problems/0122.买卖股票的最佳时机II.md +++ b/problems/0122.买卖股票的最佳时机II.md @@ -274,6 +274,7 @@ const maxProfit = (prices) => { ### TypeScript: +贪心 ```typescript function maxProfit(prices: number[]): number { let resProfit: number = 0; @@ -284,6 +285,21 @@ function maxProfit(prices: number[]): number { }; ``` +动态规划 +```typescript +function maxProfit(prices: number[]): number { + const dp = Array(prices.length) + .fill(0) + .map(() => Array(2).fill(0)) + dp[0][0] = -prices[0] + for (let i = 1; i < prices.length; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]) + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]) + } + return dp[prices.length - 1][1] +} +``` + ### Rust 贪心: From 3d64ead78d6e865a994a47df38c362a0db0636d9 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Fri, 10 Mar 2023 14:52:24 +0800 Subject: [PATCH 009/126] =?UTF-8?q?Update=200055.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0055.跳跃游戏.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/problems/0055.跳跃游戏.md b/problems/0055.跳跃游戏.md index a898263d..6f6dec26 100644 --- a/problems/0055.跳跃游戏.md +++ b/problems/0055.跳跃游戏.md @@ -178,16 +178,16 @@ var canJump = function(nums) { ```Rust impl Solution { - fn max(a: usize, b: usize) -> usize { - if a > b { a } else { b } - } pub fn can_jump(nums: Vec) -> bool { - let mut cover = 0; - if (nums.len() == 1) { return true; } - let mut i = 0; + if nums.len() == 1 { + return true; + } + let (mut i, mut cover) = (0, 0); while i <= cover { - cover = Self::max(i + nums[i] as usize, cover); - if cover >= nums.len() - 1 { return true; } + cover = (i + nums[i] as usize).max(cover); + if cover >= nums.len() - 1 { + return true; + } i += 1; } false From 296ef893b4a15d4459e7400bd2bd699b3173bbbc Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:12:53 -0500 Subject: [PATCH 010/126] =?UTF-8?q?Update=200151.=E7=BF=BB=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95=E8=AF=8D?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加python解法:使用双指针法移除空格 --- problems/0151.翻转字符串里的单词.md | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index dc12ae23..eb78cc9d 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -516,6 +516,48 @@ class Solution: return s[:ps] + s[ps:][::-1] # Must do the last step, because the last word is omit though the pointers are on the correct positions, ``` +```python +class Solution: # 使用双指针法移除空格 + def reverseWords(self, s: str) -> str: + + def removeextraspace(s): + start = 0; end = len(s)-1 + while s[start]==' ': + start+=1 + while s[end]==' ': + end-=1 + news = list(s[start:end+1]) + slow = fast = 0 + while fast0 and news[fast]==news[fast-1]==' ': + fast+=1 + news[slow]=news[fast] + slow+=1; fast+=1 + #return "".join(news[:slow]) + return news[:slow] + + def reversestr(s): + left,right = 0,len(s)-1 + news = list(s) + while left Date: Sun, 12 Mar 2023 11:25:46 +0800 Subject: [PATCH 011/126] =?UTF-8?q?update=200203.=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0203.移除链表元素.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index 99bd3580..7e3955a5 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -118,6 +118,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + **设置一个虚拟头结点在进行移除节点操作:** ```CPP @@ -144,6 +147,9 @@ public: ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + From 9321c3c6773f4cd244d86d5f8052042c30ba5be0 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 12 Mar 2023 11:34:01 +0800 Subject: [PATCH 012/126] =?UTF-8?q?update=200707.=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0707.设计链表.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 95560fb1..f6f16e30 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -152,6 +152,9 @@ private: }; ``` +* 时间复杂度: 涉及 `index` 的相关操作为 O(index), 其余为 O(1) +* 空间复杂度: O(n) + ## 其他语言版本 From 2d7a9a16c513f8e49ed9cd51d7a54743588ec722 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 12 Mar 2023 11:38:20 +0800 Subject: [PATCH 013/126] =?UTF-8?q?update=200206.=E7=BF=BB=E8=BD=AC?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0206.翻转链表.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md index 8bf61c3f..d558e783 100644 --- a/problems/0206.翻转链表.md +++ b/problems/0206.翻转链表.md @@ -68,6 +68,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + ## 递归法 递归法相对抽象一些,但是其实和双指针法是一样的逻辑,同样是当cur为空的时候循环结束,不断将cur指向pre的过程。 @@ -97,6 +100,9 @@ public: }; ``` +* 时间复杂度: O(n), 要递归处理链表的每个节点 +* 空间复杂度: O(n), 递归调用了 n 层栈空间 + 我们可以发现,上面的递归写法和双指针法实质上都是从前往后翻转指针指向,其实还有另外一种与双指针法不同思路的递归写法:从后往前翻转指针指向。 具体代码如下(带详细注释): @@ -120,6 +126,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + ## 其他语言版本 From 358818c7a499809056fee400f460cc80b0c20ceb Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 12 Mar 2023 11:41:09 +0800 Subject: [PATCH 014/126] =?UTF-8?q?update=200019.=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E7=9A=84=E5=80=92=E6=95=B0=E7=AC=ACN?= =?UTF-8?q?=E4=B8=AA=E8=8A=82=E7=82=B9=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0019.删除链表的倒数第N个节点.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index c408fefc..a11ff8ba 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -87,6 +87,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + ## 其他语言版本 From 3aabfed8bd708b8524cab5eac65b3358eeceb9bf Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 12 Mar 2023 11:46:51 +0800 Subject: [PATCH 015/126] =?UTF-8?q?update=200142.=E7=8E=AF=E5=BD=A2?= =?UTF-8?q?=E9=93=BE=E8=A1=A8II=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0142.环形链表II.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md index 8a48c7d5..46df4777 100644 --- a/problems/0142.环形链表II.md +++ b/problems/0142.环形链表II.md @@ -145,6 +145,9 @@ public: }; ``` +* 时间复杂度: O(n),快慢指针相遇前,指针走的次数小于链表长度,快慢指针相遇后,两个index指针走的次数也小于链表长度,总体为走的次数小于 2n +* 空间复杂度: O(1) + ## 补充 在推理过程中,大家可能有一个疑问就是:**为什么第一次在环中相遇,slow的 步数 是 x+y 而不是 x + 若干环的长度 + y 呢?** From 0ccbc1ea535240a2118296eaf1d5414c41a865b4 Mon Sep 17 00:00:00 2001 From: jeffreyjia Date: Sun, 12 Mar 2023 13:07:31 +0800 Subject: [PATCH 016/126] =?UTF-8?q?=E6=9B=B4=E6=96=B00746.=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=9C=80=E5=B0=8F=E8=8A=B1=E8=B4=B9=E7=88=AC=E6=A5=BC?= =?UTF-8?q?=E6=A2=AF.md=20=E6=8F=90=E4=BE=9BGo=E7=89=88=E6=9C=AC=E8=A7=A3?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E6=96=B0=E6=80=9D=E8=B7=AF(dp[i]=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E4=BB=8Ei=E5=B1=82=E8=B5=B7=E8=B7=B3=E6=89=80?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E6=94=AF=E4=BB=98=E7=9A=84=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E8=B4=B9=E7=94=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 ++++++ .idea/leetcode-master.iml | 9 +++++++ .idea/modules.xml | 8 ++++++ .idea/vcs.xml | 6 +++++ problems/0746.使用最小花费爬楼梯.md | 27 ++++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/leetcode-master.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..35410cac --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/leetcode-master.iml b/.idea/leetcode-master.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/leetcode-master.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..7c250acd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index 44b6406c..d6b3a177 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -284,6 +284,33 @@ func min(a, b int) int { return b } ``` +``` GO +第二种思路: dp[i]表示从i层起跳所需要支付的最小费用 +递推公式: +i Date: Sun, 12 Mar 2023 13:10:21 +0800 Subject: [PATCH 017/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A0.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3d725761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.idea \ No newline at end of file From d8df97845c165669713c5606b5e6a5397e356d5e Mon Sep 17 00:00:00 2001 From: jeffreyjia Date: Sun, 12 Mar 2023 13:24:03 +0800 Subject: [PATCH 018/126] =?UTF-8?q?=E5=BF=BD=E7=95=A5idea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 -------- .idea/leetcode-master.iml | 9 --------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 4 files changed, 31 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/leetcode-master.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 35410cac..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml -# 基于编辑器的 HTTP 客户端请求 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/leetcode-master.iml b/.idea/leetcode-master.iml deleted file mode 100644 index 5e764c4f..00000000 --- a/.idea/leetcode-master.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 7c250acd..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 50cdae9a91df693b122f5bf8e89aa8fc5164a0d8 Mon Sep 17 00:00:00 2001 From: jeffreyjia Date: Sun, 12 Mar 2023 13:25:18 +0800 Subject: [PATCH 019/126] =?UTF-8?q?=E5=88=A0=E9=99=A4.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 -- .idea/.gitignore | 8 ++++++++ .idea/leetcode-master.iml | 9 +++++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ 5 files changed, 31 insertions(+), 2 deletions(-) delete mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/leetcode-master.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3d725761..00000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.DS_Store -.idea \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..35410cac --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/leetcode-master.iml b/.idea/leetcode-master.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/leetcode-master.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..7c250acd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From d34e4a8378ae8c62cdb8a3a00462561c70ec0b4a Mon Sep 17 00:00:00 2001 From: jeffreyjia Date: Sun, 12 Mar 2023 13:25:53 +0800 Subject: [PATCH 020/126] =?UTF-8?q?=E5=BF=BD=E7=95=A5idea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 -------- .idea/leetcode-master.iml | 9 --------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 4 files changed, 31 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/leetcode-master.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 35410cac..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml -# 基于编辑器的 HTTP 客户端请求 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/leetcode-master.iml b/.idea/leetcode-master.iml deleted file mode 100644 index 5e764c4f..00000000 --- a/.idea/leetcode-master.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 7c250acd..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From abc26c5e5ab377379179dba63f93f7e2eef50353 Mon Sep 17 00:00:00 2001 From: StriveDD Date: Mon, 13 Mar 2023 21:26:29 +0800 Subject: [PATCH 021/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A01020.=E9=A3=9E?= =?UTF-8?q?=E6=8A=B5=E7=9A=84=E6=95=B0=E9=87=8FJava=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1020.飞地的数量.md | 125 +++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/problems/1020.飞地的数量.md b/problems/1020.飞地的数量.md index 3da37376..ad848e73 100644 --- a/problems/1020.飞地的数量.md +++ b/problems/1020.飞地的数量.md @@ -144,6 +144,130 @@ public: } }; ``` +## 其他语言版本 + +**Java**: + +深度优先遍历版本: + +```java +class Solution { + // 四个方向 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + // 深度优先遍历,把可以通向边缘部分的 1 全部标记成 true + public void dfs(int[][] grid, int row, int col, boolean[][] visited) { + for (int[] current: position) { + int newRow = row + current[0], newCol = col + current[1]; + // 下标越界直接跳过 + if (newRow < 0 || newRow >= grid.length || newCol < 0 || newCol >= grid[0].length) continue; + // 当前位置不是 1 或者已经被访问了就直接跳过 + if (grid[newRow][newCol] != 1 || visited[newRow][newCol]) continue; + visited[newRow][newCol] = true; + dfs(grid, newRow, newCol, visited); + } + } + + public int numEnclaves(int[][] grid) { + int rowSize = grid.length, colSize = grid[0].length, ans = 0; // ans 记录答案 + boolean[][] visited = new boolean[rowSize][colSize]; // 标记数组 + // 左侧边界和右侧边界查找 1 进行标记并进行深度优先遍历 + for (int row = 0; row < rowSize; row++) { + if (grid[row][0] == 1 && !visited[row][0]) { + visited[row][0] = true; + dfs(grid, row, 0, visited); + } + if (grid[row][colSize - 1] == 1 && !visited[row][colSize - 1]) { + visited[row][colSize - 1] = true; + dfs(grid, row, colSize - 1, visited); + } + } + // 上边界和下边界遍历,但是四个角不用遍历,因为上面已经遍历到了 + for (int col = 1; col < colSize - 1; col++) { + if (grid[0][col] == 1 && !visited[0][col]) { + visited[0][col] = true; + dfs(grid, 0, col, visited); + } + if (grid[rowSize - 1][col] == 1 && !visited[rowSize - 1][col]) { + visited[rowSize - 1][col] = true; + dfs(grid, rowSize - 1, col, visited); + } + } + // 查找没有标记过的 1,记录到 ans 中 + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (grid[row][col] == 1 && !visited[row][col]) ++ans; + } + } + return ans; + } +} +``` + +广度优先遍历版本: + +```java +class Solution { + // 四个方向 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + // 广度优先遍历,把可以通向边缘部分的 1 全部标记成 true + public void bfs(int[][] grid, Queue queue, boolean[][] visited) { + while (!queue.isEmpty()) { + int[] curPos = queue.poll(); + for (int[] current: position) { + int row = curPos[0] + current[0], col = curPos[1] + current[1]; + // 下标越界直接跳过 + if (row < 0 || row >= grid.length || col < 0 || col >= grid[0].length) + continue; + // 当前位置不是 1 或者已经被访问了就直接跳过 + if (visited[row][col] || grid[row][col] == 0) continue; + visited[row][col] = true; + queue.add(new int[]{row, col}); + } + } + } + + public int numEnclaves(int[][] grid) { + int rowSize = grid.length, colSize = grid[0].length, ans = 0; // ans 记录答案 + boolean[][] visited = new boolean[rowSize][colSize]; // 标记数组 + Queue queue = new ArrayDeque<>(); + // 左侧边界和右侧边界查找 1 进行标记并进行深度优先遍历 + for (int row = 0; row < rowSize; row++) { + if (grid[row][0] == 1) { + visited[row][0] = true; + queue.add(new int[]{row, 0}); + } + if (grid[row][colSize - 1] == 1) { + visited[row][colSize - 1] = true; + queue.add(new int[]{row, colSize - 1}); + } + } + // 上边界和下边界遍历,但是四个角不用遍历,因为上面已经遍历到了 + for (int col = 1; col < colSize - 1; col++) { + if (grid[0][col] == 1) { + visited[0][col] = true; + queue.add(new int[]{0, col}); + } + if (grid[rowSize - 1][col] == 1 && !visited[rowSize - 1][col]) { + visited[rowSize - 1][col] = true; + queue.add(new int[]{rowSize - 1, col}); + } + } + bfs(grid, queue, visited); + // 查找没有标记过的 1,记录到 ans 中 + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + if (grid[row][col] == 1 && !visited[row][col]) ++ans; + } + } + return ans; + } +} +``` + + + ## 类似题目 * 1254. 统计封闭岛屿的数目 @@ -153,3 +277,4 @@ public: + From 2b73437e7283230b340d72fe208b2c39c9d6a3c7 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Tue, 14 Mar 2023 11:35:23 +0800 Subject: [PATCH 022/126] =?UTF-8?q?Update=200045.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8FII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 48 ++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 22151fdc..911834e1 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -379,43 +379,46 @@ object Solution { ```Rust //版本一 impl Solution { - fn max(a: i32, b:i32) -> i32 { - if a > b { a } else { b } - } pub fn jump(nums: Vec) -> i32 { - if nums.len() == 0 { return 0; } - let mut cur_distance: i32 = 0; - let mut ans: i32 = 0; - let mut next_distance: i32 = 0; - for i in 0..nums.len() { - next_distance = Self::max(nums[i] + i as i32, next_distance); - if i as i32 == cur_distance { - if cur_distance != (nums.len() - 1) as i32 { + if nums.len() == 1 { + return 0; + } + let mut cur_distance = 0; + let mut ans = 0; + let mut next_distance = 0; + for (n, &i) in nums.iter().enumerate() { + next_distance = (n as i32 + i).max(next_distance); + if i == cur_distance { + if cur_distance < n as i32 - 1 { ans += 1; cur_distance = next_distance; - if next_distance == (nums.len() - 1) as i32 { break; } + if next_distance >= n as i32 - 1 { + break; + }; + } else { + break; } - else { break; } } } ans } } + ``` ```Rust //版本二 impl Solution { - fn max(a: i32, b:i32) -> i32 { - if a > b { a } else { b } - } pub fn jump(nums: Vec) -> i32 { - let mut cur_distance: i32 = 0; - let mut ans: i32 = 0; - let mut next_distance: i32 = 0; - for i in 0..nums.len() - 1 { - next_distance = Self::max(nums[i] + i as i32, next_distance); - if i as i32 == cur_distance { + if nums.len() == 1 { + return 0; + } + let mut cur_distance = 0; + let mut ans = 0; + let mut next_distance = 0; + for (n, &i) in nums.iter().enumerate() { + next_distance = (n as i32 + i).max(next_distance); + if i == cur_distance { cur_distance = next_distance; ans += 1; } @@ -423,6 +426,7 @@ impl Solution { ans } } + ``` From 05028415306e7678ef1121e7c93dd6611897d68e Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Tue, 14 Mar 2023 11:58:01 +0800 Subject: [PATCH 023/126] =?UTF-8?q?Update=200045.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8FII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 911834e1..9b13d31d 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -386,13 +386,13 @@ impl Solution { let mut cur_distance = 0; let mut ans = 0; let mut next_distance = 0; - for (n, &i) in nums.iter().enumerate() { - next_distance = (n as i32 + i).max(next_distance); + for (i, &n) in nums.iter().enumerate().take(nums.len() - 1) { + next_distance = (n as usize + i).max(next_distance); if i == cur_distance { - if cur_distance < n as i32 - 1 { + if cur_distance < nums.len() - 1 { ans += 1; cur_distance = next_distance; - if next_distance >= n as i32 - 1 { + if next_distance >= nums.len() - 1 { break; }; } else { @@ -403,7 +403,6 @@ impl Solution { ans } } - ``` ```Rust @@ -416,8 +415,8 @@ impl Solution { let mut cur_distance = 0; let mut ans = 0; let mut next_distance = 0; - for (n, &i) in nums.iter().enumerate() { - next_distance = (n as i32 + i).max(next_distance); + for (i, &n) in nums.iter().enumerate().take(nums.len() - 1) { + next_distance = (n as usize + i).max(next_distance); if i == cur_distance { cur_distance = next_distance; ans += 1; @@ -426,7 +425,6 @@ impl Solution { ans } } - ``` From 411ef134a7e194e281affa0be45efe9bbcad4a25 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Tue, 14 Mar 2023 12:33:05 +0800 Subject: [PATCH 024/126] =?UTF-8?q?Update=201005.K=E6=AC=A1=E5=8F=96?= =?UTF-8?q?=E5=8F=8D=E5=90=8E=E6=9C=80=E5=A4=A7=E5=8C=96=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...1005.K次取反后最大化的数组和.md | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index cdf42511..439bdfde 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -231,23 +231,18 @@ var largestSumAfterKNegations = function(nums, k) { ```Rust impl Solution { - pub fn largest_sum_after_k_negations(nums: Vec, k: i32) -> i32 { - let mut nums = nums; - let mut k = k; - let len = nums.len(); - nums.sort_by(|a, b| b.abs().cmp(&a.abs())); - for i in 0..len { - if nums[i] < 0 && k > 0 { - nums[i] *= -1; + pub fn largest_sum_after_k_negations(mut nums: Vec, mut k: i32) -> i32 { + nums.sort_by_key(|b| std::cmp::Reverse(b.abs())); + for v in nums.iter_mut() { + if *v < 0 && k > 0 { + *v *= -1; k -= 1; } } - if k % 2 == 1 { nums[len - 1] *= -1; } - let mut result = 0; - for num in nums { - result += num; + if k % 2 == 1 { + *nums.last_mut().unwrap() *= -1; } - result + nums.iter().sum() } } ``` From d1eccfba1a51880bece8edba08894000591eb3e0 Mon Sep 17 00:00:00 2001 From: StriveDD Date: Tue, 14 Mar 2023 19:05:39 +0800 Subject: [PATCH 025/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A00417.=E5=A4=AA?= =?UTF-8?q?=E5=B9=B3=E6=B4=8B=E5=A4=A7=E8=A5=BF=E6=B4=8B=E6=B0=B4=E6=B5=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98.md=E7=9A=84Java=E7=89=88=E6=9C=AC=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0417.太平洋大西洋水流问题.md | 124 +++++++++++++++++- problems/1020.飞地的数量.md | 3 +- 2 files changed, 123 insertions(+), 4 deletions(-) diff --git a/problems/0417.太平洋大西洋水流问题.md b/problems/0417.太平洋大西洋水流问题.md index f936399b..0ec8ebf9 100644 --- a/problems/0417.太平洋大西洋水流问题.md +++ b/problems/0417.太平洋大西洋水流问题.md @@ -230,17 +230,137 @@ for (int j = 0; j < m; j++) { dfs (heights, pacific, 0, j); // 遍历最左列,接触太平洋 dfs (heights, atlantic, n - 1, j); // 遍历最右列,接触大西洋 } -``` +``` 那么本题整体的时间复杂度其实是: 2 * n * m + n * m ,所以最终时间复杂度为 O(n * m) 。 空间复杂度为:O(n * m) 这个就不难理解了。开了几个 n * m 的数组。 - ## 其他语言版本 +### Java + +深度优先遍历: + +```Java +class Solution { + // 四个位置 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + /** + * @param heights 题目给定的二维数组 + * @param row 当前位置的行号 + * @param col 当前位置的列号 + * @param sign 记录是哪一条河,两条河中可以一个为 0,一个为 1 + * @param visited 记录这个位置可以到哪条河 + */ + public void dfs(int[][] heights, int row, int col, int sign, boolean[][][] visited) { + for (int[] current: position) { + int curRow = row + current[0], curCol = col + current[1]; + // 越界 + if (curRow < 0 || curRow >= heights.length || curCol < 0 || curCol >= heights[0].length) + continue; + // 高度不合适或者已经被访问过了 + if (heights[curRow][curCol] < heights[row][col] || visited[curRow][curCol][sign]) continue; + visited[curRow][curCol][sign] = true; + dfs(heights, curRow, curCol, sign, visited); + } + } + + public List> pacificAtlantic(int[][] heights) { + int rowSize = heights.length, colSize = heights[0].length; + List> ans = new ArrayList<>(); + // 记录 [row, col] 位置是否可以到某条河,可以为 true,反之为 false; + // 假设太平洋的标记为 1,大西洋为 0 + boolean[][][] visited = new boolean[rowSize][colSize][2]; + for (int row = 0; row < rowSize; row++) { + visited[row][colSize - 1][0] = true; + visited[row][0][1] = true; + dfs(heights, row, colSize - 1, 0, visited); + dfs(heights, row, 0, 1, visited); + } + for (int col = 0; col < colSize; col++) { + visited[rowSize - 1][col][0] = true; + visited[0][col][1] = true; + dfs(heights, rowSize - 1, col, 0, visited); + dfs(heights, 0, col, 1, visited); + } + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + // 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if (visited[row][col][0] && visited[row][col][1]) + ans.add(List.of(row, col)); + } + } + return ans; + } +} +``` + +广度优先遍历: + +```Java +class Solution { + // 四个位置 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + /** + * @param heights 题目给定的二维数组 + * @param queue 记录可以到达边界的节点 + * @param visited 记录这个位置可以到哪条河 + */ + public void bfs(int[][] heights, Queue queue, boolean[][][] visited) { + while (!queue.isEmpty()) { + int[] curPos = queue.poll(); + for (int[] current: position) { + int row = curPos[0] + current[0], col = curPos[1] + current[1], sign = curPos[2]; + // 越界 + if (row < 0 || row >= heights.length || col < 0 || col >= heights[0].length) continue; + // 高度不合适或者已经被访问过了 + if (heights[row][col] < heights[curPos[0]][curPos[1]] || visited[row][col][sign]) continue; + visited[row][col][sign] = true; + queue.add(new int[]{row, col, sign}); + } + } + } + + public List> pacificAtlantic(int[][] heights) { + int rowSize = heights.length, colSize = heights[0].length; + List> ans = new ArrayList<>(); + boolean[][][] visited = new boolean[rowSize][colSize][2]; + // 队列,保存的数据为 [行号, 列号, 标记] + // 假设太平洋的标记为 1,大西洋为 0 + Queue queue = new ArrayDeque<>(); + for (int row = 0; row < rowSize; row++) { + visited[row][colSize - 1][0] = true; + visited[row][0][1] = true; + queue.add(new int[]{row, colSize - 1, 0}); + queue.add(new int[]{row, 0, 1}); + } + for (int col = 0; col < colSize; col++) { + visited[rowSize - 1][col][0] = true; + visited[0][col][1] = true; + queue.add(new int[]{rowSize - 1, col, 0}); + queue.add(new int[]{0, col, 1}); + } + bfs(heights, queue, visited); + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + // 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if (visited[row][col][0] && visited[row][col][1]) + ans.add(List.of(row, col)); + } + } + return ans; + } +} +``` + + +

+ diff --git a/problems/1020.飞地的数量.md b/problems/1020.飞地的数量.md index ad848e73..d244e60c 100644 --- a/problems/1020.飞地的数量.md +++ b/problems/1020.飞地的数量.md @@ -146,7 +146,7 @@ public: ``` ## 其他语言版本 -**Java**: +### Java 深度优先遍历版本: @@ -277,4 +277,3 @@ class Solution { - From d002d8769cfae23d0f5656bf9f36ba10590371d7 Mon Sep 17 00:00:00 2001 From: StriveDD Date: Wed, 15 Mar 2023 20:36:34 +0800 Subject: [PATCH 026/126] =?UTF-8?q?=E6=8F=90=E4=BA=A41020.=E9=A3=9E?= =?UTF-8?q?=E6=8A=B5=E7=9A=84=E6=95=B0=E9=87=8F.md=E7=9A=84Python=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=BB=A3=E7=A0=81=EF=BC=8C0417.=E5=A4=AA=E5=B9=B3?= =?UTF-8?q?=E6=B4=8B=E5=A4=A7=E8=A5=BF=E6=B4=8B=E6=B0=B4=E6=B5=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98.md=E7=9A=84Python=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0417.太平洋大西洋水流问题.md | 95 ++++++++++++++- problems/1020.飞地的数量.md | 113 +++++++++++++++++- 2 files changed, 202 insertions(+), 6 deletions(-) diff --git a/problems/0417.太平洋大西洋水流问题.md b/problems/0417.太平洋大西洋水流问题.md index 0ec8ebf9..ec229365 100644 --- a/problems/0417.太平洋大西洋水流问题.md +++ b/problems/0417.太平洋大西洋水流问题.md @@ -356,6 +356,100 @@ class Solution { } ``` +### Python + +深度优先遍历 + +```Python3 +class Solution: + def __init__(self): + self.position = [[-1, 0], [0, 1], [1, 0], [0, -1]] # 四个方向 + + # heights:题目给定的二维数组, row:当前位置的行号, col:当前位置的列号 + # sign:记录是哪一条河,两条河中可以一个为 0,一个为 1 + # visited:记录这个位置可以到哪条河 + def dfs(self, heights: List[List[int]], row: int, col: int, sign: int, visited: List[List[List[int]]]): + for current in self.position: + curRow, curCol = row + current[0], col + current[1] + # 索引下标越界 + if curRow < 0 or curRow >= len(heights) or curCol < 0 or curCol >= len(heights[0]): continue + # 不满足条件或者已经被访问过 + if heights[curRow][curCol] < heights[row][col] or visited[curRow][curCol][sign]: continue + visited[curRow][curCol][sign] = True + self.dfs(heights, curRow, curCol, sign, visited) + + def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: + rowSize, colSize = len(heights), len(heights[0]) + # visited 记录 [row, col] 位置是否可以到某条河,可以为 true,反之为 false; + # 假设太平洋的标记为 1,大西洋为 0 + # ans 用来保存满足条件的答案 + ans, visited = [], [[[False for _ in range(2)] for _ in range(colSize)] for _ in range(rowSize)] + for row in range(rowSize): + visited[row][0][1] = True + visited[row][colSize - 1][0] = True + self.dfs(heights, row, 0, 1, visited) + self.dfs(heights, row, colSize - 1, 0, visited) + for col in range(0, colSize): + visited[0][col][1] = True + visited[rowSize - 1][col][0] = True + self.dfs(heights, 0, col, 1, visited) + self.dfs(heights, rowSize - 1, col, 0, visited) + for row in range(rowSize): + for col in range(colSize): + # 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if visited[row][col][0] and visited[row][col][1]: + ans.append([row, col]) + return ans +``` + +广度优先遍历 + +```Python3 +class Solution: + def __init__(self): + self.position = [[-1, 0], [0, 1], [1, 0], [0, -1]] + + # heights:题目给定的二维数组,visited:记录这个位置可以到哪条河 + def bfs(self, heights: List[List[int]], queue: deque, visited: List[List[List[int]]]): + while queue: + curPos = queue.popleft() + for current in self.position: + row, col, sign = curPos[0] + current[0], curPos[1] + current[1], curPos[2] + # 越界 + if row < 0 or row >= len(heights) or col < 0 or col >= len(heights[0]): continue + # 不满足条件或已经访问过 + if heights[row][col] < heights[curPos[0]][curPos[1]] or visited[row][col][sign]: continue + visited[row][col][sign] = True + queue.append([row, col, sign]) + + def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: + rowSize, colSize = len(heights), len(heights[0]) + # visited 记录 [row, col] 位置是否可以到某条河,可以为 true,反之为 false; + # 假设太平洋的标记为 1,大西洋为 0 + # ans 用来保存满足条件的答案 + ans, visited = [], [[[False for _ in range(2)] for _ in range(colSize)] for _ in range(rowSize)] + # 队列,保存的数据为 [行号, 列号, 标记] + # 假设太平洋的标记为 1,大西洋为 0 + queue = deque() + for row in range(rowSize): + visited[row][0][1] = True + visited[row][colSize - 1][0] = True + queue.append([row, 0, 1]) + queue.append([row, colSize - 1, 0]) + for col in range(0, colSize): + visited[0][col][1] = True + visited[rowSize - 1][col][0] = True + queue.append([0, col, 1]) + queue.append([rowSize - 1, col, 0]) + self.bfs(heights, queue, visited) # 广度优先遍历 + for row in range(rowSize): + for col in range(colSize): + # 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if visited[row][col][0] and visited[row][col][1]: + ans.append([row, col]) + return ans +``` + @@ -363,4 +457,3 @@ class Solution { - diff --git a/problems/1020.飞地的数量.md b/problems/1020.飞地的数量.md index d244e60c..f97678e8 100644 --- a/problems/1020.飞地的数量.md +++ b/problems/1020.飞地的数量.md @@ -170,7 +170,8 @@ class Solution { public int numEnclaves(int[][] grid) { int rowSize = grid.length, colSize = grid[0].length, ans = 0; // ans 记录答案 - boolean[][] visited = new boolean[rowSize][colSize]; // 标记数组 + // 标记数组记录每个值为 1 的位置是否可以到达边界,可以为 true,反之为 false + boolean[][] visited = new boolean[rowSize][colSize]; // 左侧边界和右侧边界查找 1 进行标记并进行深度优先遍历 for (int row = 0; row < rowSize; row++) { if (grid[row][0] == 1 && !visited[row][0]) { @@ -230,9 +231,10 @@ class Solution { public int numEnclaves(int[][] grid) { int rowSize = grid.length, colSize = grid[0].length, ans = 0; // ans 记录答案 - boolean[][] visited = new boolean[rowSize][colSize]; // 标记数组 + // 标记数组记录每个值为 1 的位置是否可以到达边界,可以为 true,反之为 false + boolean[][] visited = new boolean[rowSize][colSize]; Queue queue = new ArrayDeque<>(); - // 左侧边界和右侧边界查找 1 进行标记并进行深度优先遍历 + // 搜索左侧边界和右侧边界查找 1 存入队列 for (int row = 0; row < rowSize; row++) { if (grid[row][0] == 1) { visited[row][0] = true; @@ -243,7 +245,7 @@ class Solution { queue.add(new int[]{row, colSize - 1}); } } - // 上边界和下边界遍历,但是四个角不用遍历,因为上面已经遍历到了 + // 搜索上边界和下边界遍历,但是四个角不用遍历,因为上面已经遍历到了 for (int col = 1; col < colSize - 1; col++) { if (grid[0][col] == 1) { visited[0][col] = true; @@ -254,7 +256,7 @@ class Solution { queue.add(new int[]{rowSize - 1, col}); } } - bfs(grid, queue, visited); + bfs(grid, queue, visited); // 广度优先遍历 // 查找没有标记过的 1,记录到 ans 中 for (int row = 0; row < rowSize; row++) { for (int col = 0; col < colSize; col++) { @@ -266,6 +268,106 @@ class Solution { } ``` +### Python + +深度优先遍历 + +```Python3 +class Solution: + def __init__(self): + self.position = [[-1, 0], [0, 1], [1, 0], [0, -1]] # 四个方向 + + # 深度优先遍历,把可以通向边缘部分的 1 全部标记成 true + def dfs(self, grid: List[List[int]], row: int, col: int, visited: List[List[bool]]) -> None: + for current in self.position: + newRow, newCol = row + current[0], col + current[1] + # 索引下标越界 + if newRow < 0 or newRow >= len(grid) or newCol < 0 or newCol >= len(grid[0]): + continue + # 当前位置值不是 1 或者已经被访问过了 + if grid[newRow][newCol] == 0 or visited[newRow][newCol]: continue + visited[newRow][newCol] = True + self.dfs(grid, newRow, newCol, visited) + + def numEnclaves(self, grid: List[List[int]]) -> int: + rowSize, colSize, ans = len(grid), len(grid[0]), 0 + # 标记数组记录每个值为 1 的位置是否可以到达边界,可以为 True,反之为 False + visited = [[False for _ in range(colSize)] for _ in range(rowSize)] + # 搜索左边界和右边界,对值为 1 的位置进行深度优先遍历 + for row in range(rowSize): + if grid[row][0] == 1: + visited[row][0] = True + self.dfs(grid, row, 0, visited) + if grid[row][colSize - 1] == 1: + visited[row][colSize - 1] = True + self.dfs(grid, row, colSize - 1, visited) + # 搜索上边界和下边界,对值为 1 的位置进行深度优先遍历,但是四个角不需要,因为上面遍历过了 + for col in range(1, colSize - 1): + if grid[0][col] == 1: + visited[0][col] = True + self.dfs(grid, 0, col, visited) + if grid[rowSize - 1][col] == 1: + visited[rowSize - 1][col] = True + self.dfs(grid, rowSize - 1, col, visited) + # 找出矩阵中值为 1 但是没有被标记过的位置,记录答案 + for row in range(rowSize): + for col in range(colSize): + if grid[row][col] == 1 and not visited[row][col]: + ans += 1 + return ans +``` + +广度优先遍历 + +```Python3 +class Solution: + def __init__(self): + self.position = [[-1, 0], [0, 1], [1, 0], [0, -1]] # 四个方向 + + # 广度优先遍历,把可以通向边缘部分的 1 全部标记成 true + def bfs(self, grid: List[List[int]], queue: deque, visited: List[List[bool]]) -> None: + while queue: + curPos = queue.popleft() + for current in self.position: + row, col = curPos[0] + current[0], curPos[1] + current[1] + # 索引下标越界 + if row < 0 or row >= len(grid) or col < 0 or col >= len(grid[0]): continue + # 当前位置值不是 1 或者已经被访问过了 + if grid[row][col] == 0 or visited[row][col]: continue + visited[row][col] = True + queue.append([row, col]) + + + def numEnclaves(self, grid: List[List[int]]) -> int: + rowSize, colSize, ans = len(grid), len(grid[0]), 0 + # 标记数组记录每个值为 1 的位置是否可以到达边界,可以为 True,反之为 False + visited = [[False for _ in range(colSize)] for _ in range(rowSize)] + queue = deque() # 队列 + # 搜索左侧边界和右侧边界查找 1 存入队列 + for row in range(rowSize): + if grid[row][0] == 1: + visited[row][0] = True + queue.append([row, 0]) + if grid[row][colSize - 1] == 1: + visited[row][colSize - 1] = True + queue.append([row, colSize - 1]) + # 搜索上边界和下边界查找 1 存入队列,但是四个角不用遍历,因为上面已经遍历到了 + for col in range(1, colSize - 1): + if grid[0][col] == 1: + visited[0][col] = True + queue.append([0, col]) + if grid[rowSize - 1][col] == 1: + visited[rowSize - 1][col] = True + queue.append([rowSize - 1, col]) + self.bfs(grid, queue, visited) # 广度优先遍历 + # 找出矩阵中值为 1 但是没有被标记过的位置,记录答案 + for row in range(rowSize): + for col in range(colSize): + if grid[row][col] == 1 and not visited[row][col]: + ans += 1 + return ans +``` + ## 类似题目 @@ -277,3 +379,4 @@ class Solution { + From ef00e2c35dfe1ecb2223fe4a32b75cfa91ec042c Mon Sep 17 00:00:00 2001 From: ZashJie <1030298236@qq.com> Date: Thu, 16 Mar 2023 12:20:42 +0800 Subject: [PATCH 027/126] modify_01 --- problems/背包理论基础01背包-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index ff0b6aba..c45fc3d3 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -87,7 +87,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目, 那么可以有两个方向推出来dp[i][j], -* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。) +* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。) * **放物品i**:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); From 2175be827dbe4215f3ccf55048e62b158a936a0e Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Thu, 16 Mar 2023 22:24:32 +0800 Subject: [PATCH 028/126] =?UTF-8?q?update=200242.=E6=9C=89=E6=95=88?= =?UTF-8?q?=E7=9A=84=E5=AD=97=E6=AF=8D=E5=BC=82=E4=BD=8D=E8=AF=8D:=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0242.有效的字母异位词.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0242.有效的字母异位词.md b/problems/0242.有效的字母异位词.md index 9f84a5cd..1006ea35 100644 --- a/problems/0242.有效的字母异位词.md +++ b/problems/0242.有效的字母异位词.md @@ -85,6 +85,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + ## 其他语言版本 From 9a4086cd3628b0199e7e4b51eefe7dfab35688b3 Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Thu, 16 Mar 2023 19:55:49 -0400 Subject: [PATCH 029/126] =?UTF-8?q?Update=200222.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E8=8A=82=E7=82=B9=E4=B8=AA?= =?UTF-8?q?=E6=95=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加完全二叉树写法2,更易理解且减少非完全二叉树节点的迭代次数 --- problems/0222.完全二叉树的节点个数.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md index c346b6ff..d89a9bce 100644 --- a/problems/0222.完全二叉树的节点个数.md +++ b/problems/0222.完全二叉树的节点个数.md @@ -379,6 +379,20 @@ class Solution: return (2 << leftDepth) - 1 #注意(2<<1) 相当于2^2,所以leftDepth初始为0 return self.countNodes(root.left) + self.countNodes(root.right) + 1 ``` +完全二叉树写法2 +```python +class Solution: # 利用完全二叉树特性 + def countNodes(self, root: TreeNode) -> int: + if not root: return 0 + count = 1 + left = root.left; right = root.right + while left and right: + count+=1 + left = left.left; right = right.right + if not left and not right: # 如果同时到底说明是满二叉树,反之则不是 + return 2**count-1 + return 1+self.countNodes(root.left)+self.countNodes(root.right) +``` ## Go From c3588f445f13ec540e7c44e031924d946922a588 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:09:35 +0800 Subject: [PATCH 030/126] =?UTF-8?q?docs:=20=E5=88=86=E5=8F=91=E9=A5=BC?= =?UTF-8?q?=E5=B9=B2=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E8=AE=B2=E8=A7=A3?= =?UTF-8?q?=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0455.分发饼干.md | 157 ++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/problems/0455.分发饼干.md b/problems/0455.分发饼干.md index 63525b03..3688b3fd 100644 --- a/problems/0455.分发饼干.md +++ b/problems/0455.分发饼干.md @@ -4,31 +4,35 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

- # 455.分发饼干 [力扣题目链接](https://leetcode.cn/problems/assign-cookies/) 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 -对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 +对每个孩子 i,都有一个胃口值  g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 -示例 1: -* 输入: g = [1,2,3], s = [1,1] -* 输出: 1 -解释:你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。所以你应该输出1。 +示例  1: -示例 2: -* 输入: g = [1,2], s = [1,2,3] -* 输出: 2 -* 解释:你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。你拥有的饼干数量和尺寸都足以让所有孩子满足。所以你应该输出2. +- 输入: g = [1,2,3], s = [1,1] +- 输出: 1 + 解释:你有三个孩子和两块小饼干,3 个孩子的胃口值分别是:1,2,3。虽然你有两块小饼干,由于他们的尺寸都是 1,你只能让胃口值是 1 的孩子满足。所以你应该输出 1。 +示例  2: + +- 输入: g = [1,2], s = [1,2,3] +- 输出: 2 +- 解释:你有两个孩子和三块小饼干,2 个孩子的胃口值分别是 1,2。你拥有的饼干数量和尺寸都足以让所有孩子满足。所以你应该输出 2. 提示: -* 1 <= g.length <= 3 * 10^4 -* 0 <= s.length <= 3 * 10^4 -* 1 <= g[i], s[j] <= 2^31 - 1 +- 1 <= g.length <= 3 \* 10^4 +- 0 <= s.length <= 3 \* 10^4 +- 1 <= g[i], s[j] <= 2^31 - 1 + +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,你想先喂哪个小孩?| LeetCode:455.分发饼干](https://www.bilibili.com/video/BV1MM411b7cq),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 @@ -46,14 +50,12 @@ ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230203105634.png) - -这个例子可以看出饼干9只有喂给胃口为7的小孩,这样才是整体最优解,并想不出反例,那么就可以撸代码了。 - +这个例子可以看出饼干 9 只有喂给胃口为 7 的小孩,这样才是整体最优解,并想不出反例,那么就可以撸代码了。 C++代码整体如下: ```CPP -// 版本一 +// 版本一 // 时间复杂度:O(nlogn) // 空间复杂度:O(1) class Solution { @@ -63,8 +65,8 @@ public: sort(s.begin(), s.end()); int index = s.size() - 1; // 饼干数组的下标 int result = 0; - for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口 - if (index >= 0 && s[index] >= g[i]) { // 遍历饼干 + for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口 + if (index >= 0 && s[index] >= g[i]) { // 遍历饼干 result++; index--; } @@ -74,27 +76,25 @@ public: }; ``` -从代码中可以看出我用了一个index来控制饼干数组的遍历,遍历饼干并没有再起一个for循环,而是采用自减的方式,这也是常用的技巧。 +从代码中可以看出我用了一个 index 来控制饼干数组的遍历,遍历饼干并没有再起一个 for 循环,而是采用自减的方式,这也是常用的技巧。 -有的同学看到要遍历两个数组,就想到用两个for循环,那样逻辑其实就复杂了。 +有的同学看到要遍历两个数组,就想到用两个 for 循环,那样逻辑其实就复杂了。 +### 注意事项 -### 注意事项 +注意版本一的代码中,可以看出来,是先遍历的胃口,在遍历的饼干,那么可不可以 先遍历 饼干,在遍历胃口呢? -注意版本一的代码中,可以看出来,是先遍历的胃口,在遍历的饼干,那么可不可以 先遍历 饼干,在遍历胃口呢? +其实是不可以的。 -其实是不可以的。 +外面的 for 是里的下标 i 是固定移动的,而 if 里面的下标 index 是符合条件才移动的。 -外面的for 是里的下标i 是固定移动的,而if里面的下标 index 是符合条件才移动的。 - -如果 for 控制的是饼干, if 控制胃口,就是出现如下情况 : +如果 for 控制的是饼干, if 控制胃口,就是出现如下情况 : ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230112102848.png) -if 里的 index 指向 胃口 10, for里的i指向饼干9,因为 饼干9 满足不了 胃口10,所以 i 持续向前移动,而index 走不到` s[index] >= g[i]` 的逻辑,所以index不会移动,那么当i 持续向前移动,最后所有的饼干都匹配不上。 - -所以 一定要for 控制 胃口,里面的if控制饼干。 +if 里的 index 指向 胃口 10, for 里的 i 指向饼干 9,因为 饼干 9 满足不了 胃口 10,所以 i 持续向前移动,而 index 走不到` s[index] >= g[i]` 的逻辑,所以 index 不会移动,那么当 i 持续向前移动,最后所有的饼干都匹配不上。 +所以 一定要 for 控制 胃口,里面的 if 控制饼干。 ### 其他思路 @@ -117,11 +117,11 @@ public: return index; } }; -``` +``` -细心的录友可以发现,这种写法,两个循环的顺序改变了,先遍历的饼干,在遍历的胃口,这是因为遍历顺序变了,我们是从小到大遍历。 +细心的录友可以发现,这种写法,两个循环的顺序改变了,先遍历的饼干,在遍历的胃口,这是因为遍历顺序变了,我们是从小到大遍历。 -理由在上面 “注意事项”中 已经讲过。 +理由在上面 “注意事项”中 已经讲过。 ## 总结 @@ -131,8 +131,8 @@ public: ## 其他语言版本 - ### Java + ```java class Solution { // 思路1:优先考虑饼干,小饼干先喂饱小胃口 @@ -151,6 +151,7 @@ class Solution { } } ``` + ```java class Solution { // 思路2:优先考虑胃口,先喂饱大胃口 @@ -172,6 +173,7 @@ class Solution { ``` ### Python + ```python class Solution: # 思路1:优先考虑小胃口 @@ -184,6 +186,7 @@ class Solution: res += 1 return res ``` + ```python class Solution: # 思路2:优先考虑大胃口 @@ -199,6 +202,7 @@ class Solution: ``` ### Go + ```golang //排序后,局部最优 func findContentChildren(g []int, s []int) int { @@ -218,6 +222,7 @@ func findContentChildren(g []int, s []int) int { ``` ### Rust + ```rust pub fn find_content_children(mut children: Vec, mut cookie: Vec) -> i32 { children.sort(); @@ -236,21 +241,21 @@ pub fn find_content_children(mut children: Vec, mut cookie: Vec) -> i3 ``` ### Javascript -```js -var findContentChildren = function(g, s) { - g = g.sort((a, b) => a - b) - s = s.sort((a, b) => a - b) - let result = 0 - let index = s.length - 1 - for(let i = g.length - 1; i >= 0; i--) { - if(index >= 0 && s[index] >= g[i]) { - result++ - index-- - } - } - return result -}; +```js +var findContentChildren = function (g, s) { + g = g.sort((a, b) => a - b); + s = s.sort((a, b) => a - b); + let result = 0; + let index = s.length - 1; + for (let i = g.length - 1; i >= 0; i--) { + if (index >= 0 && s[index] >= g[i]) { + result++; + index--; + } + } + return result; +}; ``` ### TypeScript @@ -258,41 +263,41 @@ var findContentChildren = function(g, s) { ```typescript // 大饼干尽量喂胃口大的 function findContentChildren(g: number[], s: number[]): number { - g.sort((a, b) => a - b); - s.sort((a, b) => a - b); - const childLength: number = g.length, - cookieLength: number = s.length; - let curChild: number = childLength - 1, - curCookie: number = cookieLength - 1; - let resCount: number = 0; - while (curChild >= 0 && curCookie >= 0) { - if (g[curChild] <= s[curCookie]) { - curCookie--; - resCount++; - } - curChild--; + g.sort((a, b) => a - b); + s.sort((a, b) => a - b); + const childLength: number = g.length, + cookieLength: number = s.length; + let curChild: number = childLength - 1, + curCookie: number = cookieLength - 1; + let resCount: number = 0; + while (curChild >= 0 && curCookie >= 0) { + if (g[curChild] <= s[curCookie]) { + curCookie--; + resCount++; } - return resCount; -}; + curChild--; + } + return resCount; +} ``` ```typescript // 小饼干先喂饱小胃口的 function findContentChildren(g: number[], s: number[]): number { - g.sort((a, b) => a - b); - s.sort((a, b) => a - b); - const childLength: number = g.length, - cookieLength: number = s.length; - let curChild: number = 0, - curCookie: number = 0; - while (curChild < childLength && curCookie < cookieLength) { - if (g[curChild] <= s[curCookie]) { - curChild++; - } - curCookie++; + g.sort((a, b) => a - b); + s.sort((a, b) => a - b); + const childLength: number = g.length, + cookieLength: number = s.length; + let curChild: number = 0, + curCookie: number = 0; + while (curChild < childLength && curCookie < cookieLength) { + if (g[curChild] <= s[curCookie]) { + curChild++; } - return curChild; -}; + curCookie++; + } + return curChild; +} ``` ### C From 5678f566a8985e145c22f8297abc38744cc98463 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:11:35 +0800 Subject: [PATCH 031/126] =?UTF-8?q?docs:=20=E6=91=86=E5=8A=A8=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E8=AE=B2=E8=A7=A3?= =?UTF-8?q?=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0376.摆动序列.md | 215 ++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 104 deletions(-) diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md index 925d7262..469c19fd 100644 --- a/problems/0376.摆动序列.md +++ b/problems/0376.摆动序列.md @@ -4,7 +4,6 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

- > 本周讲解了[贪心理论基础](https://programmercarl.com/贪心算法理论基础.html),以及第一道贪心的题目:[贪心算法:分发饼干](https://programmercarl.com/0455.分发饼干.html),可能会给大家一种贪心算法比较简单的错觉,好了,接下来几天的题目难度要上来了,哈哈。 # 376. 摆动序列 @@ -13,25 +12,32 @@ 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。 -例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 +例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3)  是正负交替出现的。相反, [1,4,7,2,5]  和  [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。 示例 1: -* 输入: [1,7,4,9,2,5] -* 输出: 6 -* 解释: 整个序列均为摆动序列。 + +- 输入: [1,7,4,9,2,5] +- 输出: 6 +- 解释: 整个序列均为摆动序列。 示例 2: -* 输入: [1,17,5,10,13,15,10,5,16,8] -* 输出: 7 -* 解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。 + +- 输入: [1,17,5,10,13,15,10,5,16,8] +- 输出: 7 +- 解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。 示例 3: -* 输入: [1,2,3,4,5,6,7,8,9] -* 输出: 2 -## 思路1(贪心解法) +- 输入: [1,2,3,4,5,6,7,8,9] +- 输出: 2 + +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,寻找摆动有细节!| LeetCode:376.摆动序列](https://www.bilibili.com/video/BV17M411b7NS),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + +## 思路 1(贪心解法) 本题要求通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。 @@ -53,63 +59,61 @@ **实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)** -**这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点** +**这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点** -在计算是否有峰值的时候,大家知道遍历的下标i ,计算prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果`prediff < 0 && curdiff > 0` 或者 `prediff > 0 && curdiff < 0` 此时就有波动就需要统计。 +在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果`prediff < 0 && curdiff > 0` 或者 `prediff > 0 && curdiff < 0` 此时就有波动就需要统计。 这是我们思考本题的一个大题思路,但本题要考虑三种情况: -1. 情况一:上下坡中有平坡 -2. 情况二:数组首尾两端 +1. 情况一:上下坡中有平坡 +2. 情况二:数组首尾两端 3. 情况三:单调坡中有平坡 ### 情况一:上下坡中有平坡 -例如 [1,2,2,2,1]这样的数组,如图: +例如 [1,2,2,2,1]这样的数组,如图: -![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230106170449.png) +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230106170449.png) -它的摇摆序列长度是多少呢? **其实是长度是3**,也就是我们在删除的时候 要不删除左面的三个2,要不就删除右边的三个2。 +它的摇摆序列长度是多少呢? **其实是长度是 3**,也就是我们在删除的时候 要不删除左面的三个 2,要不就删除右边的三个 2。 -如图,可以统一规则,删除左边的三个2: +如图,可以统一规则,删除左边的三个 2: ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230106172613.png) -在图中,当i指向第一个2的时候,`prediff > 0 && curdiff = 0` ,当 i 指向最后一个2的时候 `prediff = 0 && curdiff < 0`。 +在图中,当 i 指向第一个 2 的时候,`prediff > 0 && curdiff = 0` ,当 i 指向最后一个 2 的时候 `prediff = 0 && curdiff < 0`。 -如果我们采用,删左面三个2的规则,那么 当 `prediff = 0 && curdiff < 0` 也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。 +如果我们采用,删左面三个 2 的规则,那么 当 `prediff = 0 && curdiff < 0` 也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。 -所以我们记录峰值的条件应该是: `(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)`,为什么这里允许 prediff == 0 ,就是为了 上面我说的这种情况。 +所以我们记录峰值的条件应该是: `(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)`,为什么这里允许 prediff == 0 ,就是为了 上面我说的这种情况。 +### 情况二:数组首尾两端 -### 情况二:数组首尾两端 +所以本题统计峰值的时候,数组最左面和最右面如果统计呢? +题目中说了,如果只有两个不同的元素,那摆动序列也是 2。 -所以本题统计峰值的时候,数组最左面和最右面如果统计呢? - -题目中说了,如果只有两个不同的元素,那摆动序列也是2。 - -例如序列[2,5],如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。 +例如序列[2,5],如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。 因为我们在计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i])的时候,至少需要三个数字才能计算,而数组只有两个数字。 -这里我们可以写死,就是 如果只有两个元素,且元素不同,那么结果为2。 +这里我们可以写死,就是 如果只有两个元素,且元素不同,那么结果为 2。 -不写死的话,如果和我们的判断规则结合在一起呢? +不写死的话,如果和我们的判断规则结合在一起呢? -可以假设,数组最前面还有一个数字,那这个数字应该是什么呢? +可以假设,数组最前面还有一个数字,那这个数字应该是什么呢? -之前我们在 讨论 情况一:相同数字连续 的时候, prediff = 0 ,curdiff < 0 或者 >0 也记为波谷。 +之前我们在 讨论 情况一:相同数字连续 的时候, prediff = 0 ,curdiff < 0 或者 >0 也记为波谷。 -那么为了规则统一,针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即preDiff = 0,如图: +那么为了规则统一,针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即 preDiff = 0,如图: ![376.摆动序列1](https://code-thinking-1253855093.file.myqcloud.com/pics/20201124174357612.png) -针对以上情形,result初始为1(默认最右面有一个峰值),此时curDiff > 0 && preDiff <= 0,那么result++(计算了左面的峰值),最后得到的result就是2(峰值个数为2即摆动序列长度为2) +针对以上情形,result 初始为 1(默认最右面有一个峰值),此时 curDiff > 0 && preDiff <= 0,那么 result++(计算了左面的峰值),最后得到的 result 就是 2(峰值个数为 2 即摆动序列长度为 2) 经过以上分析后,我们可以写出如下代码: -```CPP +```CPP // 版本一 class Solution { public: @@ -129,33 +133,34 @@ public: return result; } }; -``` -* 时间复杂度:O(n) -* 空间复杂度:O(1) +``` -此时大家是不是发现 以上代码提交也不能通过本题? +- 时间复杂度:O(n) +- 空间复杂度:O(1) + +此时大家是不是发现 以上代码提交也不能通过本题? 所以此时我们要讨论情况三! -### 情况三:单调坡度有平坡 +### 情况三:单调坡度有平坡 -在版本一中,我们忽略了一种情况,即 如果在一个单调坡度上有平坡,例如[1,2,2,2,3,4],如图: +在版本一中,我们忽略了一种情况,即 如果在一个单调坡度上有平坡,例如[1,2,2,2,3,4],如图: ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230108171505.png) -图中,我们可以看出,版本一的代码在三个地方记录峰值,但其实结果因为是2,因为 单调中的平坡 不能算峰值(即摆动)。 +图中,我们可以看出,版本一的代码在三个地方记录峰值,但其实结果因为是 2,因为 单调中的平坡 不能算峰值(即摆动)。 -之所以版本一会出问题,是因为我们实时更新了 prediff。 +之所以版本一会出问题,是因为我们实时更新了 prediff。 -那么我们应该什么时候更新prediff呢? +那么我们应该什么时候更新 prediff 呢? -我们只需要在 这个坡度 摆动变化的时候,更新prediff就行,这样prediff在 单调区间有平坡的时候 就不会发生变化,造成我们的误判。 +我们只需要在 这个坡度 摆动变化的时候,更新 prediff 就行,这样 prediff 在 单调区间有平坡的时候 就不会发生变化,造成我们的误判。 所以本题的最终代码为: ```CPP -// 版本二 +// 版本二 class Solution { public: int wiggleMaxLength(vector& nums) { @@ -168,7 +173,7 @@ public: // 出现峰值 if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) { result++; - preDiff = curDiff; // 注意这里,只在摆动变化的时候更新prediff + preDiff = curDiff; // 注意这里,只在摆动变化的时候更新prediff } } return result; @@ -176,25 +181,25 @@ public: }; ``` -其实本题看起来好像简单,但需要考虑的情况还是很复杂的,而且很难一次性想到位。 +其实本题看起来好像简单,但需要考虑的情况还是很复杂的,而且很难一次性想到位。 -**本题异常情况的本质,就是要考虑平坡**, 平坡分两种,一个是 上下中间有平坡,一个是单调有平坡,如图: +**本题异常情况的本质,就是要考虑平坡**, 平坡分两种,一个是 上下中间有平坡,一个是单调有平坡,如图: ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230108174452.png) -## 思路2(动态规划) +## 思路 2(动态规划) 考虑用动态规划的思想来解决这个问题。 -很容易可以发现,对于我们当前考虑的这个数,要么是作为山峰(即nums[i] > nums[i-1]),要么是作为山谷(即nums[i] < nums[i - 1])。 +很容易可以发现,对于我们当前考虑的这个数,要么是作为山峰(即 nums[i] > nums[i-1]),要么是作为山谷(即 nums[i] < nums[i - 1])。 -* 设dp状态`dp[i][0]`,表示考虑前i个数,第i个数作为山峰的摆动子序列的最长长度 -* 设dp状态`dp[i][1]`,表示考虑前i个数,第i个数作为山谷的摆动子序列的最长长度 +- 设 dp 状态`dp[i][0]`,表示考虑前 i 个数,第 i 个数作为山峰的摆动子序列的最长长度 +- 设 dp 状态`dp[i][1]`,表示考虑前 i 个数,第 i 个数作为山谷的摆动子序列的最长长度 则转移方程为: -* `dp[i][0] = max(dp[i][0], dp[j][1] + 1)`,其中`0 < j < i`且`nums[j] < nums[i]`,表示将nums[i]接到前面某个山谷后面,作为山峰。 -* `dp[i][1] = max(dp[i][1], dp[j][0] + 1)`,其中`0 < j < i`且`nums[j] > nums[i]`,表示将nums[i]接到前面某个山峰后面,作为山谷。 +- `dp[i][0] = max(dp[i][0], dp[j][1] + 1)`,其中`0 < j < i`且`nums[j] < nums[i]`,表示将 nums[i]接到前面某个山谷后面,作为山峰。 +- `dp[i][1] = max(dp[i][1], dp[j][0] + 1)`,其中`0 < j < i`且`nums[j] > nums[i]`,表示将 nums[i]接到前面某个山峰后面,作为山谷。 初始状态: @@ -223,28 +228,25 @@ public: }; ``` -* 时间复杂度:O(n^2) -* 空间复杂度:O(n) +- 时间复杂度:O(n^2) +- 空间复杂度:O(n) **进阶** 可以用两棵线段树来维护区间的最大值 -* 每次更新`dp[i][0]`,则在`tree1`的`nums[i]`位置值更新为`dp[i][0]` -* 每次更新`dp[i][1]`,则在`tree2`的`nums[i]`位置值更新为`dp[i][1]` -* 则dp转移方程中就没有必要j从0遍历到i-1,可以直接在线段树中查询指定区间的值即可。 +- 每次更新`dp[i][0]`,则在`tree1`的`nums[i]`位置值更新为`dp[i][0]` +- 每次更新`dp[i][1]`,则在`tree2`的`nums[i]`位置值更新为`dp[i][1]` +- 则 dp 转移方程中就没有必要 j 从 0 遍历到 i-1,可以直接在线段树中查询指定区间的值即可。 时间复杂度:O(nlog n) 空间复杂度:O(n) - - - ## 其他语言版本 +### Java -### Java ```Java class Solution { public int wiggleMaxLength(int[] nums) { @@ -270,6 +272,7 @@ class Solution { } } ``` + ```java // DP class Solution { @@ -300,7 +303,7 @@ class Solution { } ``` -### Python +### Python **贪心** @@ -332,7 +335,7 @@ class Solution: # nums[i] 为波谷 if nums[j] > nums[i]: dp[i][1] = max(dp[i][1], dp[j][0] + 1) - # nums[i] 为波峰 + # nums[i] 为波峰 if nums[j] < nums[i]: dp[i][0] = max(dp[i][0], dp[j][1] + 1) return max(dp[-1][0], dp[-1][1]) @@ -357,9 +360,10 @@ class Solution: return max(up, down) ``` -### Go +### Go **贪心** + ```go func wiggleMaxLength(nums []int) int { n := len(nums) @@ -383,6 +387,7 @@ func wiggleMaxLength(nums []int) int { ``` **动态规划** + ```go func wiggleMaxLength(nums []int) int { n := len(nums) @@ -419,8 +424,10 @@ func max(a, b int) int { } ``` -### Javascript +### Javascript + **贪心** + ```Javascript var wiggleMaxLength = function(nums) { if(nums.length <= 1) return nums.length @@ -437,10 +444,12 @@ var wiggleMaxLength = function(nums) { return result }; ``` + **动态规划** + ```Javascript var wiggleMaxLength = function(nums) { - if (nums.length === 1) return 1; + if (nums.length === 1) return 1; // 考虑前i个数,当第i个值作为峰谷时的情况(则第i-1是峰顶) let down = 1; // 考虑前i个数,当第i个值作为峰顶时的情况(则第i-1是峰谷) @@ -458,7 +467,9 @@ var wiggleMaxLength = function(nums) { ``` ### Rust + **贪心** + ```Rust impl Solution { pub fn wiggle_max_length(nums: Vec) -> i32 { @@ -504,11 +515,12 @@ impl Solution { ``` ### C + **贪心** ```c int wiggleMaxLength(int* nums, int numsSize){ - if(numsSize <= 1) + if(numsSize <= 1) return numsSize; int length = 1; @@ -568,54 +580,49 @@ int wiggleMaxLength(int* nums, int numsSize){ } ``` - - ### TypeScript **贪心** ```typescript function wiggleMaxLength(nums: number[]): number { - let length: number = nums.length; - if (length <= 1) return length; - let preDiff: number = 0; - let curDiff: number = 0; - let count: number = 1; - for (let i = 1; i < length; i++) { - curDiff = nums[i] - nums[i - 1]; - if ( - (preDiff <= 0 && curDiff > 0) || - (preDiff >= 0 && curDiff < 0) - ) { - preDiff = curDiff; - count++; - } + let length: number = nums.length; + if (length <= 1) return length; + let preDiff: number = 0; + let curDiff: number = 0; + let count: number = 1; + for (let i = 1; i < length; i++) { + curDiff = nums[i] - nums[i - 1]; + if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) { + preDiff = curDiff; + count++; } - return count; -}; + } + return count; +} ``` **动态规划** ```typescript function wiggleMaxLength(nums: number[]): number { - const length: number = nums.length; - if (length <= 1) return length; - const dp: number[][] = new Array(length).fill(0).map(_ => []); - dp[0][0] = 1; // 第一个数作为波峰 - dp[0][1] = 1; // 第一个数作为波谷 - for (let i = 1; i < length; i++) { - dp[i][0] = 1; - dp[i][1] = 1; - for (let j = 0; j < i; j++) { - if (nums[j] < nums[i]) dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1); - } - for (let j = 0; j < i; j++) { - if (nums[j] > nums[i]) dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1); - } + const length: number = nums.length; + if (length <= 1) return length; + const dp: number[][] = new Array(length).fill(0).map((_) => []); + dp[0][0] = 1; // 第一个数作为波峰 + dp[0][1] = 1; // 第一个数作为波谷 + for (let i = 1; i < length; i++) { + dp[i][0] = 1; + dp[i][1] = 1; + for (let j = 0; j < i; j++) { + if (nums[j] < nums[i]) dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1); } - return Math.max(dp[length - 1][0], dp[length - 1][1]); -}; + for (let j = 0; j < i; j++) { + if (nums[j] > nums[i]) dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1); + } + } + return Math.max(dp[length - 1][0], dp[length - 1][1]); +} ``` ### Scala From ef8500d4cfa9f2669dec76157a01896d018b441e Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:14:43 +0800 Subject: [PATCH 032/126] =?UTF-8?q?docs:=20=E6=9C=80=E5=A4=A7=E5=AD=90?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=92=8C=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E8=AE=B2=E8=A7=A3=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0053.最大子序和.md | 116 ++++++++++++++++--------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/problems/0053.最大子序和.md b/problems/0053.最大子序和.md index 14017f98..1de68041 100644 --- a/problems/0053.最大子序和.md +++ b/problems/0053.最大子序和.md @@ -4,7 +4,6 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

- # 53. 最大子序和 [力扣题目链接](https://leetcode.cn/problems/maximum-subarray/) @@ -12,17 +11,21 @@ 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: -* 输入: [-2,1,-3,4,-1,2,1,-5,4] -* 输出: 6 -* 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 +- 输入: [-2,1,-3,4,-1,2,1,-5,4] +- 输出: 6 +- 解释:  连续子数组  [4,-1,2,1] 的和最大,为  6。 + +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和](https://www.bilibili.com/video/BV1aY4y1Z7ya),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 暴力解法 -暴力解法的思路,第一层for 就是设置起始位置,第二层for循环遍历数组寻找最大值 +暴力解法的思路,第一层 for 就是设置起始位置,第二层 for 循环遍历数组寻找最大值 -* 时间复杂度:O(n^2) -* 空间复杂度:O(1) +- 时间复杂度:O(n^2) +- 空间复杂度:O(1) ```CPP class Solution { @@ -42,13 +45,13 @@ public: }; ``` -以上暴力的解法C++勉强可以过,其他语言就不确定了。 +以上暴力的解法 C++勉强可以过,其他语言就不确定了。 ## 贪心解法 **贪心贪的是哪里呢?** -如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方! +如果 -2 1 在一起,计算起点的时候,一定是从 1 开始计算,因为负数只会拉低总和,这就是贪心贪的地方! 局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。 @@ -56,29 +59,27 @@ public: **局部最优的情况下,并记录最大的“连续和”,可以推出全局最优**。 - -从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。 +从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。 **这相当于是暴力解法中的不断调整最大子序和区间的起始位置**。 - **那有同学问了,区间终止位置不用调整么? 如何才能得到最大“连续和”呢?** -区间的终止位置,其实就是如果count取到最大值了,及时记录下来了。例如如下代码: +区间的终止位置,其实就是如果 count 取到最大值了,及时记录下来了。例如如下代码: ``` if (count > result) result = count; ``` -**这样相当于是用result记录最大子序和区间和(变相的算是调整了终止位置)**。 +**这样相当于是用 result 记录最大子序和区间和(变相的算是调整了终止位置)**。 如动画所示: ![53.最大子序和](https://code-thinking.cdn.bcebos.com/gifs/53.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C.gif) -红色的起始位置就是贪心每次取count为正数的时候,开始一个区间的统计。 +红色的起始位置就是贪心每次取 count 为正数的时候,开始一个区间的统计。 -那么不难写出如下C++代码(关键地方已经注释) +那么不难写出如下 C++代码(关键地方已经注释) ```CPP class Solution { @@ -98,38 +99,34 @@ public: }; ``` -* 时间复杂度:O(n) -* 空间复杂度:O(1) +- 时间复杂度:O(n) +- 空间复杂度:O(1) 当然题目没有说如果数组为空,应该返回什么,所以数组为空的话返回啥都可以了。 +## 常见误区 -## 常见误区 - -误区一: - -不少同学认为 如果输入用例都是-1,或者 都是负数,这个贪心算法跑出来的结果是0, 这是**又一次证明脑洞模拟不靠谱的经典案例**,建议大家把代码运行一下试一试,就知道了,也会理解 为什么 result 要初始化为最小负数了。 +误区一: +不少同学认为 如果输入用例都是-1,或者 都是负数,这个贪心算法跑出来的结果是 0, 这是**又一次证明脑洞模拟不靠谱的经典案例**,建议大家把代码运行一下试一试,就知道了,也会理解 为什么 result 要初始化为最小负数了。 误区二: -大家在使用贪心算法求解本题,经常陷入的误区,就是分不清,是遇到 负数就选择起始位置,还是连续和为负选择起始位置。 +大家在使用贪心算法求解本题,经常陷入的误区,就是分不清,是遇到 负数就选择起始位置,还是连续和为负选择起始位置。 -在动画演示用,大家可以发现, 4,遇到 -1 的时候,我们依然累加了,为什么呢? +在动画演示用,大家可以发现, 4,遇到 -1 的时候,我们依然累加了,为什么呢? -因为和为3,只要连续和还是正数就会 对后面的元素 起到增大总和的作用。 所以只要连续和为正数我们就保留。 - -这里也会有录友疑惑,那 4 + -1 之后 不就变小了吗? 会不会错过 4 成为最大连续和的可能性? - -其实并不会,因为还有一个变量result 一直在更新 最大的连续和,只要有更大的连续和出现,result就更新了,那么result已经把4更新了,后面 连续和变成3,也不会对最后结果有影响。 +因为和为 3,只要连续和还是正数就会 对后面的元素 起到增大总和的作用。 所以只要连续和为正数我们就保留。 +这里也会有录友疑惑,那 4 + -1 之后 不就变小了吗? 会不会错过 4 成为最大连续和的可能性? +其实并不会,因为还有一个变量 result 一直在更新 最大的连续和,只要有更大的连续和出现,result 就更新了,那么 result 已经把 4 更新了,后面 连续和变成 3,也不会对最后结果有影响。 ## 动态规划 -当然本题还可以用动态规划来做,当前[「代码随想录」](https://img-blog.csdnimg.cn/20201124161234338.png)主要讲解贪心系列,后续到动态规划系列的时候会详细讲解本题的dp方法。 +当然本题还可以用动态规划来做,当前[「代码随想录」](https://img-blog.csdnimg.cn/20201124161234338.png)主要讲解贪心系列,后续到动态规划系列的时候会详细讲解本题的 dp 方法。 -那么先给出我的dp代码如下,有时间的录友可以提前做一做: +那么先给出我的 dp 代码如下,有时间的录友可以提前做一做: ```CPP class Solution { @@ -148,8 +145,8 @@ public: }; ``` -* 时间复杂度:O(n) -* 空间复杂度:O(n) +- 时间复杂度:O(n) +- 空间复杂度:O(n) ## 总结 @@ -159,8 +156,8 @@ public: ## 其他语言版本 - ### Java + ```java class Solution { public int maxSubArray(int[] nums) { @@ -201,6 +198,7 @@ class Solution { ``` ### Python + ```python class Solution: def maxSubArray(self, nums: List[int]) -> int: @@ -233,6 +231,7 @@ func maxSubArray(nums []int) int { ``` ### Rust + ```rust pub fn max_sub_array(nums: Vec) -> i32 { let mut max_sum = i32::MIN; @@ -247,6 +246,7 @@ pub fn max_sub_array(nums: Vec) -> i32 { ``` ### Javascript: + ```Javascript var maxSubArray = function(nums) { let result = -Infinity @@ -264,14 +264,15 @@ var maxSubArray = function(nums) { }; ``` - ### C: + 贪心: + ```c int maxSubArray(int* nums, int numsSize){ int maxVal = INT_MIN; int subArrSum = 0; - + int i; for(i = 0; i < numsSize; ++i) { subArrSum += nums[i]; @@ -286,6 +287,7 @@ int maxSubArray(int* nums, int numsSize){ ``` 动态规划: + ```c /** * 解题思路:动态规划: @@ -324,15 +326,15 @@ int maxSubArray(int* nums, int numsSize){ ```typescript function maxSubArray(nums: number[]): number { - let curSum: number = 0; - let resMax: number = -Infinity; - for (let i = 0, length = nums.length; i < length; i++) { - curSum += nums[i]; - resMax = Math.max(curSum, resMax); - if (curSum < 0) curSum = 0; - } - return resMax; -}; + let curSum: number = 0; + let resMax: number = -Infinity; + for (let i = 0, length = nums.length; i < length; i++) { + curSum += nums[i]; + resMax = Math.max(curSum, resMax); + if (curSum < 0) curSum = 0; + } + return resMax; +} ``` **动态规划** @@ -340,17 +342,17 @@ function maxSubArray(nums: number[]): number { ```typescript // 动态规划 function maxSubArray(nums: number[]): number { - const length = nums.length; - if (length === 0) return 0; - const dp: number[] = []; - dp[0] = nums[0]; - let resMax: number = nums[0]; - for (let i = 1; i < length; i++) { - dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]); - resMax = Math.max(resMax, dp[i]); - } - return resMax; -}; + const length = nums.length; + if (length === 0) return 0; + const dp: number[] = []; + dp[0] = nums[0]; + let resMax: number = nums[0]; + for (let i = 1; i < length; i++) { + dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]); + resMax = Math.max(resMax, dp[i]); + } + return resMax; +} ``` ### Scala From ef5a6f8567a5924308fb4fe081665f8f5577c5fb Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:17:32 +0800 Subject: [PATCH 033/126] =?UTF-8?q?docs:=20=E8=82=A1=E7=A5=A8=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA=E4=BA=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0122.买卖股票的最佳时机II.md | 131 ++++++++++-------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md index 29242be3..533a14a4 100644 --- a/problems/0122.买卖股票的最佳时机II.md +++ b/problems/0122.买卖股票的最佳时机II.md @@ -4,43 +4,49 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

- -# 122.买卖股票的最佳时机II +# 122.买卖股票的最佳时机 II [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/) -给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 +给定一个数组,它的第  i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 - 示例 1: -* 输入: [7,1,5,3,6,4] -* 输出: 7 -* 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 + +- 输入: [7,1,5,3,6,4] +- 输出: 7 +- 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 示例 2: -* 输入: [1,2,3,4,5] -* 输出: 4 -* 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 -示例 3: -* 输入: [7,6,4,3,1] -* 输出: 0 -* 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 +- 输入: [1,2,3,4,5] +- 输出: 4 +- 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 + +示例  3: + +- 输入: [7,6,4,3,1] +- 输出: 0 +- 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 提示: -* 1 <= prices.length <= 3 * 10 ^ 4 -* 0 <= prices[i] <= 10 ^ 4 + +- 1 <= prices.length <= 3 \* 10 ^ 4 +- 0 <= prices[i] <= 10 ^ 4 + +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机 II](https://www.bilibili.com/video/BV1ev4y1C7na),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 本题首先要清楚两点: -* 只有一只股票! -* 当前只有买股票或者卖股票的操作 +- 只有一只股票! +- 当前只有买股票或者卖股票的操作 想获得利润至少要两天为一个交易单元。 @@ -52,17 +58,16 @@ 如何分解呢? -假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。 +假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。 相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。 -**此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑!** +**此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!** -那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。 +那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。 如图: - ![122.买卖股票的最佳时机II](https://code-thinking-1253855093.file.myqcloud.com/pics/2020112917480858-20230310134659477.png) 一些同学陷入:第一天怎么就没有利润呢,第一天到底算不算的困惑中。 @@ -77,7 +82,7 @@ 局部最优可以推出全局最优,找不出反例,试一试贪心! -对应C++代码如下: +对应 C++代码如下: ```CPP class Solution { @@ -92,12 +97,12 @@ public: }; ``` -* 时间复杂度:O(n) -* 空间复杂度:O(1) +- 时间复杂度:O(n) +- 空间复杂度:O(1) ### 动态规划 -动态规划将在下一个系列详细讲解,本题解先给出我的C++代码(带详细注释),感兴趣的同学可以自己先学习一下。 +动态规划将在下一个系列详细讲解,本题解先给出我的 C++代码(带详细注释),感兴趣的同学可以自己先学习一下。 ```CPP class Solution { @@ -119,8 +124,8 @@ public: }; ``` -* 时间复杂度:$O(n)$ -* 空间复杂度:$O(n)$ +- 时间复杂度:$O(n)$ +- 空间复杂度:$O(n)$ ## 总结 @@ -134,9 +139,10 @@ public: ## 其他语言版本 -### Java: +### Java: 贪心: + ```java // 贪心思路 class Solution { @@ -151,6 +157,7 @@ class Solution { ``` 动态规划: + ```java class Solution { // 动态规划 public int maxProfit(int[] prices) { @@ -172,8 +179,10 @@ class Solution { // 动态规划 } ``` -### Python: +### Python: + 贪心: + ```python class Solution: def maxProfit(self, prices: List[int]) -> int: @@ -184,6 +193,7 @@ class Solution: ``` 动态规划: + ```python class Solution: def maxProfit(self, prices: List[int]) -> int: @@ -200,6 +210,7 @@ class Solution: ### Go: 贪心算法 + ```go func maxProfit(prices []int) int { var sum int @@ -212,7 +223,9 @@ func maxProfit(prices []int) int { return sum } ``` + 动态规划 + ```go func maxProfit(prices []int) int { dp := make([][]int, len(prices)) @@ -226,7 +239,7 @@ func maxProfit(prices []int) int { dp[i][1] = max(dp[i-1][0] - prices[i], dp[i-1][1]) } return dp[len(prices)-1][0] - + } func max(a, b int) int { if a > b { @@ -239,6 +252,7 @@ func max(a, b int) int { ### Javascript: 贪心 + ```Javascript var maxProfit = function(prices) { let result = 0 @@ -249,27 +263,28 @@ var maxProfit = function(prices) { }; ``` -动态规划 +动态规划 + ```javascript const maxProfit = (prices) => { - let dp = Array.from(Array(prices.length), () => Array(2).fill(0)); - // dp[i][0] 表示第i天持有股票所得现金。 - // dp[i][1] 表示第i天不持有股票所得最多现金 - dp[0][0] = 0 - prices[0]; - dp[0][1] = 0; - for(let i = 1; i < prices.length; i++) { - // 如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来 - // 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0] - // 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i] - dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] - prices[i]); - - // 在来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来 - // 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1] - // 第i天卖出股票,所得现金就是按照今天股票佳价格卖出后所得现金即:prices[i] + dp[i - 1][0] - dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i]); - } + let dp = Array.from(Array(prices.length), () => Array(2).fill(0)); + // dp[i][0] 表示第i天持有股票所得现金。 + // dp[i][1] 表示第i天不持有股票所得最多现金 + dp[0][0] = 0 - prices[0]; + dp[0][1] = 0; + for (let i = 1; i < prices.length; i++) { + // 如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来 + // 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0] + // 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i] + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]); - return dp[prices.length -1][1]; + // 在来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来 + // 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1] + // 第i天卖出股票,所得现金就是按照今天股票佳价格卖出后所得现金即:prices[i] + dp[i - 1][0] + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]); + } + + return dp[prices.length - 1][1]; }; ``` @@ -277,17 +292,18 @@ const maxProfit = (prices) => { ```typescript function maxProfit(prices: number[]): number { - let resProfit: number = 0; - for (let i = 1, length = prices.length; i < length; i++) { - resProfit += Math.max(prices[i] - prices[i - 1], 0); - } - return resProfit; -}; + let resProfit: number = 0; + for (let i = 1, length = prices.length; i < length; i++) { + resProfit += Math.max(prices[i] - prices[i - 1], 0); + } + return resProfit; +} ``` ### Rust 贪心: + ```Rust impl Solution { fn max(a: i32, b: i32) -> i32 { @@ -304,6 +320,7 @@ impl Solution { ``` 动态规划: + ```Rust impl Solution { fn max(a: i32, b: i32) -> i32 { @@ -323,7 +340,9 @@ impl Solution { ``` ### C: + 贪心: + ```c int maxProfit(int* prices, int pricesSize){ int result = 0; @@ -339,6 +358,7 @@ int maxProfit(int* prices, int pricesSize){ ``` 动态规划: + ```c #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -363,6 +383,7 @@ int maxProfit(int* prices, int pricesSize){ ### Scala 贪心: + ```scala object Solution { def maxProfit(prices: Array[Int]): Int = { From 29646b86b90026072dfa903877e16123164d60fa Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:19:09 +0800 Subject: [PATCH 034/126] =?UTF-8?q?docs:=E8=B7=B3=E8=B7=83=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0055.跳跃游戏.md | 61 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/problems/0055.跳跃游戏.md b/problems/0055.跳跃游戏.md index a898263d..6c75b04c 100644 --- a/problems/0055.跳跃游戏.md +++ b/problems/0055.跳跃游戏.md @@ -4,7 +4,6 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

- # 55. 跳跃游戏 [力扣题目链接](https://leetcode.cn/problems/jump-game/) @@ -15,20 +14,25 @@ 判断你是否能够到达最后一个位置。 -示例 1: -* 输入: [2,3,1,1,4] -* 输出: true -* 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。 +示例  1: -示例 2: -* 输入: [3,2,1,0,4] -* 输出: false -* 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 +- 输入: [2,3,1,1,4] +- 输出: true +- 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。 +示例  2: + +- 输入: [3,2,1,0,4] +- 输出: false +- 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 + +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,怎么跳跃不重要,关键在覆盖范围 | LeetCode:55.跳跃游戏](https://www.bilibili.com/video/BV1VG4y1X7kB),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 -刚看到本题一开始可能想:当前位置元素如果是3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢? +刚看到本题一开始可能想:当前位置元素如果是 3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢? 其实跳几步无所谓,关键在于可跳的覆盖范围! @@ -46,14 +50,13 @@ 如图: - ![55.跳跃游戏](https://code-thinking-1253855093.file.myqcloud.com/pics/20201124154758229-20230310135019977.png) -i每次移动只能在cover的范围内移动,每移动一个元素,cover得到该元素数值(新的覆盖范围)的补充,让i继续移动下去。 +i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。 -而cover每次只取 max(该元素数值补充后的范围, cover本身范围)。 +而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。 -如果cover大于等于了终点下标,直接return true就可以了。 +如果 cover 大于等于了终点下标,直接 return true 就可以了。 C++代码如下: @@ -71,6 +74,7 @@ public: } }; ``` + ## 总结 这道题目关键点在于:不用拘泥于每次究竟跳几步,而是看覆盖范围,覆盖范围内一定是可以跳过来的,不用管是怎么跳的。 @@ -83,8 +87,8 @@ public: ## 其他语言版本 +### Java -### Java ```Java class Solution { public boolean canJump(int[] nums) { @@ -106,6 +110,7 @@ class Solution { ``` ### Python + ```python class Solution: def canJump(self, nums: List[int]) -> bool: @@ -156,9 +161,7 @@ func max(a, b int ) int { } ``` - - -### Javascript +### Javascript ```Javascript var canJump = function(nums) { @@ -196,6 +199,7 @@ impl Solution { ``` ### C + ```c #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -217,23 +221,23 @@ bool canJump(int* nums, int numsSize){ } ``` - ### TypeScript ```typescript function canJump(nums: number[]): boolean { - let farthestIndex: number = 0; - let cur: number = 0; - while (cur <= farthestIndex) { - farthestIndex = Math.max(farthestIndex, cur + nums[cur]); - if (farthestIndex >= nums.length - 1) return true; - cur++; - } - return false; -}; + let farthestIndex: number = 0; + let cur: number = 0; + while (cur <= farthestIndex) { + farthestIndex = Math.max(farthestIndex, cur + nums[cur]); + if (farthestIndex >= nums.length - 1) return true; + cur++; + } + return false; +} ``` ### Scala + ```scala object Solution { def canJump(nums: Array[Int]): Boolean = { @@ -250,7 +254,6 @@ object Solution { } ``` -

From 6f8d5eb7a04e178b99d23b4b4c443bbdfd84840c Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:21:12 +0800 Subject: [PATCH 035/126] =?UTF-8?q?docs:=E8=B7=B3=E8=B7=83=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E4=BA=8C=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 70 ++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 22151fdc..eb622cd3 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -4,10 +4,9 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

+> 相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不少,做好心里准备! -> 相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不少,做好心里准备! - -# 45.跳跃游戏II +# 45.跳跃游戏 II [力扣题目链接](https://leetcode.cn/problems/jump-game-ii/) @@ -18,13 +17,17 @@ 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 示例: -* 输入: [2,3,1,1,4] -* 输出: 2 -* 解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。 + +- 输入: [2,3,1,1,4] +- 输出: 2 +- 解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳  1  步,然后跳  3  步到达数组的最后一个位置。 说明: 假设你总是可以到达数组的最后一个位置。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏 II](https://www.bilibili.com/video/BV1Y24y1r7XZ),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 @@ -46,7 +49,6 @@ 如图: - ![45.跳跃游戏II](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232309103.png) **图中覆盖范围的意义在于,只要红色的区域,最多两步一定可以到!(不用管具体怎么跳,反正一定可以跳到)** @@ -57,8 +59,8 @@ 这里还是有个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时 -* 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。 -* 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。 +- 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。 +- 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。 C++代码如下:(详细注释) @@ -92,14 +94,14 @@ public: **针对于方法一的特殊情况,可以统一处理**,即:移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不考虑是不是终点的情况。 -想要达到这样的效果,只要让移动下标,最大只能移动到nums.size - 2的地方就可以了。 +想要达到这样的效果,只要让移动下标,最大只能移动到 nums.size - 2 的地方就可以了。 -因为当移动下标指向nums.size - 2时: +因为当移动下标指向 nums.size - 2 时: -* 如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即ans++),因为最后一步一定是可以到的终点。(题目假设总是可以到达数组的最后一个位置),如图: -![45.跳跃游戏II2](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232445286.png) +- 如果移动下标等于当前覆盖最大距离下标, 需要再走一步(即 ans++),因为最后一步一定是可以到的终点。(题目假设总是可以到达数组的最后一个位置),如图: + ![45.跳跃游戏II2](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232445286.png) -* 如果移动下标不等于当前覆盖最大距离下标,说明当前覆盖最远距离就可以直接达到终点了,不需要再走一步。如图: +- 如果移动下标不等于当前覆盖最大距离下标,说明当前覆盖最远距离就可以直接达到终点了,不需要再走一步。如图: ![45.跳跃游戏II1](https://code-thinking-1253855093.file.myqcloud.com/pics/20201201232338693.png) @@ -127,7 +129,7 @@ public: 可以看出版本二的代码相对于版本一简化了不少! -**其精髓在于控制移动下标i只移动到nums.size() - 2的位置**,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。 +**其精髓在于控制移动下标 i 只移动到 nums.size() - 2 的位置**,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。 ## 总结 @@ -137,11 +139,10 @@ public: 理解本题的关键在于:**以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点**,这个范围内最小步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。 - ## 其他语言版本 +### Java -### Java ```Java // 版本一 class Solution { @@ -207,7 +208,7 @@ class Solution: nextDistance = 0 for i in range(len(nums)): nextDistance = max(i + nums[i], nextDistance) - if i == curDistance: + if i == curDistance: if curDistance != len(nums) - 1: ans += 1 curDistance = nextDistance @@ -230,9 +231,10 @@ class Solution: step += 1 return step ``` + ```python # 动态规划做法 -class Solution: +class Solution: def jump(self, nums: List[int]) -> int: result = [10**4+1]*len(nums) result[0]=0 @@ -244,7 +246,6 @@ class Solution: ``` - ### Go ```go @@ -331,21 +332,21 @@ var jump = function(nums) { ```typescript function jump(nums: number[]): number { - const length: number = nums.length; - let curFarthestIndex: number = 0, - nextFarthestIndex: number = 0; - let curIndex: number = 0; - let stepNum: number = 0; - while (curIndex < length - 1) { - nextFarthestIndex = Math.max(nextFarthestIndex, curIndex + nums[curIndex]); - if (curIndex === curFarthestIndex) { - curFarthestIndex = nextFarthestIndex; - stepNum++; - } - curIndex++; + const length: number = nums.length; + let curFarthestIndex: number = 0, + nextFarthestIndex: number = 0; + let curIndex: number = 0; + let stepNum: number = 0; + while (curIndex < length - 1) { + nextFarthestIndex = Math.max(nextFarthestIndex, curIndex + nums[curIndex]); + if (curIndex === curFarthestIndex) { + curFarthestIndex = nextFarthestIndex; + stepNum++; } - return stepNum; -}; + curIndex++; + } + return stepNum; +} ``` ### Scala @@ -425,7 +426,6 @@ impl Solution { } ``` -

From a8d3d3cf75ff188b192993486059c9048f31d0e4 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:22:58 +0800 Subject: [PATCH 036/126] =?UTF-8?q?docs:k=E6=AC=A1=E5=8F=96=E5=8F=8D?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1005.K次取反后最大化的数组和.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index cdf42511..fb2a1cb7 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -34,6 +34,10 @@ * 1 <= K <= 10000 * -100 <= A[i] <= 100 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,这不就是常识?还能叫贪心?LeetCode:1005.K次取反后最大化的数组和](https://www.bilibili.com/video/BV138411G7LY),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 本题思路其实比较好想了,如何可以让数组和最大呢? From 8919bcc03a39ad6366d04a3315713300c00dff53 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:24:02 +0800 Subject: [PATCH 037/126] =?UTF-8?q?docs:=E5=8A=A0=E6=B2=B9=E7=AB=99?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0134.加油站.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index 77e199fd..f432bf0b 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -45,6 +45,10 @@ * 解释: 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油。开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油。开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油。你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。因此,无论怎样,你都不可能绕环路行驶一周。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站](https://www.bilibili.com/video/BV1jA411r7WX),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 暴力方法 From 74b4c506aa7a922f173ebe30daef96e17a97153c Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:26:03 +0800 Subject: [PATCH 038/126] =?UTF-8?q?docs:=E5=88=86=E5=8F=91=E7=B3=96?= =?UTF-8?q?=E6=9E=9C=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0135.分发糖果.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md index 181f24e9..ef79868a 100644 --- a/problems/0135.分发糖果.md +++ b/problems/0135.分发糖果.md @@ -28,6 +28,10 @@ * 输出: 4 * 解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这已满足上述两个条件。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,两者兼顾很容易顾此失彼!LeetCode:135.分发糖果](https://www.bilibili.com/video/BV1ev4y1r7wN),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 From 6f1111447cca7dafb2261836ff1735de819a4f9a Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:27:20 +0800 Subject: [PATCH 039/126] =?UTF-8?q?docs:=E6=9F=A0=E6=AA=AC=E6=B0=B4?= =?UTF-8?q?=E6=89=BE=E9=9B=B6=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0860.柠檬水找零.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index fc336eba..cd52adb0 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -50,6 +50,10 @@ * 0 <= bills.length <= 10000 * bills[i] 不是 5 就是 10 或是 20  +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,看上去复杂,其实逻辑都是固定的!LeetCode:860.柠檬水找零](https://www.bilibili.com/video/BV12x4y1j7DD),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 这是前几天的leetcode每日一题,感觉不错,给大家讲一下。 From 5cb8eb074673c8e2f977adf83787145a84cee079 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:28:54 +0800 Subject: [PATCH 040/126] =?UTF-8?q?docs:=E8=BA=AB=E9=AB=98=E9=87=8D?= =?UTF-8?q?=E5=BB=BA=E9=98=9F=E5=88=97=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0406.根据身高重建队列.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 48c498e1..3f82d0bc 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -37,6 +37,10 @@ 题目数据确保队列可以被重建 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,不要两边一起贪,会顾此失彼 | LeetCode:406.根据身高重建队列](https://www.bilibili.com/video/BV1EA411675Y),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。 From 3f904211ca06133b2493ac5594187e1f925112fb Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:30:37 +0800 Subject: [PATCH 041/126] =?UTF-8?q?docs:=20=E6=9C=80=E5=B0=8F=E7=9A=84?= =?UTF-8?q?=E7=AE=AD=E5=BC=95=E7=88=86=E6=B0=94=E7=90=83=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0452.用最少数量的箭引爆气球.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index 6b018f97..53eee25c 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -42,6 +42,10 @@ * points[i].length == 2 * -2^31 <= xstart < xend <= 2^31 - 1 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,判断重叠区间问题 | LeetCode:452.用最少数量的箭引爆气球](https://www.bilibili.com/video/BV1SA41167xe),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 如何使用最少的弓箭呢? From 403f524b3fb2f969074a10fe3516cefd563dec3b Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:31:35 +0800 Subject: [PATCH 042/126] =?UTF-8?q?docs:=20=E6=97=A0=E9=87=8D=E5=8F=A0?= =?UTF-8?q?=E5=8C=BA=E9=97=B4=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0435.无重叠区间.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index e5675e04..02db2034 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -30,6 +30,10 @@ * 输出: 0 * 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,依然是判断重叠区间 | LeetCode:435.无重叠区间](https://www.bilibili.com/video/BV1A14y1c7E1),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 **相信很多同学看到这道题目都冥冥之中感觉要排序,但是究竟是按照右边界排序,还是按照左边界排序呢?** From b0692bfa0d0a368e0d3acf2f6f6541a8534b2d65 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:32:37 +0800 Subject: [PATCH 043/126] =?UTF-8?q?docs:=20=E5=88=92=E5=88=86=E5=AD=97?= =?UTF-8?q?=E6=AF=8D=E5=8C=BA=E9=97=B4=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index 077cb54a..ad680ef9 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -24,6 +24,10 @@ * S的长度在[1, 500]之间。 * S只包含小写字母 'a' 到 'z' 。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间](https://www.bilibili.com/video/BV18G4y1K7d5),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 一想到分割字符串就想到了回溯,但本题其实不用回溯去暴力搜索。 From f3b8bfaf77975d7b396d464c606a25c120e3ede9 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:33:41 +0800 Subject: [PATCH 044/126] =?UTF-8?q?docs:=20=E5=90=88=E5=B9=B6=E5=8C=BA?= =?UTF-8?q?=E9=97=B4=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0056.合并区间.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index d467ab1a..17d2cc0a 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -22,6 +22,9 @@ * 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。 * 注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,合并区间有细节!LeetCode:56.合并区间](https://www.bilibili.com/video/BV1wx4y157nD),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 From 1d2d187c3a93b390742b533302bda036c5df27c7 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:35:28 +0800 Subject: [PATCH 045/126] =?UTF-8?q?docs:=20=E5=8D=95=E8=B0=83=E9=80=92?= =?UTF-8?q?=E5=A2=9E=E7=9A=84=E6=95=B0=E5=AD=97=E6=B7=BB=E5=8A=A0=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0738.单调递增的数字.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index fda378aa..f92652cd 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -26,6 +26,10 @@ 说明: N 是在 [0, 10^9] 范围内的一个整数。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,思路不难想,但代码不好写!LeetCode:738.单调自增的数字](https://www.bilibili.com/video/BV1Kv4y1x7tP),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 暴力解法 From 7ad80ab57f282ac94eef6aa42cecb98774601b46 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:37:27 +0800 Subject: [PATCH 046/126] =?UTF-8?q?docs:=20=E7=9B=91=E6=8E=A7=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0968.监控二叉树.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0968.监控二叉树.md b/problems/0968.监控二叉树.md index 14563a51..267e7f6e 100644 --- a/problems/0968.监控二叉树.md +++ b/problems/0968.监控二叉树.md @@ -38,6 +38,10 @@ * 给定树的节点数的范围是 [1, 1000]。 * 每个节点的值都是 0。 +# 视频讲解 + +**《代码随想录》算法视频公开课:[贪心算法,二叉树与贪心的结合,有点难...... LeetCode:968.监督二叉树](https://www.bilibili.com/video/BV1SA411U75i),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 From 33f6bc9a36aeca424dd7a5c1cb5ec5f186679ee9 Mon Sep 17 00:00:00 2001 From: liangzhensheng <1250564179@qq.com> Date: Fri, 17 Mar 2023 11:58:35 +0800 Subject: [PATCH 047/126] =?UTF-8?q?docs:=2001=E8=83=8C=E5=8C=85=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=AD=97=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index ff0b6aba..c45fc3d3 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -87,7 +87,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目, 那么可以有两个方向推出来dp[i][j], -* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。) +* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。) * **放物品i**:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); From 29e1a07cc3a51cb61c5aec933d5d914eb105741d Mon Sep 17 00:00:00 2001 From: sharky <1821984081@qq.com> Date: Fri, 17 Mar 2023 12:22:40 +0800 Subject: [PATCH 048/126] =?UTF-8?q?=E5=9B=9E=E6=BA=AF=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E5=8E=BB=E9=87=8D=E9=97=AE=E9=A2=98=E7=9A=84=E5=8F=A6=E4=B8=80?= =?UTF-8?q?=E7=A7=8D=E5=86=99=E6=B3=95=EF=BC=8C40.=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=80=BB=E5=92=8CII=E7=9A=84java=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...溯算法去重问题的另一种写法.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/problems/回溯算法去重问题的另一种写法.md b/problems/回溯算法去重问题的另一种写法.md index b3bd74da..cbbd831f 100644 --- a/problems/回溯算法去重问题的另一种写法.md +++ b/problems/回溯算法去重问题的另一种写法.md @@ -317,7 +317,38 @@ class Solution { } } ``` +**40.组合总和II** +```java +class Solution { + List> result = new ArrayList<>(); + LinkedList path = new LinkedList<>(); + public List> combinationSum2(int[] candidates, int target) { + Arrays.sort( candidates ); + if( candidates[0] > target ) return result; + backtracking(candidates,target,0,0); + return result; + } + public void backtracking(int[] candidates,int target,int sum,int startIndex){ + if( sum > target )return; + if( sum == target ){ + result.add( new ArrayList<>(path) ); + } + HashSet hashSet = new HashSet<>(); + for( int i = startIndex; i < candidates.length; i++){ + if( hashSet.contains(candidates[i]) ){ + continue; + } + hashSet.add(candidates[i]); + path.add(candidates[i]); + sum += candidates[i]; + backtracking(candidates,target,sum,i+1); + path.removeLast(); + sum -= candidates[i]; + } + } +} +``` Python: **90.子集II** From 39b1b10a8aa80b3a8fb0bc6363a7e761de4211db Mon Sep 17 00:00:00 2001 From: zsq <1377821797@qq.com> Date: Sat, 18 Mar 2023 22:16:17 +0800 Subject: [PATCH 049/126] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改README语法错误 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9b2f7ef..43f4df15 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ **这里每一篇题解,都是精品,值得仔细琢磨**。 -我在题目讲解中统一使用C++,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,正是这些[热心小伙们](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)的贡献的代码,当然我也会严格把控代码质量。 +我在题目讲解中统一使用C++,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,正是这些[热心小伙们](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)贡献的代码,当然我也会严格把控代码质量。 **所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们受益**。 From 8a7432ef2174ce8864f3e79816df2399815cd28d Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 18 Mar 2023 23:49:44 +0800 Subject: [PATCH 050/126] =?UTF-8?q?update=200349.=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86:=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0349.两个数组的交集.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 905bf4b2..0da0e30c 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -72,6 +72,9 @@ public: }; ``` +* 时间复杂度: O(mn) +* 空间复杂度: O(n) + ## 拓展 那有同学可能问了,遇到哈希问题我直接都用set不就得了,用什么数组啊。 @@ -110,6 +113,8 @@ public: }; ``` +* 时间复杂度: O(m + n) +* 空间复杂度: O(n) ## 其他语言版本 From 46a34392d5308b9606436d6722bd43053da4da73 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 00:02:30 +0800 Subject: [PATCH 051/126] =?UTF-8?q?update=200202.=E5=BF=AB=E4=B9=90?= =?UTF-8?q?=E6=95=B0=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6?= =?UTF-8?q?=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0202.快乐数.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index 2687574f..5ac29e86 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -75,6 +75,8 @@ public: }; ``` +* 时间复杂度: O(logn) +* 空间复杂度: O(logn) From 3b79659bc0c3303ccf48219ff9398184b622b88c Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 00:04:13 +0800 Subject: [PATCH 052/126] =?UTF-8?q?update=200001.=E4=B8=A4=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0001.两数之和.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index a0acdcbe..b3abb991 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -109,6 +109,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + ## 总结 本题其实有四个重点: From 79dfddde054abed5c766aa70ed56f54ee3b1c3ef Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Sat, 18 Mar 2023 15:43:20 -0400 Subject: [PATCH 053/126] =?UTF-8?q?Update=200112.=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=80=BB=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加112-python-简洁版解法 --- problems/0112.路径总和.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index e412d38e..bb46f04a 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -475,6 +475,12 @@ class solution: return false # 别忘记处理空treenode else: return isornot(root, targetsum - root.val) + +class Solution: # 简洁版 + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + if not root: return False + if root.left==root.right==None and root.val == targetSum: return True + return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val) ``` **迭代 - 层序遍历** From 87dbf5efc5e12ea3a305be097c2967ac3792e403 Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Sat, 18 Mar 2023 16:34:16 -0400 Subject: [PATCH 054/126] =?UTF-8?q?Update=200112.=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=80=BB=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加:0113 - python - 迭代法 - 前序遍历解法 --- problems/0112.路径总和.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index e412d38e..29e5a547 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -560,6 +560,26 @@ class Solution: return result ``` +**迭代法,前序遍历** + +```python +class Solution: + def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: + if not root: return [] + stack, path_stack,result = [[root,root.val]],[[root.val]],[] + while stack: + cur,cursum = stack.pop() + path = path_stack.pop() + if cur.left==cur.right==None: + if cursum==targetSum: result.append(path) + if cur.right: + stack.append([cur.right,cursum+cur.right.val]) + path_stack.append(path+[cur.right.val]) + if cur.left: + stack.append([cur.left,cursum+cur.left.val]) + path_stack.append(path+[cur.left.val]) + return result +``` ## go ### 112. 路径总和 From 08a984d61c5b855b5052d8617dc23cf170d61c01 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 11:13:34 +0800 Subject: [PATCH 055/126] =?UTF-8?q?update=200454.=E5=9B=9B=E6=95=B0?= =?UTF-8?q?=E7=9B=B8=E5=8A=A0II=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0454.四数相加II.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index 07c3f711..c2a5710f 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -83,6 +83,9 @@ public: ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(n^2),最坏情况下A和B的值各不相同,相加产生的数字个数为 n^2 + From c91ee8fdc2b7ff02953a758b0b9c7da4c031d7d0 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 11:16:15 +0800 Subject: [PATCH 056/126] =?UTF-8?q?update=200383.=E8=B5=8E=E9=87=91?= =?UTF-8?q?=E4=BF=A1=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6?= =?UTF-8?q?=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0383.赎金信.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md index 4e6ba033..d9a184b6 100644 --- a/problems/0383.赎金信.md +++ b/problems/0383.赎金信.md @@ -39,8 +39,6 @@ canConstruct("aa", "aab") -> true 那么第一个思路其实就是暴力枚举了,两层for循环,不断去寻找,代码如下: ```CPP -// 时间复杂度: O(n^2) -// 空间复杂度:O(1) class Solution { public: bool canConstruct(string ransomNote, string magazine) { @@ -62,6 +60,9 @@ public: }; ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(1) + 这里时间复杂度是比较高的,而且里面还有一个字符串删除也就是erase的操作,也是费时的,当然这段代码也可以过这道题。 @@ -78,8 +79,6 @@ public: 代码如下: ```CPP -// 时间复杂度: O(n) -// 空间复杂度:O(1) class Solution { public: bool canConstruct(string ransomNote, string magazine) { @@ -105,6 +104,10 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + + ## 其他语言版本 From 015935e4fa757f2fee1551e26336aa0fd520d844 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 11:24:04 +0800 Subject: [PATCH 057/126] =?UTF-8?q?update=200015.=E4=B8=89=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 6675e408..26c9eaa2 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -83,6 +83,10 @@ public: }; ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(n),额外的 set 开销 + + ## 双指针 **其实这道题目使用哈希法并不十分合适**,因为在去重的操作中有很多细节需要注意,在面试中很难直接写出没有bug的代码。 @@ -158,6 +162,10 @@ public: }; ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(1) + + ## 去重逻辑的思考 ### a的去重 From cd537cb91aa0c2b879a9b3b8cf0d2f5ab0552495 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sun, 19 Mar 2023 11:26:02 +0800 Subject: [PATCH 058/126] =?UTF-8?q?update=200018.=E5=9B=9B=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0018.四数之和.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 8e87fcbd..5f4c2ec9 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -121,6 +121,10 @@ public: ``` +* 时间复杂度: O(n^3) +* 空间复杂度: O(1) + + ## 补充 二级剪枝的部分: From 06ebd5f204f8a7012c1e4518ce778fa06750d7e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=88=E5=93=88=E5=93=88?= <76643786+Projecthappy@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:08:57 +0800 Subject: [PATCH 059/126] =?UTF-8?q?Update=200454.=E5=9B=9B=E6=95=B0?= =?UTF-8?q?=E7=9B=B8=E5=8A=A0II.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先是先判断map中是否有这个key,后面更新时再get(key),经过测试,直接使用getOrDefault()方法效率会更高一些,没有当前key时返回0,值为0就是没有当前key --- problems/0454.四数相加II.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index c2a5710f..411b60e8 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -97,26 +97,25 @@ Java: ```Java class Solution { public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { - Map map = new HashMap<>(); - int temp; int res = 0; + Map map = new HashMap(); //统计两个数组中的元素之和,同时统计出现的次数,放入map for (int i : nums1) { for (int j : nums2) { - temp = i + j; - if (map.containsKey(temp)) { - map.put(temp, map.get(temp) + 1); + int tmp = map.getOrDefault(i + j, 0); + if (tmp == 0) { + map.put(i + j, 1); } else { - map.put(temp, 1); + map.replace(i + j, tmp + 1); } } } //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数 for (int i : nums3) { for (int j : nums4) { - temp = i + j; - if (map.containsKey(0 - temp)) { - res += map.get(0 - temp); + int tmp = map.getOrDefault(0 - i - j, 0); + if (tmp != 0) { + res += tmp; } } } From 37d12a168cfa59e0ae44203f5aa8234d588f23fd Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Wed, 22 Mar 2023 18:22:15 -0400 Subject: [PATCH 060/126] =?UTF-8?q?Update=200530.=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E5=B0=8F=E7=BB=9D?= =?UTF-8?q?=E5=AF=B9=E5=B7=AE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加python - 双指针法,不用数组 (同Carl写法) - 更快 --- .../0530.二叉搜索树的最小绝对差.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/problems/0530.二叉搜索树的最小绝对差.md b/problems/0530.二叉搜索树的最小绝对差.md index 203add39..fa1430de 100644 --- a/problems/0530.二叉搜索树的最小绝对差.md +++ b/problems/0530.二叉搜索树的最小绝对差.md @@ -221,8 +221,27 @@ class Solution: for i in range(len(res)-1): // 统计有序数组的最小差值 r = min(abs(res[i]-res[i+1]),r) return r + + +class Solution: # 双指针法,不用数组 (同Carl写法) - 更快 + def getMinimumDifference(self, root: Optional[TreeNode]) -> int: + global pre,minval + pre = None + minval = 10**5 + self.traversal(root) + return minval + + def traversal(self,root): + global pre,minval + if not root: return None + self.traversal(root.left) + if pre and root.val-pre.val Date: Thu, 23 Mar 2023 10:57:32 +0800 Subject: [PATCH 061/126] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=860056.?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=8C=BA=E9=97=B4=E7=9A=84=E8=A7=A3=E6=B3=95?= =?UTF-8?q?=E4=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0056.合并区间.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index d467ab1a..0daf5f9b 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -174,6 +174,34 @@ func max(a, b int) int { return b } ``` +```go +// 版本2 +func merge(intervals [][]int) [][]int { + if len(intervals) == 1 { + return intervals + } + sort.Slice(intervals, func(i, j int) bool { + return intervals[i][0] < intervals[j][0] + }) + res := make([][]int, 0) + res = append(res, intervals[0]) + for i := 1; i < len(intervals); i++ { + if intervals[i][0] <= res[len(res)-1][1]{ + res[len(res)-1][1] = max56(res[len(res)-1][1],intervals[i][1]) + } else { + res = append(res, intervals[i]) + } + } + return res +} +func max56(a, b int) int { + if a > b { + return a + } + return b +} +``` + ### Javascript ```javascript From 4b65ece9ed30a88962782f1742d2d07d53783010 Mon Sep 17 00:00:00 2001 From: "Mr.D" Date: Sun, 26 Mar 2023 16:52:18 +0800 Subject: [PATCH 062/126] Add another Rust solution --- problems/0001.两数之和.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index b3abb991..eea3ba7a 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -216,6 +216,26 @@ impl Solution { } } ``` +Rust + +``` +use std::collections::HashMap; + +impl Solution { + pub fn two_sum(nums: Vec, target: i32) -> Vec { + let mut hm: HashMap = HashMap::new(); + for i in 0..nums.len() { + let j = target - nums[i]; + if hm.contains_key(&j) { + return vec![*hm.get(&j).unwrap(), i as i32] + } else { + hm.insert(nums[i], i as i32); + } + } + vec![-1, -1] + } +} +``` Javascript From c73c1a2b107780ce0aeb78c578112d065b887aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=A6=E8=B6=85=E7=A6=B9?= <1677425105@qq.com> Date: Sun, 26 Mar 2023 18:36:13 +0800 Subject: [PATCH 063/126] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E7=90=86?= =?UTF-8?q?=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index ff0b6aba..c45fc3d3 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -87,7 +87,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目, 那么可以有两个方向推出来dp[i][j], -* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。) +* **不放物品i**:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。) * **放物品i**:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); From 62a9b6c3722a44f8bf71ea360d6331a2f9918294 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 14:07:22 +0800 Subject: [PATCH 064/126] =?UTF-8?q?update=200344.=E5=8F=8D=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0344.反转字符串.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index 6ffbac26..775cfc58 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -130,6 +130,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + From 22ab6281e44ca025aaca2e5a94ba3e07f2021c1a Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 14:17:07 +0800 Subject: [PATCH 065/126] =?UTF-8?q?update=200541.=E5=8F=8D=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2II=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0541.反转字符串II.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index 516f78da..179395b3 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -65,6 +65,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + @@ -96,6 +99,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1)或O(n), 取决于使用的语言中字符串是否可以修改. + 另一种思路的解法 @@ -116,6 +122,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + ## 其他语言版本 From fe386a051dc73b3fd40bc79b70119df2e068ed9b Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 14:29:13 +0800 Subject: [PATCH 066/126] =?UTF-8?q?update=200151.=E7=BF=BB=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95=E8=AF=8D?= =?UTF-8?q?=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index eb78cc9d..1b006665 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -114,6 +114,7 @@ void removeExtraSpaces(string& s) { } ``` + 有的同学可能发现用erase来移除空格,在leetcode上性能也还行。主要是以下几点;: 1. leetcode上的测试集里,字符串的长度不够长,如果足够长,性能差距会非常明显。 @@ -197,6 +198,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) 或 O(n),取决于语言中字符串是否可变 + ## 其他语言版本 From cc1a327fb1d9f9e3ead9ba8f122b20ff4d112baf Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 14:36:32 +0800 Subject: [PATCH 067/126] =?UTF-8?q?update=20=E5=89=91=E6=8C=87Offer58-II.?= =?UTF-8?q?=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=9A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/剑指Offer58-II.左旋转字符串.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 49480abf..f368514f 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -66,6 +66,9 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度:O(1) + 是不是发现这代码也太简单了,哈哈。 # 总结 From 167cb84ee3b4ae514d898e33090d2453a516f02e Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 15:12:08 +0800 Subject: [PATCH 068/126] =?UTF-8?q?update=200028.=E5=AE=9E=E7=8E=B0strStr?= =?UTF-8?q?=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0028.实现strStr.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index 2757130c..263c1689 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -444,6 +444,8 @@ public: }; ``` +* 时间复杂度: O(n + m) +* 空间复杂度: O(m), 只需要保存字符串needle的前缀表 # 前缀表(不减一)C++实现 @@ -540,6 +542,9 @@ public: } }; ``` +* 时间复杂度: O(n + m) +* 空间复杂度: O(m) + # 总结 From dbcd875d3bcc0ccbf6b331bbfd07e799e272688b Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Mon, 27 Mar 2023 16:22:07 +0800 Subject: [PATCH 069/126] =?UTF-8?q?update=200459.=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E5=AD=90=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=9A=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0459.重复的子字符串.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index 5d870219..98c02a25 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -73,6 +73,8 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) 不过这种解法还有一个问题,就是 我们最终还是要判断 一个字符串(s + s)是否出现过 s 的过程,大家可能直接用contains,find 之类的库函数。 却忽略了实现这些函数的时间复杂度(暴力解法是m * n,一般库函数实现为 O(m + n))。 @@ -185,6 +187,8 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) 前缀表(不减一)的C++代码实现: @@ -219,6 +223,8 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) ## 其他语言版本 From 334f4a27de2ecc00134c6cf287f658758f856e6f Mon Sep 17 00:00:00 2001 From: hoxiansen <1365171821@qq.com> Date: Tue, 28 Mar 2023 09:40:19 +0000 Subject: [PATCH 070/126] =?UTF-8?q?Update=200518.=E9=9B=B6=E9=92=B1?= =?UTF-8?q?=E5=85=91=E6=8D=A2II.md=20=E8=A1=A5=E5=85=85=E4=BA=8C=E7=BB=B4d?= =?UTF-8?q?p=E6=95=B0=E7=BB=84=E7=9A=84Java=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0518.零钱兑换II.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md index 3fd03e16..eb5a844c 100644 --- a/problems/0518.零钱兑换II.md +++ b/problems/0518.零钱兑换II.md @@ -215,6 +215,27 @@ class Solution { } } ``` +```Java +// 二维dp数组版本,方便理解 +class Solution { + public int change(int amount, int[] coins) { + int[][] dp = new int[coins.length][amount + 1]; + // 只有一种硬币的情况 + for (int i = 0; i <= amount; i += coins[0]) { + dp[0][i] = 1; + } + for (int i = 1; i < coins.length; i++) { + for (int j = 0; j <= amount; j++) { + // 第i种硬币使用0~k次,求和 + for (int k = 0; k * coins[i] <= j; k++) { + dp[i][j] += dp[i - 1][j - k * coins[i]]; + } + } + } + return dp[coins.length - 1][amount]; + } +} +``` Python: From b18aba58bcfa66b31fb9d40ffb6805f75f5bd3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E6=97=A0=E7=BC=BA?= Date: Tue, 28 Mar 2023 22:22:14 +0800 Subject: [PATCH 071/126] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=94=99=E5=88=AB?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将爬楼梯文件中的中字更正为了种 --- problems/0070.爬楼梯.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md index d8246223..a06ee91e 100644 --- a/problems/0070.爬楼梯.md +++ b/problems/0070.爬楼梯.md @@ -72,7 +72,7 @@ dp[i]: 爬到第i层楼梯,有dp[i]种方法 3. dp数组如何初始化 -再回顾一下dp[i]的定义:爬到第i层楼梯,有dp[i]中方法。 +再回顾一下dp[i]的定义:爬到第i层楼梯,有dp[i]种方法。 那么i为0,dp[i]应该是多少呢,这个可以有很多解释,但基本都是直接奔着答案去解释的。 From f6a22863841064c9f5c61ad606fa10f293494de9 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 11:52:19 +0800 Subject: [PATCH 072/126] =?UTF-8?q?Update=20=E6=A0=B9=E6=8D=AE=E8=BA=AB?= =?UTF-8?q?=E9=AB=98=E9=87=8D=E5=BB=BA=E9=98=9F=E5=88=97=EF=BC=88vector?= =?UTF-8?q?=E5=8E=9F=E7=90=86=E8=AE=B2=E8=A7=A3=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...高重建队列(vector原理讲解).md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/problems/根据身高重建队列(vector原理讲解).md b/problems/根据身高重建队列(vector原理讲解).md index 94d94e38..4f8cab82 100644 --- a/problems/根据身高重建队列(vector原理讲解).md +++ b/problems/根据身高重建队列(vector原理讲解).md @@ -177,6 +177,35 @@ Java: Python: +Rust: + +```rust +// 版本二,使用list(链表) +use std::collections::LinkedList; +impl Solution{ + pub fn reconstruct_queue(mut people: Vec>) -> Vec> { + let mut queue = LinkedList::new(); + people.sort_by(|a, b| { + if a[0] == b[0] { + return a[1].cmp(&b[1]); + } + b[0].cmp(&a[0]) + }); + queue.push_back(people[0].clone()); + for v in people.iter().skip(1) { + if queue.len() > v[1] as usize { + let mut back_link = queue.split_off(v[1] as usize); + queue.push_back(v.clone()); + queue.append(&mut back_link); + } else { + queue.push_back(v.clone()); + } + } + queue.into_iter().collect() + } +} +``` + Go: From 59c86a7023989e3cb3195615f30a0a99e39fa556 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 18:15:26 +0800 Subject: [PATCH 073/126] =?UTF-8?q?Update=200844.=E6=AF=94=E8=BE=83?= =?UTF-8?q?=E5=90=AB=E9=80=80=E6=A0=BC=E7=9A=84=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0844.比较含退格的字符串.md | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/problems/0844.比较含退格的字符串.md b/problems/0844.比较含退格的字符串.md index 6534f18c..40d5caa1 100644 --- a/problems/0844.比较含退格的字符串.md +++ b/problems/0844.比较含退格的字符串.md @@ -535,6 +535,35 @@ function getIndexAfterDel(s: string, startIndex: number): number { } ``` +### Rust + +> 双指针 + +```rust +impl Solution { + pub fn backspace_compare(s: String, t: String) -> bool { + let (s, t) = ( + s.chars().collect::>(), + t.chars().collect::>(), + ); + Self::get_string(s) == Self::get_string(t) + } + + pub fn get_string(mut chars: Vec) -> Vec { + let mut slow = 0; + for i in 0..chars.len() { + if chars[i] == '#' { + slow = (slow as u32).saturating_sub(1) as usize; + } else { + chars[slow] = chars[i]; + slow += 1; + } + } + chars.truncate(slow); + chars + } +} +``` From e4951bc9dba7ebaa5314d41a52b0a5d97b8a6cea Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 18:34:11 +0800 Subject: [PATCH 074/126] =?UTF-8?q?Update=200844.=E6=AF=94=E8=BE=83?= =?UTF-8?q?=E5=90=AB=E9=80=80=E6=A0=BC=E7=9A=84=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0844.比较含退格的字符串.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0844.比较含退格的字符串.md b/problems/0844.比较含退格的字符串.md index 40d5caa1..ac56f6f9 100644 --- a/problems/0844.比较含退格的字符串.md +++ b/problems/0844.比较含退格的字符串.md @@ -565,7 +565,27 @@ impl Solution { } ``` +> 双栈法 +```rust +impl Solution { + pub fn backspace_compare(s: String, t: String) -> bool { + Self::get_string(s) == Self::get_string(t) + } + + pub fn get_string(string: String) -> String { + let mut s = String::new(); + for c in string.chars() { + if c != '#' { + s.push(c); + } else if !s.is_empty() { + s.pop(); + } + } + s + } +} +```

From 7e02650599bd98ef92f017f2838c09c17235a502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E6=97=A0=E7=BC=BA?= Date: Wed, 29 Mar 2023 20:21:27 +0800 Subject: [PATCH 075/126] =?UTF-8?q?update=20=E4=BD=BF=E7=94=A8=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E8=8A=B1=E8=B4=B9=E7=88=AC=E6=A5=BC=E6=A2=AF.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化文档中的语言描述 --- problems/0746.使用最小花费爬楼梯.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index d6b3a177..d7258d45 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -92,7 +92,7 @@ dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。 这里就要说明本题力扣为什么改题意,而且修改题意之后 就清晰很多的原因了。 -新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 从 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。 +新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。 所以初始化 dp[0] = 0,dp[1] = 0; From d2811139ae718d265b37653ae9ebfd4f07701c9d Mon Sep 17 00:00:00 2001 From: Jeremy Feng <44312563+jeremy-feng@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:35:33 +0800 Subject: [PATCH 076/126] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E8=83=8C=E5=8C=85.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- problems/背包问题理论基础完全背包.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包问题理论基础完全背包.md b/problems/背包问题理论基础完全背包.md index d0b2ce0b..f80d4671 100644 --- a/problems/背包问题理论基础完全背包.md +++ b/problems/背包问题理论基础完全背包.md @@ -41,7 +41,7 @@ * [动态规划:关于01背包问题,你该了解这些!](https://programmercarl.com/背包理论基础01背包-1.html) * [动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html) -首先在回顾一下01背包的核心代码 +首先再回顾一下01背包的核心代码 ```cpp for(int i = 0; i < weight.size(); i++) { // 遍历物品 for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量 From 96502b5f09b432ebb87f126fb56db83a5504abb4 Mon Sep 17 00:00:00 2001 From: Jeremy Feng <44312563+jeremy-feng@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:39:08 +0800 Subject: [PATCH 077/126] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E8=83=8C=E5=8C=85.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- problems/背包问题理论基础完全背包.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包问题理论基础完全背包.md b/problems/背包问题理论基础完全背包.md index f80d4671..e927aa20 100644 --- a/problems/背包问题理论基础完全背包.md +++ b/problems/背包问题理论基础完全背包.md @@ -173,7 +173,7 @@ int main() { 别急,下一篇就是了!哈哈 -最后,**又可以出一道面试题了,就是纯完全背包,要求先用二维dp数组实现,然后再用一维dp数组实现,最后在问,两个for循环的先后是否可以颠倒?为什么?** +最后,**又可以出一道面试题了,就是纯完全背包,要求先用二维dp数组实现,然后再用一维dp数组实现,最后再问,两个for循环的先后是否可以颠倒?为什么?** 这个简单的完全背包问题,估计就可以难住不少候选人了。 From f7988e06dc26ffb93d93f41c8454b4d4504f5828 Mon Sep 17 00:00:00 2001 From: ayao98 <91120769+ayao98@users.noreply.github.com> Date: Fri, 31 Mar 2023 15:50:58 +0800 Subject: [PATCH 078/126] =?UTF-8?q?Update=200104.=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c++语言部分,函数名和节点命名大小写有错误 --- problems/0104.二叉树的最大深度.md | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md index b95e39c8..36578fd3 100644 --- a/problems/0104.二叉树的最大深度.md +++ b/problems/0104.二叉树的最大深度.md @@ -50,7 +50,7 @@ 代码如下: ```CPP -int getdepth(treenode* node) +int getdepth(TreeNode* node) ``` 2. 确定终止条件:如果为空节点的话,就返回0,表示高度为0。 @@ -76,14 +76,14 @@ return depth; ```CPP class solution { public: - int getdepth(treenode* node) { + int getdepth(TreeNode* node) { if (node == NULL) return 0; int leftdepth = getdepth(node->left); // 左 int rightdepth = getdepth(node->right); // 右 int depth = 1 + max(leftdepth, rightdepth); // 中 return depth; } - int maxdepth(treenode* root) { + int maxDepth(TreeNode* root) { return getdepth(root); } }; @@ -93,9 +93,9 @@ public: ```CPP class solution { public: - int maxdepth(treenode* root) { + int maxDepth(TreeNode* root) { if (root == null) return 0; - return 1 + max(maxdepth(root->left), maxdepth(root->right)); + return 1 + max(maxDepth(root->left), maxDepth(root->right)); } }; @@ -110,7 +110,7 @@ public: class solution { public: int result; - void getdepth(treenode* node, int depth) { + void getdepth(TreeNode* node, int depth) { result = depth > result ? depth : result; // 中 if (node->left == NULL && node->right == NULL) return ; @@ -127,7 +127,7 @@ public: } return ; } - int maxdepth(treenode* root) { + int maxDepth(TreeNode* root) { result = 0; if (root == NULL) return result; getdepth(root, 1); @@ -144,7 +144,7 @@ public: class solution { public: int result; - void getdepth(treenode* node, int depth) { + void getdepth(TreeNode* node, int depth) { result = depth > result ? depth : result; // 中 if (node->left == NULL && node->right == NULL) return ; if (node->left) { // 左 @@ -155,7 +155,7 @@ public: } return ; } - int maxdepth(treenode* root) { + int maxDepth(TreeNode* root) { result = 0; if (root == 0) return result; getdepth(root, 1); @@ -182,16 +182,16 @@ c++代码如下: ```CPP class solution { public: - int maxdepth(treenode* root) { + int maxDepth(TreeNode* root) { if (root == NULL) return 0; int depth = 0; - queue que; + queue que; que.push(root); while(!que.empty()) { int size = que.size(); depth++; // 记录深度 for (int i = 0; i < size; i++) { - treenode* node = que.front(); + TreeNode* node = que.front(); que.pop(); if (node->left) que.push(node->left); if (node->right) que.push(node->right); @@ -230,11 +230,11 @@ c++代码: ```CPP class solution { public: - int maxdepth(node* root) { + int maxDepth(Node* root) { if (root == 0) return 0; int depth = 0; for (int i = 0; i < root->children.size(); i++) { - depth = max (depth, maxdepth(root->children[i])); + depth = max (depth, maxDepth(root->children[i])); } return depth + 1; } @@ -247,15 +247,15 @@ public: ```CPP class solution { public: - int maxdepth(node* root) { - queue que; + int maxDepth(Node* root) { + queue que; if (root != NULL) que.push(root); int depth = 0; while (!que.empty()) { int size = que.size(); depth++; // 记录深度 for (int i = 0; i < size; i++) { - node* node = que.front(); + Node* node = que.front(); que.pop(); for (int j = 0; j < node->children.size(); j++) { if (node->children[j]) que.push(node->children[j]); From 6af02057b674d64c19c733c490ae9090e30e498e Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Fri, 31 Mar 2023 18:04:59 +0800 Subject: [PATCH 079/126] =?UTF-8?q?Update=200435.=E6=97=A0=E9=87=8D?= =?UTF-8?q?=E5=8F=A0=E5=8C=BA=E9=97=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0435.无重叠区间.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index 02db2034..37ef819d 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -399,18 +399,20 @@ object Solution { ```Rust impl Solution { pub fn erase_overlap_intervals(intervals: Vec>) -> i32 { - if intervals.len() == 0 { return 0; } - let mut intervals = intervals; - intervals.sort_by(|a, b| a[1].cmp(&b[1])); + if intervals.is_empty() { + return 0; + } + intervals.sort_by_key(|interval| interval[1]); let mut count = 1; let mut end = intervals[0][1]; - for i in 1..intervals.len() { - if end <= intervals[i][0] { - end = intervals[i][1]; + for v in intervals.iter().skip(1) { + if end <= v[0] { + end = v[1]; count += 1; } } - intervals.len() as i32 - count + + (intervals.len() - count) as i32 } } ``` From 2208d96581e13b19e4d41610f259b04ad3a75856 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Fri, 31 Mar 2023 18:37:51 +0800 Subject: [PATCH 080/126] =?UTF-8?q?Update=200763.=E5=88=92=E5=88=86?= =?UTF-8?q?=E5=AD=97=E6=AF=8D=E5=8C=BA=E9=97=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index ad680ef9..fbcafdc8 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -412,28 +412,22 @@ object Solution { ### Rust ```Rust -use std::collections::HashMap; impl Solution { - fn max (a: usize, b: usize) -> usize { - if a > b { a } else { b } - } pub fn partition_labels(s: String) -> Vec { - let s = s.chars().collect::>(); - let mut hash: HashMap = HashMap::new(); - for i in 0..s.len() { - hash.insert(s[i], i); + let mut hash = vec![0; 26]; + for (i, &c) in s.as_bytes().iter().enumerate() { + hash[(c - b'a') as usize] = i; } - let mut result: Vec = Vec::new(); - let mut left: usize = 0; - let mut right: usize = 0; - for i in 0..s.len() { - right = Self::max(right, hash[&s[i]]); + let mut res = vec![]; + let (mut left, mut right) = (0, 0); + for (i, &c) in s.as_bytes().iter().enumerate() { + right = right.max(hash[(c - b'a') as usize]); if i == right { - result.push((right - left + 1) as i32); + res.push((right - left + 1) as i32); left = i + 1; } } - result + res } } ``` From 24d59de1c0ef5580b122516404ea5b5bdd9c0d44 Mon Sep 17 00:00:00 2001 From: GODVvVZzz <2662446324@qq.com> Date: Fri, 31 Mar 2023 20:59:03 +0800 Subject: [PATCH 081/126] =?UTF-8?q?Modify=20376=E6=91=86=E5=8A=A8=E5=BA=8F?= =?UTF-8?q?=E5=88=97.md=20=E9=94=99=E5=88=AB=E5=AD=97-=E6=9E=9C->=E4=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0376.摆动序列.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md index 469c19fd..ff388b55 100644 --- a/problems/0376.摆动序列.md +++ b/problems/0376.摆动序列.md @@ -89,7 +89,7 @@ ### 情况二:数组首尾两端 -所以本题统计峰值的时候,数组最左面和最右面如果统计呢? +所以本题统计峰值的时候,数组最左面和最右面如何统计呢? 题目中说了,如果只有两个不同的元素,那摆动序列也是 2。 @@ -655,3 +655,4 @@ object Solution { + From 7e80792a63f6d0b63745f2bb5c401b1a749afc1a Mon Sep 17 00:00:00 2001 From: YuZou Date: Fri, 31 Mar 2023 22:20:36 +0800 Subject: [PATCH 082/126] =?UTF-8?q?update=200045.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8FII.md=20=E4=BF=AE=E6=94=B9=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E8=AF=AD=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index c6e4e9b5..2f6e8b67 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -76,11 +76,9 @@ public: for (int i = 0; i < nums.size(); i++) { nextDistance = max(nums[i] + i, nextDistance); // 更新下一步覆盖最远距离下标 if (i == curDistance) { // 遇到当前覆盖最远距离下标 - if (curDistance < nums.size() - 1) { // 如果当前覆盖最远距离下标不是终点 - ans++; // 需要走下一步 - curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了) - if (nextDistance >= nums.size() - 1) break; // 下一步的覆盖范围已经可以达到终点,结束循环 - } else break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束 + ans++; // 需要走下一步 + curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了) + if (nextDistance >= nums.size() - 1) break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束 } } return ans; From 6943358d8f75b4c189bcedaa5b79d5c0b0a93c2a Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Fri, 31 Mar 2023 21:58:27 -0400 Subject: [PATCH 083/126] =?UTF-8?q?Update=200538.=E6=8A=8A=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E8=BD=AC=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=E7=B4=AF=E5=8A=A0=E6=A0=91.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 python 迭代法 --- ...38.把二叉搜索树转换为累加树.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md index 29b21840..ad5310e1 100644 --- a/problems/0538.把二叉搜索树转换为累加树.md +++ b/problems/0538.把二叉搜索树转换为累加树.md @@ -234,6 +234,26 @@ class Solution: return root ``` +**迭代** +```python +class Solution: + def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + if not root: return root + stack = [] + result = [] + cur = root + pre = 0 + while cur or stack: + if cur: + stack.append(cur) + cur = cur.right + else: + cur = stack.pop() + cur.val+= pre + pre = cur.val + cur =cur.left + return root +``` ## Go From ddda474eb4d73d894205cd5845b0c41f1b34226b Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Sat, 1 Apr 2023 11:42:50 +0800 Subject: [PATCH 084/126] =?UTF-8?q?Update=200056.=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=8C=BA=E9=97=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0056.合并区间.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index 17d2cc0a..d03a590d 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -280,24 +280,22 @@ object Solution { ```Rust impl Solution { - fn max(a: i32, b: i32) -> i32 { - if a > b { a } else { b } - } - - pub fn merge(intervals: Vec>) -> Vec> { - let mut intervals = intervals; - let mut result = Vec::new(); - if intervals.len() == 0 { return result; } - intervals.sort_by(|a, b| a[0].cmp(&b[0])); - result.push(intervals[0].clone()); - for i in 1..intervals.len() { - if result.last_mut().unwrap()[1] >= intervals[i][0] { - result.last_mut().unwrap()[1] = Self::max(result.last_mut().unwrap()[1], intervals[i][1]); + pub fn merge(mut intervals: Vec>) -> Vec> { + let mut res = vec![]; + if intervals.is_empty() { + return res; + } + intervals.sort_by_key(|a| a[0]); + res.push(intervals[0].clone()); + for interval in intervals.into_iter().skip(1) { + let res_last_ele = res.last_mut().unwrap(); + if res_last_ele[1] >= interval[0] { + res_last_ele[1] = interval[1].max(res_last_ele[1]); } else { - result.push(intervals[i].clone()); + res.push(interval); } } - result + res } } ``` From cd1a680c26c25e928b7a56f3e98ce8d00f7e1577 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Sat, 1 Apr 2023 12:22:37 +0800 Subject: [PATCH 085/126] =?UTF-8?q?Update=200738.=E5=8D=95=E8=B0=83?= =?UTF-8?q?=E9=80=92=E5=A2=9E=E7=9A=84=E6=95=B0=E5=AD=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0738.单调递增的数字.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index f92652cd..1cf8a0a6 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -280,18 +280,20 @@ object Solution { ```Rust impl Solution { pub fn monotone_increasing_digits(n: i32) -> i32 { - let mut str_num = n.to_string().chars().map(|x| x.to_digit(10).unwrap() as i32).collect::>(); - let mut flag = str_num.len(); - for i in (1..str_num.len()).rev() { - if str_num[i - 1] > str_num[i] { + let mut n_bytes = n.to_string().into_bytes(); + let mut flag = n_bytes.len(); + for i in (1..n_bytes.len()).rev() { + if n_bytes[i - 1] > n_bytes[i] { flag = i; - str_num[i - 1] -= 1; + n_bytes[i - 1] -= 1; } } - for i in flag..str_num.len() { - str_num[i] = 9; + for v in n_bytes.iter_mut().skip(flag) { + *v = 57; } - str_num.iter().fold(0, |acc, x| acc * 10 + x) + n_bytes + .into_iter() + .fold(0, |acc, x| acc * 10 + x as i32 - 48) } } ``` From 02f9c26f696774c9db2aa7bef4ac25f9d4b28803 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:42:01 +0800 Subject: [PATCH 086/126] =?UTF-8?q?updaye=200232.=E7=94=A8=E6=A0=88?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0232.用栈实现队列.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index efeb1046..4a57ee96 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -112,6 +112,10 @@ public: ``` +* 时间复杂度: push和empty为O(1), pop和peek为O(n) +* 空间复杂度: O(n) + + ## 拓展 可以看出peek()的实现,直接复用了pop(), 要不然,对stOut判空的逻辑又要重写一遍。 From 1b6e26be2bf4f2dd584b3b59e4781a9d79cd4b48 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:45:02 +0800 Subject: [PATCH 087/126] =?UTF-8?q?update=200225.=E7=94=A8=E9=98=9F?= =?UTF-8?q?=E5=88=97=E5=AE=9E=E7=8E=B0=E6=A0=88=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0225.用队列实现栈.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index 16b9e47c..bad2faec 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -111,6 +111,8 @@ public: } }; ``` +* 时间复杂度: push为O(n),其他为O(1) +* 空间复杂度: O(n) # 优化 @@ -156,6 +158,9 @@ public: } }; ``` +* 时间复杂度: push为O(n),其他为O(1) +* 空间复杂度: O(n) + # 其他语言版本 From 916718824bd6fe521ee2164b29f71d11633828a7 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:47:36 +0800 Subject: [PATCH 088/126] =?UTF-8?q?update=200020.=E6=9C=89=E6=95=88?= =?UTF-8?q?=E7=9A=84=E6=8B=AC=E5=8F=B7=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0020.有效的括号.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index a25129c5..213d61b7 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -135,6 +135,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + 技巧性的东西没有固定的学习方法,还是要多看多练,自己灵活运用了。 From 2633b1a346e106e8d14ee6404f1cf50cfb83a0af Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:50:29 +0800 Subject: [PATCH 089/126] =?UTF-8?q?update=201047.=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9:=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 810f7292..694f1a92 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -77,6 +77,9 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + 当然可以拿字符串直接作为栈,这样省去了栈还要转为字符串的操作。 @@ -99,6 +102,8 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1),返回值不计空间复杂度 ## 题外话 From 6cd25d1fc5f98a02c7ef1ad52ad416c39d7357a4 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:53:40 +0800 Subject: [PATCH 090/126] =?UTF-8?q?update=200150.=E9=80=86=E6=B3=A2?= =?UTF-8?q?=E5=85=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=B1=82=E5=80=BC:=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0150.逆波兰表达式求值.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index f0323bc4..09cc4f96 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -113,6 +113,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + ## 题外话 From 1662ac347d28f35073066dba2761cd9d0c4bcf35 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:55:37 +0800 Subject: [PATCH 091/126] =?UTF-8?q?update=200239.=E6=BB=91=E5=8A=A8?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E6=9C=80=E5=A4=A7=E5=80=BC=EF=BC=9A=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0239.滑动窗口最大值.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index 540ab5d7..f1c4b76c 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -184,6 +184,9 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(k) + 再来看一下时间复杂度,使用单调队列的时间复杂度是 O(n)。 From b28ba70ee1464fbd915c5d655bd6865a7d2d66e0 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Sat, 1 Apr 2023 12:57:24 +0800 Subject: [PATCH 092/126] =?UTF-8?q?update=20=200347.=E5=89=8DK=E4=B8=AA?= =?UTF-8?q?=E9=AB=98=E9=A2=91=E5=85=83=E7=B4=A0=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0347.前K个高频元素.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index d8eabef4..0d268d9b 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -79,8 +79,6 @@ ```CPP -// 时间复杂度:O(nlogk) -// 空间复杂度:O(n) class Solution { public: // 小顶堆 @@ -120,6 +118,10 @@ public: } }; ``` + +* 时间复杂度: O(nlogk) +* 空间复杂度: O(n) + # 拓展 大家对这个比较运算在建堆时是如何应用的,为什么左大于右就会建立小顶堆,反而建立大顶堆比较困惑。 From d7d7e6c733716a7eb516dea3c8b7660e8d0ac9ce Mon Sep 17 00:00:00 2001 From: ray Date: Sat, 1 Apr 2023 20:54:58 +0800 Subject: [PATCH 093/126] =?UTF-8?q?=E4=BF=AE=E6=94=B9=200203.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0.md=20=E5=86=99?= =?UTF-8?q?=E6=B3=95=E6=9B=B4Python=E4=B8=80=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0203.移除链表元素.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index 7e3955a5..b52f16ea 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -316,8 +316,8 @@ class Solution: def removeElements(self, head: ListNode, val: int) -> ListNode: dummy_head = ListNode(next=head) #添加一个虚拟节点 cur = dummy_head - while(cur.next!=None): - if(cur.next.val == val): + while cur.next: + if cur.next.val == val: cur.next = cur.next.next #删除cur.next节点 else: cur = cur.next From befa14402bbf12eb147235e190bb775a42169ba9 Mon Sep 17 00:00:00 2001 From: jyu <1025368039@qq.com> Date: Sat, 1 Apr 2023 21:45:43 +0800 Subject: [PATCH 094/126] =?UTF-8?q?=E5=A2=9E=E5=8A=A0151=20C=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index 1b006665..8fa7c77c 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -970,6 +970,49 @@ pub fn remove_extra_spaces(s: &mut Vec) { } } ``` +C: + +```C +// 翻转字符串中指定范围的字符 +void reverse(char* s, int start, int end) { + for (int i = start, j = end; i < j; i++, j--) { + int tmp = s[i]; + s[i] = s[j]; + s[j] = tmp; + } +} + +// 删除字符串两端和中间多余的空格 +void removeExtraSpace(char* s) { + int start = 0; // 指向字符串开头的指针 + int end = strlen(s) - 1; // 指向字符串结尾的指针 + while (s[start] == ' ') start++; // 移动指针 start,直到找到第一个非空格字符 + while (s[end] == ' ') end--; // 移动指针 end,直到找到第一个非空格字符 + int slow = 0; // 指向新字符串的下一个写入位置的指针 + for (int i = start; i <= end; i++) { // 遍历整个字符串 + if (s[i] == ' ' && s[i+1] == ' ') { // 如果当前字符是空格,并且下一个字符也是空格,则跳过 + continue; + } + s[slow] = s[i]; // 否则,将当前字符复制到新字符串的 slow 位置 + slow++; // 将 slow 指针向后移动 + } + s[slow] = '\0'; // 在新字符串的末尾添加一个空字符 +} + +// 翻转字符串中的单词 +char * reverseWords(char * s){ + removeExtraSpace(s); // 先删除字符串两端和中间的多余空格 + reverse(s, 0, strlen(s) - 1); // 翻转整个字符串 + int slow = 0; // 指向每个单词的开头位置的指针 + for (int i = 0; i <= strlen(s); i++) { // 遍历整个字符串 + if (s[i] ==' ' || s[i] == '\0') { // 如果当前字符是空格或空字符,说明一个单词结束了 + reverse(s, slow, i-1); // 翻转单词 + slow = i + 1; // 将 slow 指针指向下一个单词的开头位置 + } + } + return s; // 返回处理后的字符串 +} +```

From c1f17275e5879b94e0dcbc321f9dd434068ce516 Mon Sep 17 00:00:00 2001 From: mercer5 <602502833@qq.com> Date: Sun, 2 Apr 2023 11:40:30 +0800 Subject: [PATCH 095/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A00739=E6=AF=8F?= =?UTF-8?q?=E6=97=A5=E6=B8=A9=E5=BA=A6=20python=20=E7=B2=BE=E7=AE=80?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0739.每日温度.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md index 263a28f4..e521fbc6 100644 --- a/problems/0739.每日温度.md +++ b/problems/0739.每日温度.md @@ -271,6 +271,7 @@ class Solution { ``` Python: +> 未精简版本 ```python class Solution: @@ -291,6 +292,22 @@ class Solution: return answer ``` +> 精简版本 + +```python +class Solution: + def dailyTemperatures(self, temperatures: List[int]) -> List[int]: + # 单调栈 + answer = [0]*len(temperatures) + stack = [] + for i in range(len(temperatures)): + while len(stack)>0 and temperatures[i] > temperatures[stack[-1]]: + answer[stack[-1]] = i - stack[-1] + stack.pop() + stack.append(i) + return answer +``` + Go: > 暴力法 From a490e39206f4fd5d89165bbf0b38f982736e5309 Mon Sep 17 00:00:00 2001 From: mercer5 <602502833@qq.com> Date: Sun, 2 Apr 2023 11:50:29 +0800 Subject: [PATCH 096/126] =?UTF-8?q?=E4=BF=AE=E6=94=B90739=E6=AF=8F?= =?UTF-8?q?=E6=97=A5=E6=B8=A9=E5=BA=A6=20python=20=E7=B2=BE=E7=AE=80?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0739.每日温度.md | 1 - 1 file changed, 1 deletion(-) diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md index e521fbc6..749dc972 100644 --- a/problems/0739.每日温度.md +++ b/problems/0739.每日温度.md @@ -297,7 +297,6 @@ class Solution: ```python class Solution: def dailyTemperatures(self, temperatures: List[int]) -> List[int]: - # 单调栈 answer = [0]*len(temperatures) stack = [] for i in range(len(temperatures)): From 34e1b0ab5ce4a839ac9bf40b9e7ceb582fd51119 Mon Sep 17 00:00:00 2001 From: ayao98 <91120769+ayao98@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:48:51 +0800 Subject: [PATCH 097/126] =?UTF-8?q?Update=200112.=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=80=BB=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0112.路径总和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index 9b6027d1..5958de93 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -250,7 +250,7 @@ private: vector> result; vector path; // 递归函数不需要返回值,因为我们要遍历整个树 - void traversal(treenode* cur, int count) { + void traversal(TreeNode* cur, int count) { if (!cur->left && !cur->right && count == 0) { // 遇到了叶子节点且找到了和为sum的路径 result.push_back(path); return; @@ -276,10 +276,10 @@ private: } public: - vector> pathsum(treenode* root, int sum) { + vector> pathSum(TreeNode* root, int sum) { result.clear(); path.clear(); - if (root == null) return result; + if (root == NULL) return result; path.push_back(root->val); // 把根节点放进路径 traversal(root, sum - root->val); return result; From 9e27f3dd9b40dabef0afd7e085fb6dec0e745474 Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Tue, 4 Apr 2023 22:51:45 -0400 Subject: [PATCH 098/126] =?UTF-8?q?Update=200332.=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=AE=89=E6=8E=92=E8=A1=8C=E7=A8=8B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加: python - 使用used数组 - 神似之前几题写法 --- problems/0332.重新安排行程.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 9bd5df7a..95e7d3ed 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -380,7 +380,33 @@ class Solution: backtracking("JFK") return path ``` + +python - 使用used数组 - 神似之前几题写法 +```python +class Solution: + def findItinerary(self, tickets: List[List[str]]) -> List[str]: + global used,path,results + used = [0]*len(tickets) + path = ['JFK'] + results = [] + tickets.sort() # 先排序,这样一旦找到第一个可行路径,一定是字母排序最小的 + self.backtracking(tickets,'JFK') + return results[0] + def backtracking(self,tickets,cur): + if sum(used) == len(tickets): + results.append(path[:]) + return True # 只要找到就返回 + for i in range(len(tickets)): + if tickets[i][0]==cur and used[i]==0: + used[i]=1 + path.append(tickets[i][1]) + state = self.backtracking(tickets,tickets[i][1]) + path.pop() + used[i]=0 + if state: return True # 只要找到就返回,不继续搜索了 +``` + ### GO ```go type pair struct { From 700b5c388bb1c3cb0a0d70ee9d0e0b54d5235a6e Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Thu, 6 Apr 2023 15:48:47 -0400 Subject: [PATCH 099/126] =?UTF-8?q?Update=200045.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8FII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加python - 贪心版本三 - 类似‘55-跳跃游戏’写法 --- problems/0045.跳跃游戏II.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index c6e4e9b5..d12664ac 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -231,6 +231,21 @@ class Solution: step += 1 return step ``` +```python +# 贪心版本三 - 类似‘55-跳跃游戏’写法 +class Solution: + def jump(self, nums) -> int: + if len(nums)==1: return 0 + i = 0 + count = 0 + cover = 0 + while i<=cover: + for i in range(i,cover+1): + cover = max(nums[i]+i,cover) + if cover>=len(nums)-1: return count+1 + count+=1 + +``` ```python # 动态规划做法 From bf8c539a635ce317ab9dd9598f06ca30bdebb677 Mon Sep 17 00:00:00 2001 From: ZerenZhang2022 <118794589+ZerenZhang2022@users.noreply.github.com> Date: Thu, 6 Apr 2023 23:39:05 -0400 Subject: [PATCH 100/126] =?UTF-8?q?Update=200452.=E7=94=A8=E6=9C=80?= =?UTF-8?q?=E5=B0=91=E6=95=B0=E9=87=8F=E7=9A=84=E7=AE=AD=E5=BC=95=E7=88=86?= =?UTF-8?q?=E6=B0=94=E7=90=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 python 不改变原数组 写法 --- .../0452.用最少数量的箭引爆气球.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index 53eee25c..67070ba4 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -177,7 +177,23 @@ class Solution: points[i][1] = min(points[i - 1][1], points[i][1]) # 更新重叠气球最小右边界 return result ``` +```python +class Solution: # 不改变原数组 + def findMinArrowShots(self, points: List[List[int]]) -> int: + points.sort(key = lambda x: x[0]) + sl,sr = points[0][0],points[0][1] + count = 1 + for i in points: + if i[0]>sr: + count+=1 + sl,sr = i[0],i[1] + else: + sl = max(sl,i[0]) + sr = min(sr,i[1]) + return count + +``` ### Go ```go func findMinArrowShots(points [][]int) int { From 4b0982e681e72081752843e8df83c0ceec1b543a Mon Sep 17 00:00:00 2001 From: Liu Cheng <32453247+Falldio@users.noreply.github.com> Date: Fri, 7 Apr 2023 14:29:56 +0800 Subject: [PATCH 101/126] =?UTF-8?q?=E6=B7=BB=E5=8A=A00132.=E5=88=86?= =?UTF-8?q?=E5=89=B2=E5=9B=9E=E6=96=87=E4=B8=B2II=E7=9A=84Golang=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0132.分割回文串II.md | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/problems/0132.分割回文串II.md b/problems/0132.分割回文串II.md index eb0e39fb..9b164dfb 100644 --- a/problems/0132.分割回文串II.md +++ b/problems/0132.分割回文串II.md @@ -289,7 +289,45 @@ class Solution: ## Go ```go +func minCut(s string) int { + isValid := make([][]bool, len(s)) + for i := 0; i < len(isValid); i++ { + isValid[i] = make([]bool, len(s)) + isValid[i][i] = true + } + for i := len(s) - 1; i >= 0; i-- { + for j := i + 1; j < len(s); j++ { + if s[i] == s[j] && (isValid[i + 1][j - 1] || j - i == 1) { + isValid[i][j] = true + } + } + } + dp := make([]int, len(s)) + for i := 0; i < len(s); i++ { + dp[i] = math.MaxInt + } + for i := 0; i < len(s); i++ { + if isValid[0][i] { + dp[i] = 0 + continue + } + for j := 0; j < i; j++ { + if isValid[j + 1][i] { + dp[i] = min(dp[i], dp[j] + 1) + } + } + } + return dp[len(s) - 1] +} + +func min(i, j int) int { + if i < j { + return i + } else { + return j + } +} ``` ## JavaScript From dbcec85e977fce41e5459ef3d108b29abc98883b Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:22:10 +0800 Subject: [PATCH 102/126] =?UTF-8?q?update=200455.=E5=88=86=E5=8F=91?= =?UTF-8?q?=E9=A5=BC=E5=B9=B2=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0455.分发饼干.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/problems/0455.分发饼干.md b/problems/0455.分发饼干.md index 3688b3fd..efadb433 100644 --- a/problems/0455.分发饼干.md +++ b/problems/0455.分发饼干.md @@ -56,8 +56,6 @@ C++代码整体如下: ```CPP // 版本一 -// 时间复杂度:O(nlogn) -// 空间复杂度:O(1) class Solution { public: int findContentChildren(vector& g, vector& s) { @@ -75,6 +73,9 @@ public: } }; ``` +* 时间复杂度:O(nlogn) +* 空间复杂度:O(1) + 从代码中可以看出我用了一个 index 来控制饼干数组的遍历,遍历饼干并没有再起一个 for 循环,而是采用自减的方式,这也是常用的技巧。 @@ -118,6 +119,9 @@ public: } }; ``` +* 时间复杂度:O(nlogn) +* 空间复杂度:O(1) + 细心的录友可以发现,这种写法,两个循环的顺序改变了,先遍历的饼干,在遍历的胃口,这是因为遍历顺序变了,我们是从小到大遍历。 From 80006ad61592e0268fd4a8857a8a8b687278c5b3 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:28:09 +0800 Subject: [PATCH 103/126] =?UTF-8?q?update=200053.=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E5=AD=90=E5=BA=8F=E5=92=8C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0053.最大子序和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0053.最大子序和.md b/problems/0053.最大子序和.md index 1de68041..48f8be29 100644 --- a/problems/0053.最大子序和.md +++ b/problems/0053.最大子序和.md @@ -24,8 +24,6 @@ 暴力解法的思路,第一层 for 就是设置起始位置,第二层 for 循环遍历数组寻找最大值 -- 时间复杂度:O(n^2) -- 空间复杂度:O(1) ```CPP class Solution { @@ -44,6 +42,9 @@ public: } }; ``` +* 时间复杂度:O(n^2) +* 空间复杂度:O(1) + 以上暴力的解法 C++勉强可以过,其他语言就不确定了。 @@ -98,7 +99,6 @@ public: } }; ``` - - 时间复杂度:O(n) - 空间复杂度:O(1) From 85f54a718d022e6a3cb5883fb3d9aff5745a3362 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:30:07 +0800 Subject: [PATCH 104/126] =?UTF-8?q?update=20=20=200055.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0055.跳跃游戏.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0055.跳跃游戏.md b/problems/0055.跳跃游戏.md index ce9a21ec..c187ef8f 100644 --- a/problems/0055.跳跃游戏.md +++ b/problems/0055.跳跃游戏.md @@ -75,6 +75,10 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + + ## 总结 这道题目关键点在于:不用拘泥于每次究竟跳几步,而是看覆盖范围,覆盖范围内一定是可以跳过来的,不用管是怎么跳的。 From 4afa9c2a51f3745b1dc6497fd522a607f3174136 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:32:31 +0800 Subject: [PATCH 105/126] =?UTF-8?q?update=20=20=200045.=E8=B7=B3=E8=B7=83?= =?UTF-8?q?=E6=B8=B8=E6=88=8FII=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index c6e4e9b5..558b32b9 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -88,6 +88,10 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + + ## 方法二 依然是贪心,思路和方法一差不多,代码可以简洁一些。 @@ -127,6 +131,11 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + + + 可以看出版本二的代码相对于版本一简化了不少! **其精髓在于控制移动下标 i 只移动到 nums.size() - 2 的位置**,所以移动下标只要遇到当前覆盖最远距离的下标,直接步数加一,不用考虑别的了。 From 38c74c90d793b9637feceec6350e269d9e460a16 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:34:25 +0800 Subject: [PATCH 106/126] =?UTF-8?q?update=20=20=201005.K=E6=AC=A1=E5=8F=96?= =?UTF-8?q?=E5=8F=8D=E5=90=8E=E6=9C=80=E5=A4=A7=E5=8C=96=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E5=92=8C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1005.K次取反后最大化的数组和.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index 4a080857..27a575c7 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -85,6 +85,10 @@ public: }; ``` +* 时间复杂度: O(nlogn) +* 空间复杂度: O(1) + + ## 总结 贪心的题目如果简单起来,会让人简单到开始怀疑:本来不就应该这么做么?这也算是算法?我认为这不是贪心? From 25bf0859a1e7b68ddfcb83456e9828244e0ee703 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:36:37 +0800 Subject: [PATCH 107/126] =?UTF-8?q?update=20=20=200135.=E5=88=86=E5=8F=91?= =?UTF-8?q?=E7=B3=96=E6=9E=9C=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0135.分发糖果.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md index ef79868a..1ba1563f 100644 --- a/problems/0135.分发糖果.md +++ b/problems/0135.分发糖果.md @@ -121,6 +121,11 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + + + ## 总结 这在leetcode上是一道困难的题目,其难点就在于贪心的策略,如果在考虑局部的时候想两边兼顾,就会顾此失彼。 From 4c7464fa93ca388699b37935e5b56e68b1f6fed2 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:37:48 +0800 Subject: [PATCH 108/126] =?UTF-8?q?update=20=200860.=E6=9F=A0=E6=AA=AC?= =?UTF-8?q?=E6=B0=B4=E6=89=BE=E9=9B=B6=20=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0860.柠檬水找零.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index cd52adb0..d96e0879 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -115,6 +115,9 @@ public: } }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(1) + ## 总结 From ff77937816b26b6aa88a41fb6b1684837ca1a31d Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:41:40 +0800 Subject: [PATCH 109/126] =?UTF-8?q?update=20=20=200056.=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=8C=BA=E9=97=B4=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0056.合并区间.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index ec659108..72dc69c5 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -73,6 +73,10 @@ public: }; ``` +* 时间复杂度: O(nlogn) +* 空间复杂度: O(logn),排序需要的空间开销 + + ## 其他语言版本 From 528c1d4f9e9678b143706178f76d91c0de6947c4 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 00:49:38 +0800 Subject: [PATCH 110/126] =?UTF-8?q?update=20=20=200968.=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0968.监控二叉树.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0968.监控二叉树.md b/problems/0968.监控二叉树.md index 267e7f6e..fdec56ca 100644 --- a/problems/0968.监控二叉树.md +++ b/problems/0968.监控二叉树.md @@ -303,6 +303,11 @@ public: ``` +* 时间复杂度: O(n),需要遍历二叉树上的每个节点 +* 空间复杂度: O(n) + + + 大家可能会惊讶,居然可以这么简短,**其实就是在版本一的基础上,使用else把一些情况直接覆盖掉了**。 在网上关于这道题解可以搜到很多这种神级别的代码,但都没讲不清楚,如果直接看代码的话,指定越看越晕,**所以建议大家对着版本一的代码一步一步来,版本二中看不中用!**。 From 4e1590e26db6363af09e0feef0109d27d48b3958 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:14:10 +0800 Subject: [PATCH 111/126] =?UTF-8?q?update=20=200474.=E4=B8=80=E5=92=8C?= =?UTF-8?q?=E9=9B=B6=20=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0474.一和零.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0474.一和零.md b/problems/0474.一和零.md index 8d79d701..6a178a25 100644 --- a/problems/0474.一和零.md +++ b/problems/0474.一和零.md @@ -156,6 +156,11 @@ public: }; ``` +* 时间复杂度: O(kmn),k 为strs的长度 +* 空间复杂度: O(mn) + + + ## 总结 不少同学刷过这道题,可能没有总结这究竟是什么背包。 From f701133a9a8b418904cf02583e90d3c7fcbdd743 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:17:04 +0800 Subject: [PATCH 112/126] =?UTF-8?q?update=20=20=200518.=E9=9B=B6=E9=92=B1?= =?UTF-8?q?=E5=85=91=E6=8D=A2II=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0518.零钱兑换II.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md index eb5a844c..c208754f 100644 --- a/problems/0518.零钱兑换II.md +++ b/problems/0518.零钱兑换II.md @@ -179,6 +179,11 @@ public: } }; ``` + +* 时间复杂度: O(mn),其中 m 是amount,n 是 coins 的长度 +* 空间复杂度: O(m) + + 是不是发现代码如此精简,哈哈 ## 总结 From 6e62049cd3f06e5bf156240087d90bdfb5910569 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:20:07 +0800 Subject: [PATCH 113/126] =?UTF-8?q?update=20=200377.=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=80=BB=E5=92=8C=E2=85=A3=20=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0377.组合总和Ⅳ.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0377.组合总和Ⅳ.md b/problems/0377.组合总和Ⅳ.md index f2287188..ee659723 100644 --- a/problems/0377.组合总和Ⅳ.md +++ b/problems/0377.组合总和Ⅳ.md @@ -130,6 +130,11 @@ public: ``` +* 时间复杂度: O(target * n),其中 n 为 nums 的长度 +* 空间复杂度: O(target) + + + C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。 但java就不用考虑这个限制,java里的int也是四个字节吧,也有可能leetcode后台对不同语言的测试数据不一样。 From 84b84e5bf11158c3ab4ac2356c8290060b7ebf45 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:46:51 +0800 Subject: [PATCH 114/126] =?UTF-8?q?update=20=20=200070.=E7=88=AC=E6=A5=BC?= =?UTF-8?q?=E6=A2=AF=E5=AE=8C=E5=85=A8=E8=83=8C=E5=8C=85=E7=89=88=E6=9C=AC?= =?UTF-8?q?=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0070.爬楼梯完全背包版本.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md index 41c2e616..8f8bc9a6 100644 --- a/problems/0070.爬楼梯完全背包版本.md +++ b/problems/0070.爬楼梯完全背包版本.md @@ -101,6 +101,11 @@ public: }; ``` +* 时间复杂度: O(nm) +* 空间复杂度: O(n) + + + 代码中m表示最多可以爬m个台阶,代码中把m改成2就是本题70.爬楼梯可以AC的代码了。 ## 总结 From 9fef5cbd00bde88126d4407c913d4b5f448d5308 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:51:41 +0800 Subject: [PATCH 115/126] =?UTF-8?q?=20update=20=20=200322.=E9=9B=B6?= =?UTF-8?q?=E9=92=B1=E5=85=91=E6=8D=A2=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0322.零钱兑换.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/problems/0322.零钱兑换.md b/problems/0322.零钱兑换.md index 3be72565..0e3947da 100644 --- a/problems/0322.零钱兑换.md +++ b/problems/0322.零钱兑换.md @@ -133,6 +133,11 @@ public: }; ``` +* 时间复杂度: O(n * amount),其中 n 为 coins 的长度 +* 空间复杂度: O(amount) + + + 对于遍历方式遍历背包放在外循环,遍历物品放在内循环也是可以的,我就直接给出代码了 ```CPP @@ -154,6 +159,8 @@ public: } }; ``` +* 同上 + ## 总结 From b6fcdc160d85cd5d541c851f514e7ea332ffd4b4 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 11:57:47 +0800 Subject: [PATCH 116/126] =?UTF-8?q?=20update=20=20=200279.=E5=AE=8C?= =?UTF-8?q?=E5=85=A8=E5=B9=B3=E6=96=B9=E6=95=B0=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index c329156b..f5b23d26 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -127,6 +127,10 @@ public: }; ``` +* 时间复杂度: O(n * √n) +* 空间复杂度: O(n) + + 同样我在给出先遍历物品,在遍历背包的代码,一样的可以AC的。 ```CPP @@ -145,6 +149,8 @@ public: } }; ``` +* 同上 + ## 总结 From ecf8251c6ad8c3524ebbe282a62a682acc91824b Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 13:58:53 +0800 Subject: [PATCH 117/126] =?UTF-8?q?update=20=20=200198.=E6=89=93=E5=AE=B6?= =?UTF-8?q?=E5=8A=AB=E8=88=8D=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0198.打家劫舍.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md index fdb2dabf..c25f3b86 100644 --- a/problems/0198.打家劫舍.md +++ b/problems/0198.打家劫舍.md @@ -108,6 +108,9 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + ## 总结 打家劫舍是DP解决的经典题目,这道题也是打家劫舍入门级题目,后面我们还会变种方式来打劫的。 From 6754a955688dd80870593da89fa26d889074e748 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:00:01 +0800 Subject: [PATCH 118/126] =?UTF-8?q?update=20=200213.=E6=89=93=E5=AE=B6?= =?UTF-8?q?=E5=8A=AB=E8=88=8DII=20=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0213.打家劫舍II.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0213.打家劫舍II.md b/problems/0213.打家劫舍II.md index 0627eedb..becad069 100644 --- a/problems/0213.打家劫舍II.md +++ b/problems/0213.打家劫舍II.md @@ -82,6 +82,11 @@ public: }; ``` +* 时间复杂度: O(n) +* 空间复杂度: O(n) + + + ## 总结 成环之后还是难了一些的, 不少题解没有把“考虑房间”和“偷房间”说清楚。 From 56b35274356fe0cecda151e5d1aa77a9f8b750b3 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:07:01 +0800 Subject: [PATCH 119/126] =?UTF-8?q?update=20=200188.=E4=B9=B0=E5=8D=96?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA?= =?UTF-8?q?IV=20=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6?= =?UTF-8?q?=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0188.买卖股票的最佳时机IV.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 4fdd7bf4..f6744a2b 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -156,6 +156,11 @@ public: }; ``` +* 时间复杂度: O(n * k),其中 n 为 prices 的长度 +* 空间复杂度: O(n * k) + + + 当然有的解法是定义一个三维数组dp[i][j][k],第i天,第j次买卖,k表示买还是卖的状态,从定义上来讲是比较直观。 但感觉三维数组操作起来有些麻烦,我是直接用二维数组来模拟三维数组的情况,代码看起来也清爽一些。 From 5bc0fa5c96684068bec235ca353e297b199f5414 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:08:42 +0800 Subject: [PATCH 120/126] =?UTF-8?q?=20update=20=20=200300.=E6=9C=80?= =?UTF-8?q?=E9=95=BF=E4=B8=8A=E5=8D=87=E5=AD=90=E5=BA=8F=E5=88=97=EF=BC=9A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0300.最长上升子序列.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index 478837cc..e8cb0b5f 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -106,6 +106,10 @@ public: } }; ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(n) + + ## 总结 From 1ed179e233bc18574a3f4e7b46cbbed9ab686667 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:11:04 +0800 Subject: [PATCH 121/126] =?UTF-8?q?update=20=20=201143.=E6=9C=80=E9=95=BF?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E5=AD=90=E5=BA=8F=E5=88=97=EF=BC=9A=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1143.最长公共子序列.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index 8e5f7eb2..730e9ad1 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -124,6 +124,10 @@ public: } }; ``` +* 时间复杂度: O(n * m),其中 n 和 m 分别为 text1 和 text2 的长度 +* 空间复杂度: O(n * m) + + ## 其他语言版本 From 4ded4b5c820f3098ab54a3dbd6cda23e0c5e70ff Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:12:41 +0800 Subject: [PATCH 122/126] =?UTF-8?q?update=20=20=201035.=E4=B8=8D=E7=9B=B8?= =?UTF-8?q?=E4=BA=A4=E7=9A=84=E7=BA=BF=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1035.不相交的线.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/1035.不相交的线.md b/problems/1035.不相交的线.md index d1e1e30a..7b60abdd 100644 --- a/problems/1035.不相交的线.md +++ b/problems/1035.不相交的线.md @@ -62,6 +62,10 @@ public: } }; ``` +* 时间复杂度: O(n * m) +* 空间复杂度: O(n * m) + + ## 总结 From f579a9f82e89f18338b7af64f94e76a63fa7f96d Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:14:03 +0800 Subject: [PATCH 123/126] =?UTF-8?q?update=20=20=200115.=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E7=9A=84=E5=AD=90=E5=BA=8F=E5=88=97=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0115.不同的子序列.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index daa708bc..6127f190 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -149,6 +149,11 @@ public: }; ``` +* 时间复杂度: O(n * m) +* 空间复杂度: O(n * m) + + + ## 其他语言版本 From 7d6476c16a421ef03c56ee101e1fd16b1d47ea9c Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:15:40 +0800 Subject: [PATCH 124/126] =?UTF-8?q?update=20=200583.=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84=E5=88=A0=E9=99=A4=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=20=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0583.两个字符串的删除操作.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/problems/0583.两个字符串的删除操作.md b/problems/0583.两个字符串的删除操作.md index eb046a9d..561ad2f2 100644 --- a/problems/0583.两个字符串的删除操作.md +++ b/problems/0583.两个字符串的删除操作.md @@ -104,6 +104,10 @@ public: }; ``` +* 时间复杂度: O(n * m) +* 空间复杂度: O(n * m) + + ### 动态规划二 @@ -127,6 +131,10 @@ public: }; ``` +* 时间复杂度: O(n * m) +* 空间复杂度: O(n * m) + + ## 其他语言版本 From 541ac6ef3cfe7da2312df2cedf9df63edce2b325 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:16:43 +0800 Subject: [PATCH 125/126] =?UTF-8?q?update=20=20=200072.=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E8=B7=9D=E7=A6=BB=EF=BC=9A=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0072.编辑距离.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md index 0b49e3c6..cc4ab00c 100644 --- a/problems/0072.编辑距离.md +++ b/problems/0072.编辑距离.md @@ -218,6 +218,10 @@ public: } }; ``` +* 时间复杂度: O(n * m) +* 空间复杂度: O(n * m) + + ## 其他语言版本 From a26fe0fdf4559c535ac3f04d4e43e87b86b01196 Mon Sep 17 00:00:00 2001 From: Yuhao Ju Date: Tue, 11 Apr 2023 14:17:50 +0800 Subject: [PATCH 126/126] =?UTF-8?q?update=20=200516.=E6=9C=80=E9=95=BF?= =?UTF-8?q?=E5=9B=9E=E6=96=87=E5=AD=90=E5=BA=8F=E5=88=97=20=EF=BC=9A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0516.最长回文子序列.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/0516.最长回文子序列.md b/problems/0516.最长回文子序列.md index d28a33cc..fcdd57b0 100644 --- a/problems/0516.最长回文子序列.md +++ b/problems/0516.最长回文子序列.md @@ -144,6 +144,11 @@ public: } }; ``` +* 时间复杂度: O(n^2) +* 空间复杂度: O(n^2) + + + ## 其他语言版本