全排列
46. 全排列
给定一个不含重复数字的数组 nums,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
# 输入: nums = [1, 2, 3]# 输出: [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]class Solution:def permute(self, nums):result_all = []visited = [0] * len(nums)def dfs(n, nums, result):if n == len(nums):result_all.append(result[:])for i in range(len(nums)):if visited[i] == 1:continueresult.append(nums[i])visited[i] = 1dfs(n+1, nums, result)result.pop()visited[i] = 0dfs(0, nums, [])return result_all
47. 全排列 II
给定一个可包含重复数字的序列 nums,按任意顺序 返回所有不重复的全排列。
# 输入: nums = [1, 1, 2]# 输出: [[1, 1, 2], [1, 2, 1], [2, 1, 1]]class Solution:def permuteUnique(self, nums):result_all = []visited = [0] * len(nums)nums.sort()def dfs(n, nums, result):if n == len(nums):result_all.append(result[:])for i in range(len(nums)):if visited[i] == 1:continueif i > 0 and nums[i] == nums[i-1] and visited[i-1]==0:continueresult.append(nums[i])visited[i] = 1dfs(n+1, nums, result)result.pop()visited[i] = 0dfs(0, nums, [])return result_all
组合总和
39. 组合总和
给定一个无重复元素的正整数数组 candidates 和一个正整数 target,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
# 输入: candidates = [2, 3, 6, 7], target = 7# 输出: [[7], [2, 2, 3]]class Solution:def combinationSum(self, candidates, target):result_all = []def dfs(n, nums, result, start_id, target):if target == 0:result_all.append(result[:])for i in range(start_id, len(nums)):if nums[i] > target:continueresult.append(nums[i])dfs(n+1, nums, result, i, target-nums[i])result.pop()dfs(0, candidates, [], 0, target)return result_all
40. 组合总和 II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。
# 输入: candidates = [2, 5, 2, 1, 2], target = 5# 输出: [[1, 2, 2], [5]]class Solution:def combinationSum2(self, candidates, target):result_all = []visited = [0] * len(candidates)candidates.sort()def dfs(n, nums, result, target, start_id):if target == 0:result_all.append(result[:])for i in range(start_id, len(nums)):if visited[i] == 1:continueif nums[i] > target:continueif i>0 and nums[i]==nums[i-1] and visited[i-1]==0:continueresult.append(nums[i])visited[i] = 1dfs(n+1, nums, result, target-nums[i], i)result.pop()visited[i] = 0dfs(0, candidates, [], target, 0)return result_all
216. 组合总和 III
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
- 所有数字都是正整数。
解集不能包含重复的组合。
# 输入: k = 3, n = 7# 输出: [[1, 2, 6], [1, 3, 5], [2, 3, 4]]class Solution:def combinationSum3(self, k, n):result_all = []visited = [0] * 9def dfs(_n, result, target, start_id):if target == 0 and len(result)==k:result_all.append(result[:])for i in range(start_id, 9):if visited[i] == 1:continueif (i+1) > target:continueif len(result) > k:continueresult.append(i+1)visited[i] = 1dfs(_n+1, result, target-(i+1), i)result.pop()visited[i] = 0dfs(0, [], n, 0)return result_all
深度优先搜索
class Solution:def exist(self, board: List[List[str]], word: str) -> bool:m, n = len(board), len(board[0])directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]visited = set()def dfs(i, j, k):if board[i][j] != word[k]: # 不匹配return Falseif k == len(word)-1:return Truevisited.add((i, j))result = Falsefor di, dj in directions:newi, newj = i+di, j+djif 0 <= newi < len(board) and 0 <= newj < len(board[0]): # 不越界if (newi, newj) not in visited: # 未访问if dfs(newi, newj, k+1):result = Truebreakvisited.remove((i, j))return resultfor _m in range(m):for _n in range(n):if dfs(_m, _n, 0):return Truereturn False
