“持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情”
前言
之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两台晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还会给刷的题总结下,谈谈自己的一些思考,和自己的思路等等,希望对小伙伴能有所帮助吧,也可以借此机会把自己短板补一补,希望自己能坚持下去呀
- 六六力扣刷题回溯之combinations(组合
- 六六力扣刷题回溯之组合总和
- 六六力扣刷题回溯之电话号码的字母组合
- 六六力扣刷题回溯之分割回文串
- 六六力扣刷题回溯之复原 IP 地址
- 六六力扣刷题回溯之子集
- 六六力扣刷题回溯之子集2
题目
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
输入: nums = [1,2,3]
输出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
复制代码
输入: nums = [0,1]
输出: [[0,1],[1,0]]
复制代码
题解
package com.six.finger.leetcode.five;
/*
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
*/
import java.util.ArrayList;
import java.util.List;
public class twentyone {
public static void main(String[] args) {
int[] nums={1,2,3};
List<List<Integer>> permute = permute(nums);
System.out.println(permute);
}
public static List<List<Integer>> permute(int[] nums) {
//先判断临界条件
if (nums.length == 0) {
return new ArrayList<>();
}
//设置一个返回值
List<List<Integer>> res = new ArrayList<>();
//设置我们存储路径的path
List<Integer> path = new ArrayList<>();
//存放使用的过程
boolean[] used = new boolean[nums.length];
//回溯函数
backtracking(res, path, used, nums);
return res;
}
private static void backtracking(List<List<Integer>> res, List<Integer> path, boolean[] used, int[] nums) {
//判断退出条件
if (path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
//回溯函数
for (int i = 0; i < nums.length; i++) {
//先判断
if (used[i]) {
continue;
}
path.add(nums[i]);
used[i] = true;
backtracking(res, path, used, nums);
path.remove(path.size() - 1);
used[i] = false;
}
}
}
复制代码
解题模版
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
复制代码
- 第一步 先判断临界条件
- 第二步 设置一个返回值
- 第三步 存放我们使用过的路径,可以用boolean[] 也可以用一个map
- 第四步,写回溯函数backtracking
- 第五步,回溯的终止条件
- 第六步,循环树的宽度
- 第七步,判断当前剩余的节点使用情况,然后把它加入到path中
- 第八步,继续遍历树的深度,
- 第九步,遍历到最低处,然后往回做减法,之前做了啥,现在往反向做
结束
今天就这么多了,回溯就写这么多了,下次换个算法写了,好了 我是小六六,三天打鱼,两天晒网!