leetcode 46 47 全排列2 Java

思路

46题主要是用递归的方法,从左到右遍历数组,依此将该下标和后面的数字两两交换,然后继续递归下去,并用一个变量start记录当前下标。直到start越过数组下标(nums.length())时结束。
47题主要是比46题要多一个判断重复的处理,47题的代码中比46题的只多了几行,比如对2,2,1,1,要确保第一个元素2只和1个2交换,只和1个1交换(注意它和它自己交换也算一次交换)

(参考:https://blog.csdn.net/chenchaofuck1/article/details/51194976
https://blog.csdn.net/mebiuw/article/details/51184815

代码如下:

46题

//46 领先98%以上
List<List<Integer>> res = new ArrayList<>();
	public List<List<Integer>> permute(int[] nums) {
		res.clear();
		dfs(nums, 0);//
		return res;
	}
	
	public void dfs(int[] n, int start) {//start表示要被替换元素的位置
		if( start >= n.length) {
			List<Integer> list = new ArrayList<Integer>();
			for(int i : n) {
				list.add(i);
			}
			res.add(list);
			return;
		}
		
		for(int i = start; i< n.length; i++) {//i从start开始,如果从start+1开始的话,会把当前序列遗漏掉直接保存了下一个序列
			int temp= n[i];
			n[i] = n[start];
			n[start] = temp;
			dfs(n, start + 1);//递归下一个位置
			//回到上一个状态
			n[start] = n[i];
			n[i] = temp;
		}
	}

47题

//47题 领先43%
List<List<Integer>> res = new ArrayList<>();
	public List<List<Integer>> permuteUnique(int[] nums) {
		res.clear();
		dfs2(nums, 0);//
		return res;
    }
	public void dfs2(int[] n, int start) {//start表示要被替换元素的位置
		if( start == n.length) {
			List<Integer> list = new ArrayList<Integer>();
			for(int i=0; i<n.length;i++) {
				list.add(n[i]);
			}
			res.add(list);//有重复元素时
			//可以利用下面这种方式去重,但是速度很慢
//			if( !res.contains(list)) {
//				res.add(list);
//			}
			return;
		}
		
		//如果后面有重复的元素,要确保只和最多1个1交换,最多只和1个2交换,......
		Set<Integer> set = new HashSet<Integer>();
		for(int i = start; i< n.length; i++) {//i从start开始,如果从start+1开始的话,会把当前序列遗漏掉直接保存了下一个序列
			if(set.contains(n[i])) {
				continue;
			} 
			
			set.add(n[i]);//如果不包含的话,设置访问过
			int temp= n[i];
			n[i] = n[start];
			n[start] = temp;
			dfs2(n, start + 1);//递归下一个位置
			//回到上一个状态
			n[start] = n[i];
			n[i] = temp;
		}
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值