permutations
前阵子阴差阳错给华为的HR提交了联系方式,今天竟然通知我参加机试,心想正好趁这个机会感受一下华为的难度,于是就参加了。
机试时间1.5h,只有一道题,便是全排列问题。和leetcode第46题的一些小区别在于:
示例:
输入:3
输出:[123,132,213,231,312,321]
因为练习得比较少,这道题发挥得不是很好,不过也为自己提了个醒——如果针对大厂的笔试,常见的经典算法的确应该掌握到位。这里paste一下leetcode46题的题解,放在这里以供后面重新温习。
题目描述
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
package pid46;
import java.util.List;
import java.util.ArrayList;
public class Solution {
public static List<List<Integer>> permute(int[] nums){
List<List<Integer>> res = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
backtrack(res,nums,new ArrayList<Integer>(),visited);
return res;
}
public static void backtrack(List<List<Integer>> res,int[] nums,ArrayList<Integer>tmp,boolean[] visited){
if(tmp.size() == nums.length){
//完成了一个全排列,将其添加到所有全排列的集合中去
res.add(new ArrayList<>(tmp));
return;
}
//否则说明本次全排列还没完成,进行全排列
for(int i=0;i<nums.length;i++){
if(visited[i] == true){
continue;
}else{
visited[i] = true;
tmp.add(nums[i]);
/*
* 对剩余位置进行全排列,排列时哪些元素可以用,哪些不可以用,参照的是visited表
*/
backtrack(res,nums,tmp,visited);//visited与nums数组形成映射
visited[i] = false;//即将回退了,下标为i的元素在后面的位置上还可以继续使用
tmp.remove(tmp.size()-1);//回溯
}
}
}
public static void main(String[] args) {
int[] nums = {1,2,3};
List<List<Integer>> list = permute(nums);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
附一篇参考文档:https://www.jianshu.com/p/9c1885ef0cb7
今天重新写了一下这道题:
package pid46;
import java.util.List;
import java.util.LinkedList;
public class Solution {
public List<List<Integer>> permute(int[] nums){
List<List<Integer>> res = new LinkedList<>();
List<Integer> track = new LinkedList<>();
backtrack(nums,res,track);
return res;
}
public void backtrack(int[] nums,List<List<Integer>> res,List<Integer> track){
if(track.size() == nums.length){
res.add(new LinkedList<>(track));
}
for(int i=0;i<nums.length;i++){
if(track.contains(nums[i])){
continue;
}
track.add(nums[i]);
backtrack(nums,res,track);
// 回退
track.remove(track.size()-1);
}
}
}