【LEETCODE】模拟面试-46. Permutations
notice:
if ( curList.contains(arr[i]) ){
continue;
}
记忆点: 看解释图中的三层树: 每一层,是for实现的,可以看到是从头扫到尾,已经有了就不要了 层与层之间,是靠recursion传递current path,一个数一个数加的 notice:每一次跳出时,要删去最后一个元素
图:新生大学
https://leetcode.com/problems/permutations/
Given a collection of distinct numbers, return all possible permutations.
For example, [1,2,3] have the following permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
input: given an array output: it's to return all the permutations of this array corner: when the array is null or its length is zero
Based on the question, we can build a solution tree, where at the root, we have n = arr.length
choices, then the second level we have n - 1
choices, then continue with decreasing one at each level.
Then we can use DFS algorithm to traverse the solution tree.
We need a list of list
to store the final permutations, and a current list
to track the current path.
例如,[1,2,3]这个例子, 可以画出如左边树状组成的解空间。
具体需要current list来储存每一条path, 当path内部元素达到和给定array一样长时,就可以把它加入到res中。
跑个test case就是,从index=0开始遍历, current list可以先装入1, 然后进入下一层,先check了现在path里面已经有了1,所以加入2, 再一次进入下一层,check之后,这时能加的只有3了, 此时长度=array的length,可以加入到res,并且返回。 返回后,current list需要remove掉最后一位,因为要为下一个情况让座。
这样就可以写出recursion的函数: base case就是当长度等于array.length时返回。 current level要做的就是从0扫到length-1, 先check当前path中是否包含此元素,包含则跳过,否则加入到path, 加完一个之后,进入next level加入下一个元素, 直到每一个path都完成后返回, 返回后要remove掉最后一个位置。
Before we add a new number into the path, firstly is to check whether it's already in the list, if yes, we ignore this number, and move to next one, if no, add it.
For each single path, we will go through root to leaf node. When the path has finished iterating all the numbers and return to the upper level, it will first delete the last number in the path, so that the curList
can add new nodes.
Time: O(n! * n) ( n!: solutions #, n: from curList.contains(arr[i])
)
Space: O(n) ( n: curList
without considering result and recursion stack )
public class Solution{
public List<List<Integer>> permutations(int[] arr){
List<List<Integer>> res = new ArrayList<List<Integer>>();
//corner
if ( arr == null || arr.length == 0 ){
return res;
}
//core
List<Integer> curList = new ArrayList<>();
helper(res, curList, arr);
return res;
}
public void helper(List<List<Integer>> res, List<Integer> curList, int[] arr){
//base
if ( curList.size() == arr.length ){
res.add(new ArrayList<Integer>(curList));
return ;
}
//current
for ( int i = 0; i < arr.length; i++ ){
if ( curList.contains(arr[i]) ){
continue;
}
curList.add(arr[i]);
//next
helper(res, curList, arr);
curList.remove(curList.size() - 1);
}
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 2020-09-20:如何判断一个数是质数?
- 金九银十Android面试复习题集:关于四大组件中的Activity你了解多少?
- HaseMap的循环姿势你真的懂了吗?
- 历经14天自定义3个注解解决项目的3个Swagger难题
- VUE开发–获取DOM对象和组件对象(十九)
- RASP攻防 —— RASP安全应用与局限性浅析
- JavaScript 交换值的奇思妙想
- Docker体验(一)
- (二)Hadoop集群配置安装
- 压缩视频
- (四)Java读写文件,合并成新的文件
- 【小白学金融】—— 用 STATA 计算 CAR 值
- 3行核心CSS代码的rate评分组件,秀到你怀疑人生
- 用 Rust 和 N-API 开发高性能 NodeJS 扩展
- 教你 Linux 免密登录配置