LeetCode90:子集II深搜回溯剪枝法

修改注意点:
1、下面每次递归中变元now是代表要确定第几个位置,循环中的i代表这个位置选择哪一个元素。每次递归下去,要为i+1不是now+1.因为要从当前选择的元素开始往下选
2、有重复元素会出现相同的子集
解决办法:剪枝
策略:
先将数组进行排序,排好之后重复元素就会聚集在一起。在进行回溯的时候,循环过程中判断这个元素是否和前面一个元素相同,相同代表这个位置,此元素已经被选择过,不再选择,跳过。
注意:i=now是这个位置选择的第一个元素,不用和前面的进行判断,因为这个位置还没有选择过

代码:

package com.LeetCode1.Array;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
 * 修改1:now和i
 * 修改2:解决有重复元素中出现重复子集问题
 *
 */
public class leet90_t {
	static List<List<Integer>> ans = new LinkedList<List<Integer>>();
	public static void main(String[] args) {
		int[] nums = {4,4,4,1,4};
		subsetsWithDup(nums);
		for(int i=0;i<ans.size();i++)
		{
			List<Integer> l = ans.get(i);
			for(int j=0;j<l.size();j++)
			{
				System.out.print(l.get(j)+" ");
			}
			System.out.println();
		}
	}
	    public static List<List<Integer>> subsetsWithDup(int[] nums) {
	    	Arrays.sort(nums);
			for(int i=0;i<nums.length+1;i++)
			{
				backtrace(i,0,new ArrayList<Integer>(),nums);
			}
			return ans;
	    }
	    public static void backtrace(int k, int now, ArrayList<Integer> l, int[] nums) {
			if(k==now)
			{
				if(ans.contains(l)) return;
				ans.add(new ArrayList<Integer>(l));//注意此处,此处不是直接加入l,l是空的,需要按l新建一个List
				return ;
			}
			for(int i=now;i<nums.length;i++)
			{
				if(i!=now&&nums[i]==nums[i-1]) continue;//关键点,大致意思:在选择的时候,如果这次以now开头的循环中,选择了与这个元素相同的元素,就不选择了
				//每次循环的含义:now是选第几个元素,循环是从第几个元素开始往后选,每个位置的元素不能选择重复
				l.add(nums[i]);
				backtrace(k, i+1, l, nums);//此处是i+1不是now+1
				l.remove(l.size()-1);
			}
	    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值