231016刷题记录
参考代码随想录来刷的
关键词:回溯、排列
1 46.全排列
力扣题目链接
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
排列和组合的区别在于,排列认为(1,2)和(2,1)是两个东西,而组合认为是一个东西。
故每轮for循环可取的值为在深度上未被取过的值。
class Solution {
private List<List<Integer>> result;
private List<Integer> path;
private int[] used;
public List<List<Integer>> permute(int[] nums) {
result = new ArrayList<>();
path = new ArrayList<>();
used = new int[nums.length];
backtracking(nums);
return result;
}
private void backtracking(int[] nums) {
if (path.size() >= nums.length) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i] != 0) continue;
path.add(nums[i]);
used[i] = 1;
backtracking(nums);
path.remove(path.size() - 1);
used[i] = 0;
}
}
}
2 47.全排列 II
力扣题目链接
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
使用哈希表去重或者先排序再判断上个取值和当前取值是否相同来去重。上一篇文章中讲过排列去重和组合去重的区别。
排列使用哈希表去重时,可不对数组排序。
class Solution {
private List<List<Integer>> result;
private List<Integer> path;
private int[] usedIndex;
public List<List<Integer>> permuteUnique(int[] nums) {
result = new ArrayList<>();
path = new ArrayList<>();
usedIndex = new int[nums.length];
backtracking(nums);
return result;
}
private void backtracking(int[] nums) {
if (path.size() >= nums.length) {
result.add(new ArrayList<>(path));
return;
}
int[] usedValue = new int[21];
for (int i = 0; i < nums.length; i++) {
// 排列
if (usedIndex[i] != 0) continue;
// 去重
if (usedValue[nums[i] + 10] != 0) continue;
usedValue[nums[i] + 10] = 1;
usedIndex[i] = 1;
path.add(nums[i]);
backtracking(nums);
path.remove(path.size() - 1);
usedIndex[i] = 0;
}
}
}
3 332.重新安排行程
力扣题目链接
给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
- 例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。
一开始想的是深度优先,一条路走到底,但这样找不全机场。在走到底之后,机场没找全时,需要回溯。
回溯图如下。
但是超时了,不知道怎么优化
class Solution {
private List<String> result;
private List<String> path;
private boolean[] used;
public List<String> findItinerary(List<List<String>> tickets) {
result = new ArrayList<>();
path = new ArrayList<>();
path.add("JFK");
used = new boolean[tickets.size()];
tickets.sort(Comparator.comparing(a -> a.get(1)));
backtracking(tickets);
return result;
}
private boolean backtracking(List<List<String>> tickets) {
if (path.size() - 1 >= tickets.size()) {
result = path;
return true;
}
for (int i = 0; i < tickets.size(); i++) {
if (!tickets.get(i).get(0).equals(path.get(path.size() - 1)) || used[i]) continue;
path.add(tickets.get(i).get(1));
used[i] = true;
if (backtracking(tickets)) return true;
used[i] = false;
path.remove(path.size() - 1);
}
return false;
}
}