LeetCode47 全排列2

LeetCode47 全排列2

方法:回溯法(深度优先搜索dfs+状态重置)+剪枝

关键点:剪枝(去重)
1、候选数组排序
2、通过该位置的重复元素nums[i-1]是否使用过(used[i-1]),如果used[i-1]=false,则结果重复,去重(continue)

    public List<List<Integer>> permuteUnique(int[] num) {
		Arrays.sort(num);                      //保证数组重复元素在一块,方便去重 ,所以通过排序的方式来实现它
        int len = num.length;
		boolean[] vis = new boolean[len];
		List<List<Integer>> res =new ArrayList<List<Integer>>();
		ArrayList<Integer> temp = new ArrayList<Integer>();
		dfs(num, len, temp, vis, res);
		return res;
	}
	public void dfs(int[] num,int len,ArrayList<Integer> temp,boolean[] vis,List<List<Integer>> res) {			
		if(temp.size() == len ) {              //递归结束条件
			res.add(new ArrayList<Integer>(temp));
			return;
		}
		for(int i = 0; i < num.length; i++) {  //确定该位置放那个元素
			if(!vis[i]){
                if(i>0 && num[i] == num[i-1] && !vis[i-1]) continue;    //减枝;当执行相同元素后者时,若前一个相同元素没有被使用,则将这个位置是该元素的所有可能性给continue掉(前一个元素被使用,说明是首次的情况,若没被使用,则不是首次出现重复)
				temp.add(num[i]);
				vis[i] = true;
				dfs(num, len, temp, vis,res);  //递归,确定位置(操纵位置(深度))				
				vis[i] = false;                //状态重置,恢复该位置元素可用性
				temp.remove(temp.size()-1);    //回溯    
			}
		}		
	}

时间复杂度:O(n!+nlogn) ; 因为数组排序+dfs
空间复杂度:O(3len) ; res+temp+used

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值