From e70a6ff0f1c9a6f7c69f552c9918729654646efe Mon Sep 17 00:00:00 2001 From: bqlin Date: Fri, 17 Dec 2021 13:46:06 +0800 Subject: [PATCH 01/14] =?UTF-8?q?20201112=E5=9B=9E=E6=BA=AF=E5=91=A8?= =?UTF-8?q?=E6=9C=AB=E6=80=BB=E7=BB=93=EF=BC=9A=E4=BC=98=E5=8C=96=E6=8E=92?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/周总结/20201112回溯周末总结.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/周总结/20201112回溯周末总结.md b/problems/周总结/20201112回溯周末总结.md index f363b9f7..c61de4bb 100644 --- a/problems/周总结/20201112回溯周末总结.md +++ b/problems/周总结/20201112回溯周末总结.md @@ -72,8 +72,8 @@ **所以这块就说一说我个人理解,对内容持开放态度,集思广益,欢迎大家来讨论!** 子集问题分析: -* 时间复杂度:$O(n × 2^n)$,因为每一个元素的状态无外乎取与不取,所以时间复杂度为$O(2^n)$,构造每一组子集都需要填进数组,又有需要$O(n)$,最终时间复杂度:$O(n × 2^n)$ -* 空间复杂度:$O(n)$,递归深度为n,所以系统栈所用空间为$O(n)$,每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为$O(n)$ +* 时间复杂度:$O(n × 2^n)$,因为每一个元素的状态无外乎取与不取,所以时间复杂度为$O(2^n)$,构造每一组子集都需要填进数组,又有需要$O(n)$,最终时间复杂度:$O(n × 2^n)$。 +* 空间复杂度:$O(n)$,递归深度为n,所以系统栈所用空间为$O(n)$,每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为$O(n)$。 排列问题分析: * 时间复杂度:$O(n!)$,这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。 From a8f8f21ba93cbd6640767243b2c89350795d9303 Mon Sep 17 00:00:00 2001 From: bqlin Date: Fri, 17 Dec 2021 13:47:27 +0800 Subject: [PATCH 02/14] =?UTF-8?q?0332.=E9=87=8D=E6=96=B0=E5=AE=89=E6=8E=92?= =?UTF-8?q?=E8=A1=8C=E7=A8=8B=EF=BC=9A=E4=BC=98=E5=8C=96=E6=8E=92=E7=89=88?= =?UTF-8?q?=EF=BC=8C=E8=A1=A5=E5=85=85Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0332.重新安排行程.md | 133 ++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 5 deletions(-) diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index cfdea237..b5c3ca00 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -125,7 +125,7 @@ void backtracking(参数) { 代码如下: -``` +```cpp // unordered_map<出发机场, map<到达机场, 航班次数>> targets unordered_map> targets; bool backtracking(int ticketNum, vector& result) { @@ -142,7 +142,8 @@ bool backtracking(int ticketNum, vector& result) { 所以找到了这个叶子节点了直接返回,这个递归函数的返回值问题我们在讲解二叉树的系列的时候,在这篇[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://programmercarl.com/0112.路径总和.html)详细介绍过。 当然本题的targets和result都需要初始化,代码如下: -``` + +```cpp for (const vector& vec : tickets) { targets[vec[0]][vec[1]]++; // 记录映射关系 } @@ -157,7 +158,7 @@ result.push_back("JFK"); // 起始机场 代码如下: -``` +```cpp if (result.size() == ticketNum + 1) { return true; } @@ -230,13 +231,15 @@ public: 一波分析之后,可以看出我就是按照回溯算法的模板来的。 代码中 -``` + +```cpp for (pair& target : targets[result[result.size() - 1]]) ``` pair里要有const,因为map中的key是不可修改的,所以是`pair`。 如果不加const,也可以复制一份pair,例如这么写: -``` + +```cpp for (pairtarget : targets[result[result.size() - 1]]) ``` @@ -445,5 +448,125 @@ var findItinerary = function(tickets) { ``` +### Swift + +直接迭代tickets数组: + +```swift +func findItinerary(_ tickets: [[String]]) -> [String] { + // 先对路线进行排序 + let tickets = tickets.sorted { (arr1, arr2) -> Bool in + if arr1[0] < arr2[0] { + return true + } else if arr1[0] > arr2[0] { + return false + } + if arr1[1] < arr2[1] { + return true + } else if arr1[1] > arr2[1] { + return false + } + return true + } + var path = ["JFK"] + var used = [Bool](repeating: false, count: tickets.count) + + @discardableResult + func backtracking() -> Bool { + // 结束条件:满足一条路径的数量 + if path.count == tickets.count + 1 { return true } + + for i in 0 ..< tickets.count { + // 巧妙之处!跳过处理过或出发站不是path末尾站的线路,即筛选出未处理的又可以衔接path的线路 + guard !used[i], tickets[i][0] == path.last! else { continue } + // 处理 + used[i] = true + path.append(tickets[i][1]) + // 递归 + if backtracking() { return true } + // 回溯 + path.removeLast() + used[i] = false + } + return false + } + backtracking() + return path +} +``` + +使用字典优化迭代遍历: + +```swift +func findItinerary(_ tickets: [[String]]) -> [String] { + // 建立出发站和目的站的一对多关系,要对目的地进行排序 + typealias Destination = (name: String, used: Bool) + var targets = [String: [Destination]]() + for line in tickets { + let src = line[0], des = line[1] + var value = targets[src] ?? [] + value.append((des, false)) + targets[src] = value + } + for (k, v) in targets { + targets[k] = v.sorted { $0.name < $1.name } + } + + var path = ["JFK"] + let pathCount = tickets.count + 1 + @discardableResult + func backtracking() -> Bool { + if path.count == pathCount { return true } + + let startPoint = path.last! + guard let end = targets[startPoint]?.count, end > 0 else { return false } + for i in 0 ..< end { + // 排除处理过的线路 + guard !targets[startPoint]![i].used else { continue } + // 处理 + targets[startPoint]![i].used = true + path.append(targets[startPoint]![i].name) + // 递归 + if backtracking() { return true } + // 回溯 + path.removeLast() + targets[startPoint]![i].used = false + } + return false + } + backtracking() + return path +} +``` + +使用插入时排序优化targets字典的构造: + +```swift +// 建立出发站和目的站的一对多关系,在构建的时候进行插入排序 +typealias Destination = (name: String, used: Bool) +var targets = [String: [Destination]]() +func sortedInsert(_ element: Destination, to array: inout [Destination]) { + var left = 0, right = array.count - 1 + while left <= right { + let mid = left + (right - left) / 2 + if array[mid].name < element.name { + left = mid + 1 + } else if array[mid].name > element.name { + right = mid - 1 + } else { + left = mid + break + } + } + array.insert(element, at: left) +} +for line in tickets { + let src = line[0], des = line[1] + var value = targets[src] ?? [] + sortedInsert((des, false), to: &value) + targets[src] = value +} +``` + -----------------------
From 879886acb3a5720dfd60447ca0e4eaae8036a0f0 Mon Sep 17 00:00:00 2001 From: bqlin Date: Fri, 17 Dec 2021 18:53:51 +0800 Subject: [PATCH 03/14] =?UTF-8?q?0051.N=E7=9A=87=E5=90=8E=EF=BC=9A?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8E=92=E7=89=88=EF=BC=8C=E8=A1=A5=E5=85=85?= =?UTF-8?q?Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0051.N皇后.md | 65 +++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index d36ac543..02aa25df 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -33,7 +33,7 @@ n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上, **如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 -都知道n皇后问题是回溯算法解决的经典问题,但是用回溯解决多了组合、切割、子集、排列问题之后,遇到这种二位矩阵还会有点不知所措。 +都知道n皇后问题是回溯算法解决的经典问题,但是用回溯解决多了组合、切割、子集、排列问题之后,遇到这种二维矩阵还会有点不知所措。 首先来看一下皇后们的约束条件: @@ -43,7 +43,7 @@ n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上, 确定完约束条件,来看看究竟要怎么去搜索皇后们的位置,其实搜索皇后的位置,可以抽象为一棵树。 -下面我用一个3 * 3 的棋牌,将搜索过程抽象为一颗树,如图: +下面我用一个 3 * 3 的棋盘,将搜索过程抽象为一颗树,如图: ![51.N皇后](https://img-blog.csdnimg.cn/20210130182532303.jpg) @@ -73,11 +73,11 @@ void backtracking(参数) { 我依然是定义全局变量二维数组result来记录最终结果。 -参数n是棋牌的大小,然后用row来记录当前遍历到棋盘的第几层了。 +参数n是棋盘的大小,然后用row来记录当前遍历到棋盘的第几层了。 代码如下: -``` +```cpp vector> result; void backtracking(int n, int row, vector& chessboard) { ``` @@ -92,7 +92,7 @@ void backtracking(int n, int row, vector& chessboard) { 代码如下: -``` +```cpp if (row == n) { result.push_back(chessboard); return; @@ -107,7 +107,7 @@ if (row == n) { 代码如下: -``` +```cpp for (int col = 0; col < n; col++) { if (isValid(row, col, chessboard, n)) { // 验证合法就可以放 chessboard[row][col] = 'Q'; // 放置皇后 @@ -117,7 +117,7 @@ for (int col = 0; col < n; col++) { } ``` -* 验证棋牌是否合法 +* 验证棋盘是否合法 按照如下标准去重: @@ -163,7 +163,7 @@ class Solution { private: vector> result; // n 为输入的棋盘大小 -// row 是当前递归到棋牌的第几行了 +// row 是当前递归到棋盘的第几行了 void backtracking(int n, int row, vector& chessboard) { if (row == n) { result.push_back(chessboard); @@ -470,7 +470,56 @@ var solveNQueens = function(n) { }; ``` +### Swift +```swift +func solveNQueens(_ n: Int) -> [[String]] { + var result = [[String]]() + // 棋盘,使用Character的二维数组,以便于更新元素 + var chessboard = [[Character]](repeating: [Character](repeating: ".", count: n), count: n) + // 检查棋盘是否符合N皇后 + func isVaild(row: Int, col: Int) -> Bool { + // 检查列 + for i in 0 ..< row { + if chessboard[i][col] == "Q" { return false } + } + + var i, j: Int + // 检查45度 + i = row - 1 + j = col - 1 + while i >= 0, j >= 0 { + if chessboard[i][j] == "Q" { return false } + i -= 1 + j -= 1 + } + // 检查135度 + i = row - 1 + j = col + 1 + while i >= 0, j < n { + if chessboard[i][j] == "Q" { return false } + i -= 1 + j += 1 + } + + return true + } + func backtracking(row: Int) { + if row == n { + result.append(chessboard.map { String($0) }) + } + + for col in 0 ..< n { + guard isVaild(row: row, col: col) else { continue } + chessboard[row][col] = "Q" // 放置皇后 + backtracking(row: row + 1) + chessboard[row][col] = "." // 回溯 + } + } + backtracking(row: 0) + return result +} +``` -----------------------
From eb721afa3527e37a702b03b15eb3fd3520b12864 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 13:55:22 +0800 Subject: [PATCH 04/14] =?UTF-8?q?0037.=E8=A7=A3=E6=95=B0=E7=8B=AC=EF=BC=9A?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8E=92=E7=89=88=EF=BC=8C=E8=A1=A5=E5=85=85?= =?UTF-8?q?Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0037.解数独.md | 51 +++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index a580f270..3d69b958 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -61,7 +61,7 @@ 代码如下: -``` +```cpp bool backtracking(vector>& board) ``` @@ -504,5 +504,54 @@ void solveSudoku(char** board, int boardSize, int* boardColSize) { } ``` +### Swift + +```swift +func solveSudoku(_ board: inout [[Character]]) { + // 判断对应格子的值是否合法 + func isValid(row: Int, col: Int, val: Character) -> Bool { + // 行中是否重复 + for i in 0 ..< 9 { + if board[row][i] == val { return false } + } + + // 列中是否重复 + for j in 0 ..< 9 { + if board[j][col] == val { return false } + } + + // 9方格内是否重复 + let startRow = row / 3 * 3 + let startCol = col / 3 * 3 + for i in startRow ..< startRow + 3 { + for j in startCol ..< startCol + 3 { + if board[i][j] == val { return false } + } + } + return true + } + + @discardableResult + func backtracking() -> Bool { + for i in 0 ..< board.count { // i:行坐标 + for j in 0 ..< board[0].count { // j:列坐标 + guard board[i][j] == "." else { continue } // 跳过已填写格子 + // 填写格子 + for val in 1 ... 9 { + let charVal = Character("\(val)") + guard isValid(row: i, col: j, val: charVal) else { continue } // 跳过不合法的 + board[i][j] = charVal // 填写 + if backtracking() { return true } + board[i][j] = "." // 回溯:擦除 + } + return false // 遍历完数字都不行 + } + } + return true // 没有不合法的,填写正确 + } + backtracking() +} +``` + -----------------------
From b2f6e0c272610e174e20e35a7cdac5195ab65ac8 Mon Sep 17 00:00:00 2001 From: Tickylime <35446132+Tickylime@users.noreply.github.com> Date: Sun, 19 Dec 2021 23:00:56 +0800 Subject: [PATCH 05/14] =?UTF-8?q?Update=200707.=E8=AE=BE=E8=AE=A1=E9=93=BE?= =?UTF-8?q?=E8=A1=A8.md?= 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 145efa18..95e90ac6 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -706,6 +706,9 @@ func (this *MyLinkedList) AddAtIndex(index int, val int) { head = head.Next index-- } + if index > 0 { + return + } node := &Node{ Val: val, //node.Next = MyLinkedList[index] From 23725675a81de764c53dafd5f02c1e9bfdcb4dd2 Mon Sep 17 00:00:00 2001 From: db <39407623+IcePigZDB@users.noreply.github.com> Date: Mon, 20 Dec 2021 15:45:51 +0800 Subject: [PATCH 06/14] =?UTF-8?q?Update=200102.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新错别字 --- problems/0102.二叉树的层序遍历.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 04b980c6..270dce6f 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -12,7 +12,7 @@ * 107.二叉树的层次遍历II * 199.二叉树的右视图 * 637.二叉树的层平均值 -* 429.N叉树的前序遍历 +* 429.N叉树的层序遍历 * 515.在每个树行中找最大值 * 116.填充每个节点的下一个右侧节点指针 * 117.填充每个节点的下一个右侧节点指针II From f6be40f9d78e1fd46a18d78c3d9ccb9edd61dbe1 Mon Sep 17 00:00:00 2001 From: mengyuan Date: Mon, 20 Dec 2021 19:44:54 +0800 Subject: [PATCH 07/14] =?UTF-8?q?update:=200376.=E6=91=86=E5=8A=A8?= =?UTF-8?q?=E5=BA=8F=E5=88=97=20js=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0376.摆动序列.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md index 3432ca53..b7293635 100644 --- a/problems/0376.摆动序列.md +++ b/problems/0376.摆动序列.md @@ -261,6 +261,7 @@ func wiggleMaxLength(nums []int) int { ``` ### Javascript +**贪心** ```Javascript var wiggleMaxLength = function(nums) { if(nums.length <= 1) return nums.length @@ -277,6 +278,25 @@ var wiggleMaxLength = function(nums) { return result }; ``` +**动态规划** +```Javascript +var wiggleMaxLength = function(nums) { + if (nums.length === 1) return 1; + // 考虑前i个数,当第i个值作为峰谷时的情况(则第i-1是峰顶) + let down = 1; + // 考虑前i个数,当第i个值作为峰顶时的情况(则第i-1是峰谷) + let up = 1; + for (let i = 1; i < nums.length; i++) { + if (nums[i] < nums[i - 1]) { + down = Math.max(up + 1, down); + } + if (nums[i] > nums[i - 1]) { + up = Math.max(down + 1, up) + } + } + return Math.max(down, up); +}; +``` -----------------------
From 7b7251f1e4bb8125c7f88030a2c93db0c0ceace3 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 13:56:43 +0800 Subject: [PATCH 08/14] =?UTF-8?q?0017.=E7=94=B5=E8=AF=9D=E5=8F=B7=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E5=AD=97=E6=AF=8D=E7=BB=84=E5=90=88=EF=BC=9A=E2=80=9C?= =?UTF-8?q?=E4=BA=8C=E4=BD=8D=E6=95=B0=E7=BB=84=E2=80=9D=20->=20=E2=80=9C?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E6=95=B0=E7=BB=84=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0017.电话号码的字母组合.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index 146493e9..7040182f 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -37,7 +37,7 @@ ## 数字和字母如何映射 -可以使用map或者定义一个二位数组,例如:string letterMap[10],来做映射,我这里定义一个二维数组,代码如下: +可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射,我这里定义一个二维数组,代码如下: ```cpp const string letterMap[10] = { From de0465b773693fa6c19a4da73a008cfa287ce812 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 14:02:02 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E5=9B=9E=E6=BA=AF=E6=80=BB=E7=BB=93?= =?UTF-8?q?=EF=BC=9A=E2=80=9C=E6=A3=8B=E7=89=8C=E2=80=9D=20->=20=E2=80=9C?= =?UTF-8?q?=E6=A3=8B=E7=9B=98=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/回溯总结.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/problems/回溯总结.md b/problems/回溯总结.md index 2fefeb04..cff41f24 100644 --- a/problems/回溯总结.md +++ b/problems/回溯总结.md @@ -331,7 +331,7 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所 在[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)中终于迎来了传说中的N皇后。 -下面我用一个3 * 3 的棋牌,将搜索过程抽象为一颗树,如图: +下面我用一个3 * 3 的棋盘,将搜索过程抽象为一颗树,如图: ![51.N皇后](https://img-blog.csdnimg.cn/20201118225433127.png) @@ -437,20 +437,5 @@ N皇后问题分析: **回溯算法系列正式结束,新的系列终将开始,录友们准备开启新的征程!** - -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - - - -----------------------
From 90aa75c57300eaa7eea9a87d268cb9b0ad8a8553 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 18:45:54 +0800 Subject: [PATCH 10/14] =?UTF-8?q?0077.=E7=BB=84=E5=90=88=E3=80=810077.?= =?UTF-8?q?=E7=BB=84=E5=90=88=E4=BC=98=E5=8C=96=EF=BC=9ASwift=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=87=8F=E5=B0=91=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0077.组合.md | 10 +++++----- problems/0077.组合优化.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/problems/0077.组合.md b/problems/0077.组合.md index 2bf856df..4ec154e1 100644 --- a/problems/0077.组合.md +++ b/problems/0077.组合.md @@ -627,7 +627,7 @@ int** combine(int n, int k, int* returnSize, int** returnColumnSizes){ func combine(_ n: Int, _ k: Int) -> [[Int]] { var path = [Int]() var result = [[Int]]() - func backtracking(_ n: Int, _ k: Int, _ startIndex: Int) { + func backtracking(start: Int) { // 结束条件,并收集结果 if path.count == k { result.append(path) @@ -638,15 +638,15 @@ func combine(_ n: Int, _ k: Int) -> [[Int]] { // let end = n // 剪枝优化 let end = n - (k - path.count) + 1 - guard startIndex <= end else { return } - for i in startIndex ... end { + guard start <= end else { return } + for i in start ... end { path.append(i) // 处理结点 - backtracking(n, k, i + 1) // 递归 + backtracking(start: i + 1) // 递归 path.removeLast() // 回溯 } } - backtracking(n, k, 1) + backtracking(start: 1) return result } ``` diff --git a/problems/0077.组合优化.md b/problems/0077.组合优化.md index b713bdcd..5fe56e82 100644 --- a/problems/0077.组合优化.md +++ b/problems/0077.组合优化.md @@ -300,7 +300,7 @@ Swift: func combine(_ n: Int, _ k: Int) -> [[Int]] { var path = [Int]() var result = [[Int]]() - func backtracking(_ n: Int, _ k: Int, _ startIndex: Int) { + func backtracking(start: Int) { // 结束条件,并收集结果 if path.count == k { result.append(path) @@ -311,15 +311,15 @@ func combine(_ n: Int, _ k: Int) -> [[Int]] { // let end = n // 剪枝优化 let end = n - (k - path.count) + 1 - guard startIndex <= end else { return } - for i in startIndex ... end { + guard start <= end else { return } + for i in start ... end { path.append(i) // 处理结点 - backtracking(n, k, i + 1) // 递归 + backtracking(start: i + 1) // 递归 path.removeLast() // 回溯 } } - backtracking(n, k, 1) + backtracking(start: 1) return result } ``` From 7c4bafe9b1d4c83a36520e3cc9c37d9c103a3651 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 20:06:04 +0800 Subject: [PATCH 11/14] =?UTF-8?q?0216.=E7=BB=84=E5=90=88=E6=80=BB=E5=92=8C?= =?UTF-8?q?III=EF=BC=9ASwift=E5=AE=9E=E7=8E=B0=E5=87=8F=E5=B0=91=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0216.组合总和III.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index a411117c..26c630b9 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -462,7 +462,7 @@ int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes){ func combinationSum3(_ count: Int, _ targetSum: Int) -> [[Int]] { var result = [[Int]]() var path = [Int]() - func backtracking(sum: Int, startIndex: Int) { + func backtracking(sum: Int, start: Int) { // 剪枝 if sum > targetSum { return } // 终止条件 @@ -474,16 +474,16 @@ func combinationSum3(_ count: Int, _ targetSum: Int) -> [[Int]] { } // 单层逻辑 - let endIndex = 9 - guard startIndex <= endIndex else { return } - for i in startIndex ... endIndex { + let end = 9 + guard start <= end else { return } + for i in start ... end { path.append(i) // 处理 - backtracking(sum: sum + i, startIndex: i + 1) + backtracking(sum: sum + i, start: i + 1) path.removeLast() // 回溯 } } - backtracking(sum: 0, startIndex: 1) + backtracking(sum: 0, start: 1) return result } ``` From 622b443bbe309d91c14693e6b2dff96fd209bbb4 Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 20:12:46 +0800 Subject: [PATCH 12/14] =?UTF-8?q?0039.=E7=BB=84=E5=90=88=E6=80=BB=E5=92=8C?= =?UTF-8?q?=EF=BC=9ASwift=E5=AE=9E=E7=8E=B0=E4=BC=98=E5=8C=96=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=91=BD=E5=90=8D=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=89=AA?= =?UTF-8?q?=E6=9E=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0039.组合总和.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index e78f2e2d..0f8fe4f6 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -455,7 +455,6 @@ func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] { var path = [Int]() func backtracking(sum: Int, startIndex: Int) { // 终止条件 - if sum > target { return } if sum == target { result.append(path) return @@ -464,8 +463,11 @@ func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] { let end = candidates.count guard startIndex < end else { return } for i in startIndex ..< end { + let sum = sum + candidates[i] // 使用局部变量隐藏回溯 + if sum > target { continue } // 剪枝 + path.append(candidates[i]) // 处理 - backtracking(sum: sum + candidates[i], startIndex: i) // sum这里用新变量完成回溯,i不用+1以重复访问 + backtracking(sum: sum, startIndex: i) // i不用+1以重复访问 path.removeLast() // 回溯 } } From 690897f33f513887c07809bd2fc158004094769c Mon Sep 17 00:00:00 2001 From: bqlin Date: Sat, 18 Dec 2021 20:23:12 +0800 Subject: [PATCH 13/14] =?UTF-8?q?0131.=E5=88=86=E5=89=B2=E5=9B=9E=E6=96=87?= =?UTF-8?q?=E4=B8=B2=EF=BC=9ASwift=E5=AE=9E=E7=8E=B0=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=E4=B8=AD=E8=B7=B3=E8=BF=87=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0131.分割回文串.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index f4d72eea..84a5bd02 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -575,12 +575,9 @@ func partition(_ s: String) -> [[String]] { for i in startIndex ..< s.count { // 回文则收集,否则跳过 - if isPalindrome(start: startIndex, end: i) { - let substring = String(s[startIndex ... i]) - path.append(substring) - } else { - continue - } + guard isPalindrome(start: startIndex, end: i) else { continue } + let substring = String(s[startIndex ... i]) + path.append(substring) // 处理 backtracking(startIndex: i + 1) // 寻找下一个起始位置的子串 if !path.isEmpty { path.removeLast() } // 回溯 } From 2a59d4fff670f89f012fdc280d662be38773b186 Mon Sep 17 00:00:00 2001 From: Martin Hsu <31008681+Martin-Hsu@users.noreply.github.com> Date: Fri, 24 Dec 2021 16:48:52 +0800 Subject: [PATCH 14/14] =?UTF-8?q?Update=200739.=E6=AF=8F=E6=97=A5=E6=B8=A9?= =?UTF-8?q?=E5=BA=A6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 簡化版可以直接i = 0開始 --- problems/0739.每日温度.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md index d16416d9..d025e73c 100644 --- a/problems/0739.每日温度.md +++ b/problems/0739.每日温度.md @@ -152,8 +152,7 @@ public: vector dailyTemperatures(vector& T) { stack st; // 递减栈 vector result(T.size(), 0); - st.push(0); - for (int i = 1; i < T.size(); i++) { + for (int i = 0; i < T.size(); i++) { while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空 result[st.top()] = i - st.top(); st.pop();