首页 > 其他分享 >剑指offer82:含有重复元素集合的组合

剑指offer82:含有重复元素集合的组合

时间:2022-12-13 11:33:52浏览次数:41  
标签:数字 组合 nums 重复 combination offer82 int 集合 target


题目:
给定一个可能有重复数字的整数数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次,解集不能包含重复的组合。
1.输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
2.输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
分析:
该题和之前几题的很大不同点在于输入的集合中有重复的数字但是输出不得包含重复的组合,如果输入的集合中有重复的数字,不经过特殊处理将产生重复的组合,例如,从集合[2,2,2]中选出2个数字本来能组成3个组合,但3个组合都是[2,2],因此它们是重复的组合,在该题中只能算1个。另外,组合不考虑数字的顺序,比如[2,2,4],[2,4,2],[4,2,2]只能算一个组合。、
该题思路的关键点:避免重复的组合的方法是当在某一步决定跳过某个值为m的数字时,跳过所有值为m的数字,例如,假设求[2,2,2]的组合,如果在处理第1个2时决定跳过它并跳过所有的2,那么得到的是一个空的组合,如果选择第1个2之后决定跳过第2个2并跳过后面的2,那么得到的是组合[2]。如果选择前两个2之后决定跳过第3个2,那么得到的是组合[2,2]。如果3个2都被选择,则得到组合[2,2,2]。采用这种方法则可避免两种产生重复组合[2,2]的情形。
为了方便跳过后面的所有值相同的数字,可以将集合中所有的数字排序,把相同的数字放在一起,这样更加方便比较数字,当决定跳过某个值的数字时,可以按顺序扫描后面的数字,直到找到不同的值为止。

代码:

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class CombinationSum2 {
public static void main(String[] args) {
CombinationSum2 combinationSum2 = new CombinationSum2();
int[] nums = {2,2,2,4,3,3};
List<List<Integer>> lists = combinationSum2.combinationSum2(nums, 8);
System.out.println(lists);
}
public List<List<Integer>> combinationSum2(int[] nums, int target) {
// 排序是为了方便跳过相同的数字
Arrays.sort(nums);
List<List<Integer>> result = new LinkedList<>();
LinkedList<Integer> combination = new LinkedList<>();
helper(nums,target,0,combination,result);
return result;
}

private void helper(int[] nums, int target, int i, LinkedList<Integer> combination, List<List<Integer>> result) {
if (target == 0){
result.add(new LinkedList<>(combination));
}else if (target>0 && i<nums.length){
helper(nums,target,getNext(nums,i),combination,result);
combination.addLast(nums[i]);
helper(nums,target-nums[i],i+1,combination,result);
combination.removeLast();
}
}
//当决定跳过数字nums[i]时可以调用函数getNext找到与该数字不同的下一个数字。
private int getNext(int[] nums, int index) {
int next = index;
while (next < nums.length && nums[next] == nums[index]){
next++;
}
return next;
}
}

剑指offer82:含有重复元素集合的组合_回溯


标签:数字,组合,nums,重复,combination,offer82,int,集合,target
From: https://blog.51cto.com/u_15911055/5933494

相关文章

  • 剑指offer81:允许重复选择元素的组合
    题目:给定一个无重复元素的正整数数组candidates和一个正整数target,找出candidates中所有可以使数字和为目标数target的唯一组合。candidates中的数字可以无限制......
  • 剑指offer84:包含重复元素集合的全排列
    题目:给定一个可包含重复数字的整数集合nums,按任意顺序返回它所有不重复的全排列。1.输入:nums=[1,1,2]输出:[[1,1,2],[1,2,1],[2,1,1]]2.输入:nums=[1,2,3]输出......
  • 分布式系统接口,如何避免表单的重复提交?
    关于怎么实现承载更多用户量的系统,一直是我重点关注的一个技术方向。改造架构提高承载力,通常来讲分为两个大方向,互相配合实现。硬件架构改进,主要是使用阿里云这种多组件的......
  • 力扣182(MySQL)-查找重复的电子邮箱(简单)
    题目:编写一个SQL查询,查找 Person 表中所有重复的电子邮箱。示例: 解题思路:方法一:使用groupby按Email来分组,然后使用having选择count(id)>1的就可以得到重复的Em......
  • 剑指offer 字符流中第一个不重复的字符(思维,队列)
    题目描述请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“g......
  • 面试之集合整理——重点 Map & List
    一,集合框架图二,遍历方式,及常用方法。map:packagecom.HashMap_Demo;importjava.util.Collections;importjava.util.HashMap;importjava.util.Iterator;importjava.util.......
  • 集合之斗地主案例
    1packagecom.Lucky.AppUnit;23/**4*开启App入口5*/6publicclassApp{7publicstaticvoidmain(String[]args){8//newstart......
  • 集合之Map【TreeMap】
    packagecom.Lucky.Map;importjava.util.Comparator;importjava.util.TreeMap;/*TreeMap:底层结构和TreeSet一样是红黑树可以排序/无重......
  • 集合之Map
    packagecom.Lucky.Map;importjava.util.HashMap;importjava.util.Map;/*map接口:无法new,只能new他的实现类*/publicclassMapDemo{publicstat......
  • 集合之Map【HashMap】
    packagecom.Lucky.Map;importjava.util.Iterator;importjava.util.Map;importjava.util.Set;importjava.util.function.BiConsumer;/*HashMap:1.底......