楠君的小窝
对于回溯的一些理解
个人感觉回溯与递归其实是差不多的,递归是由上到下的,而回溯是由下而上的。 回溯在部分题能变成记忆化搜索如果再得出递推公式就能变成DP(动态规划)了。 回溯主要的几个难点就在于剪枝 树层剪枝、树枝剪枝 数层剪枝我一般都是在每一层中使用一个哈希表,而树枝剪枝类似于有长度限制之类的,可以提前return 这段时间我的码力也是直线上升了,感觉到自己实力在不断的增长,我还自己做了一个小项目。 DataStructView相信不久就能做好
LC37. 解数独
解题思路 代码 Python 123456789101112131415161718192021222324252627282930313233class Solution: def solveSudoku(self, board: List[List[str]]) -> None: def dfs(pos: int): nonlocal valid if pos == len(spaces): valid = True return i, j = spaces[pos] for digit in range(9): if line[i][digit] == column[j][digit] == block[i // 3][j // 3][digit] == False: line[i][digit] = column[j ...
LC51. N 皇后
解题思路 首先我们可以确定一下回溯传入值 backtracking(row: int, uMap: defaultdict(int), path:list[str]) 这里row是行的意思,我们传入行不断的增加以达到每个皇后不在同一行上 uMap中key是col,value是row。 计算斜角是否在攻击范围内就是当前的row - preRow == col - preCol 代码 Python 123456789101112131415161718192021222324252627class Solution: def solveNQueens(self, n: int) -> List[List[str]]: result = [] def backtracking(row: int, umap:defaultdict(int), path:list[str]): if row == n: result.append(path.copy()) r ...
LC491. 递增子序列
解题思路 题目要求子序列至少2个元素且递增,那么我们添加条件可以是当path中有两个元素的时候 使用哈希表记录当前层使用过的元素,若再次碰到直接continue 当nums[i] < path的最后一个元素时则continue 代码 Python 12345678910111213141516171819class Solution: def findSubsequences(self, nums: List[int]) -> List[List[int]]: result = [] def backtracking(startIndex: int, path: list[int]) -> None: if len(path) >= 2: result.append(path.copy()) uset = set() for i in range(startIndex, len(nums)): ...
LC90. 子集 II
解题思路 与子集(LC79)不同的是数组中有重复的元素,题目要求我们的解集中不包含重复子集,有两种解法。 哈希表 排序 代码 Python 1234567891011121314151617class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.sort() result = [[]] def dfs(startIndex: int, path: list[int]): if startIndex == len(nums): return for i in range(startIndex, len(nums)): if i > startIndex and nums[i - 1] == nums[i]: continue path.append(nums[i]) result.ap ...
LC78. 子集
解题思路 将nums数组所有子集添加进去就行 代码 Python 1234567891011121314class Solution: def subsets(self, nums: List[int]) -> List[List[int]]: result = [[]] def dfs(startIndex: int, temp: list[int]): if startIndex == len(nums): return for i in range(startIndex, len(nums)): temp.append(nums[i]) result.append(temp.copy()) dfs(i + 1, temp) temp.pop() dfs(0, []) return result C++ 12345 ...
LC93. 复原 IP 地址
解题思路 这题考点就是剪枝 如果找到了 4 段 IP 地址并且遍历完了字符串,那么就是一种答案 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0 代码 Python 12345678910111213141516171819202122class Solution: def restoreIpAddresses(self, s: str) -> List[str]: # 4 * 3 = 12 if len(s) > 12: return [] result = [] def backtracking(startIndex: int, temp: list[str]): if len(temp) == 4: if startIndex >= len(s): result.append(".".j ...
LC131. 分割回文串
解题思路 首先需要一个check函数用来验证字符串是否为回文串,这里check我们选用双指针。 从下标0开始不断查找回文串,当下标到达s长度时添加进result 代码 Python 1234567891011121314151617181920212223242526class Solution: def partition(self, s: str) -> List[List[str]]: result = [] def check(s: str): l, r = 0, len(s) - 1 while l <= r: if s[l] != s[r]: return False l += 1 r -= 1 return True def backtracking(temp: list[str], start: int): if start == le ...
LC40. 组合总和 II
解题思路 这题与组合总和(LC39)的区别在于给的candidates中有重复的元素,题目要求每个数字在一个组合中只能使用一次,那么这里有两种方法,第一种就是直接使用哈希表记录元素,第二种则比较简单,使用startIndex,由于candidates在开始已经被排序了,那么只要 i > startIndex 且 nums[i] == nums[i - 1]时可以直接continue避免使用重复元素 代码 Python 1234567891011121314151617181920class Solution: def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: candidates.sort() answer = [] temp = [] def backtracking(start: int, s: int): if s == target: ...
LC39. 组合总和
解题思路 这题就是排序直接使用回溯,考点可能就是几个剪枝的地方。 当总和 > target时 代码 Python 1234567891011121314151617class Solution: def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: answer = [] def backtracking(start: int, temp: list[int], s: int): if s == target: answer.append(temp.copy()) return for i in range(start, len(candidates)): if s + candidates[i] > target: return temp.append(cand ...
LC216. 组合总和 III
解题思路 就是按照题目要求从1开始遍历到9,当发现可以数组内的和达到n时就添加至result,若数组长度超过k则回溯。 代码 Python 123456789101112131415161718class Solution: def combinationSum3(self, k: int, n: int) -> List[List[int]]: ans = [] temp = [] def backtracking(num, s): nonlocal temp if len(temp) == k and s == n: ans.append(temp.copy()) elif len(temp) == k: return elif s > n: return for number in range(num, 10): temp.app ...
LC47. 全排列 II
解题思路 这题大概的代码与全排列(LC46)差不多,它们的区别是给定的nums中包含重复的元素,那么我们在遍历的时候要记录当前这层是否已经使用过某个元素了,如果已经使用过了则跳过。同样使用的是哈希表,不过这次记录的不是下标而是元素值。 代码 Python 123class Solution: def permuteUnique(self, nums: List[int]) -> List[List[int]]: return list(set(permutations(nums))) C++ 123456789101112131415161718192021222324252627282930class Solution { vector<int> vis;public: void backtrack(vector<int>& nums, vector<vector<int>>& ans, int idx, vector<int>& perm) { ...
avatar
🐟认真摸鱼中
楠君的小窝
Live is so good
前往小窝
公告栏
--- 主域名 ---
fomal.cc | fomal.cn
--- 备用域名 ---
netlify.fomal.cc
cloudflare.fomal.cc
--- 网站安卓APP ---
🍧点此下载🍧
小站资讯
文章数目 :
111
本站总字数 :
6.3w
本站访客数 :
本站总访问量 :
最后更新时间 :
空降评论复制本文地址
随便逛逛昼夜切换关于博客美化设置切换全屏打印页面