写在前面
例题
leetcode46 全排列
答题链接:https://leetcode-cn.com/problems/permutations/
题目描述:给定一个没有重复数字的序列,返回其所有可能的全排列。
python实现
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(nums: list, flag: list, tempList: list, ret):
'''
params nums: 给定输入数字序列
params flag: 该次dfs时还未使用的数字
params tempList: 该次dfs时输入数组
params ret: 最终输出全排列结果
'''
if len(tempList) == len(nums): #遍历到底时, 将该列表加入结果
ret.append(tempList[:]) # 可以试试直接将tempList放入ret, 查看结果
return
for i in range(len(nums)):
if flag[i]: # 如果该数字还未被使用
tempList.append(nums[i]) # 将该数字加入临时数组
flag[i] = False # 该数字已经使用
dfs(nums, flag, tempList, ret) # 递归调用
flag[i] = True # 回溯
tempList.pop() # 回溯
flag = [True] * len(nums)
ret = []
dfs(nums, flag, [], ret)
return ret
Java实现
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ret = new LinkedList<>();
List<Integer> tempList = new LinkedList<>();
boolean[] flag = new boolean[nums.length];
Arrays.fill(flag, true);
dfs(nums, flag, tempList, ret);
return ret;
}
public void dfs(int[] nums, boolean[] flag, List<Integer> tempList, List<List<Integer>> ret) {
if (nums.length == tempList.size()) {
ret.add(new LinkedList<>(tempList));
}
for (int i = 0; i < nums.length; i++) {
if (flag[i]) {
tempList.add(nums[i]);
flag[i] = false;
dfs(nums, flag, tempList, ret);
flag[i] = true;
tempList.remove(tempList.size() - 1);
}
}
}
}
leetcode47 全排列2
答题链接:https://leetcode-cn.com/problems/permutations-ii/
题目描述:给定一个可包含重复数字的序列 nums ,按任意顺序返回所有不重复的全排列。
相比于上一题,该题增加了包含重复数字的条件,那么结果中会增加重复的序列。因此可以在结果中将相同的排列删除;或者在每次dfs枚举位置时进行剪枝处理,判断该数字是否被枚举过,如果枚举过则不必再进行dfs。
Java实现
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> ret = new LinkedList<>();
List<Integer> tempList = new LinkedList<>();
boolean[] flag = new boolean[nums.length];
Arrays.fill(flag, true);
dfs(nums, flag, tempList, ret);
return ret;
}
public void dfs(int[] nums, boolean[] flag, List<Integer> tempList, List<List<Integer>> ret) {
if (nums.length == tempList.size()) {
ret.add(new LinkedList<>(tempList));
return;
}
Set<Integer> numSet = new HashSet<>(); //使用集来存储该位置枚举过的数字
for (int i = 0; i < nums.length; i++) {
if (flag[i] && !numSet.contains(nums[i])) { // 如果该位置没被枚举过且该数字没被枚举过
flag[i] = false;
tempList.add(nums[i]);
numSet.add(nums[i]);
dfs(nums, flag, tempList, ret);
flag[i] = true;
tempList.remove(tempList.size() - 1);
}
}
}
}
leetcode39 组合总和
答题链接:https://leetcode-cn.com/problems/combination-sum/
题目描述:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
python实现
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates: list, tempList: list, numSum: int, ret, index: int):
if numSum == target:
ret.append(tempList[:])
return
for i in range(index, len(candidates)):
if numSum + candidates[i] <= target:
tempList.append(candidates[i])
numSum += candidates[i]
dfs(candidates, tempList, numSum, ret, i)
numSum -= candidates[i]
tempList.pop()
else:
break
candidates.sort() # 先排序方便剪枝
ret = []
dfs(candidates, [], 0, ret, 0)
return ret
Java实现
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ret = new LinkedList<>();
List<Integer> tempList = new LinkedList<>();
Arrays.sort(candidates);
dfs(candidates, tempList, 0, ret, 0, target);
return ret;
}
public void dfs(int[] candidates, List<Integer> tempList, int tempSum, List<List<Integer>> ret, int index, int target) {
if (tempSum == target) {
ret.add(new LinkedList<>(tempList));
return;
}
for (int i = index; i < candidates.length; i++) {
tempSum += candidates[i];
if (tempSum <= target) {
tempList.add(candidates[i]);
dfs(candidates, tempList, tempSum, ret, i, target);
tempList.remove(tempList.size() - 1);
tempSum -= candidates[i];
} else {
break;
}
}
}
}
leetcode40 组合总和2
答题链接:https://leetcode-cn.com/problems/combination-sum-ii/
题目描述:给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates, tempList, tempSum, index, ret):
if tempSum == target:
ret.append(tempList[:])
return
numSet = set()
for i in range(index, len(candidates)):
if tempSum + candidates[i] <= target and candidates[i] not in numSet:
tempSum += candidates[i]
tempList.append(candidates[i])
numSet.add(candidates[i])
dfs(candidates, tempList, tempSum, i+1, ret)
tempSum -= candidates[i]
tempList.pop()
elif tempSum + candidates[i] > target:
break
else:
continue
candidates.sort()
ret = []
dfs(candidates, [], 0, 0, ret)
return ret