组合总和 II

每日一练社区 2021-08-12 15:22:38

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[[1, 7],[1, 2, 5],[2, 6],[1, 1, 6]]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[[1,2,2],[5]]
...全文
754 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
空_无言 2023-05-26
  • 打赏
  • 举报
回复
还好吧,不是特别难,把每一步摸清楚就能做出来
自律且小白 2022-11-21
  • 打赏
  • 举报
回复
选出答案还是不难的。 递归,尾插,尾删,这些理解了就好办
Am_yz 2022-11-03
  • 打赏
  • 举报
回复
太难了,看不懂
亖夕 2022-08-11
  • 打赏
  • 举报
回复

这个不对?

class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (target == 0)
            return res;
        List<Integer> tmp = new ArrayList<Integer>();
        helper(candidates, target, 0, tmp, res);
        return res;
    }
public void helper(int[] a, int target, int start, List<Integer> tmp, List<List<Integer>> res) {
        if (target < 0)
            return;
        if (target == 0) {
            res.add(new ArrayList<Integer>(tmp));
            return;
        }
        for (int i = start; i < a.length; i++) {
            tmp.add(a[i]);
            int newtarget = target - a[i];
            helper(a, newtarget, i + 1, tmp, res);
            tmp.remove(tmp.size() - 1);
            if (newtarget <= 0)
                break;
            while (i + 1 < a.length && a[i] == a[i + 1])// 组合中有重复元素,不要重复开头
                i++;
        }
    }
}

  • 打赏
  • 举报
回复
麻了这题有du
Jony__Y 2022-04-20
  • 打赏
  • 举报
回复
首先递归很好玩,排序是为了递归更快退出
夙染尘 2022-03-09
  • 打赏
  • 举报
回复

传参名有问题是真的眼睛快看瞎了

米萧博 2022-03-06
  • 打赏
  • 举报
回复

有个愚见,全排列组合,不知道是不是计算量太大了



import itertools
candidates = [10,1,2,7,6,1,5]
candidates.sort()
target = 8
list1=[]
for j in range(1,len(candidates)+1):
    for i in list(itertools.combinations(candidates,j)):
        if sum(i)==target and i not in list1:
            list1.append(i)
print(list1)
青林一散修 2022-01-20
  • 打赏
  • 举报
回复
光用眼睛看可是真费劲啊
Soulic 2022-09-02
  • 举报
回复
@青林一散修 阅读理解,增强代码阅读能力,对review有帮助
jianyue--- 2021-10-13
  • 打赏
  • 举报
回复 1
#include <stdio.h> 
#include <stdlib.h>  
#define N 32 
int main(int argc,char* argv[]) 
{  
  void cbk_print(int * arr,int len);
  void mySort(int * arr,int len);
  void combine( int* data , int dataLen,int * out , int outLen ,int tag );
  int s[N]={10,1,2,7,6,1,5} , r[N]  , tag=8;
  int len= 7 ;
  
  mySort(s,len);
  printf("\n"); 
  combine(  s,len ,r,0 ,tag); 
  return 0 ; 
}

void mySort(int * arr,int len)
{
    for(int i=0 ;i<len-1 ; i++)
        for(int j=i+1 ;j<len ; j++)
        {
            if(arr[i]<arr[j])
            {
                int tmp=arr[i] ;
                arr[i]=arr[j] ;
                arr[j]=tmp ;
            }
        }
}
void cbk_print(int * arr,int len)
{
    printf("[ %d",arr[0]);
    for(int i = 1; i < len; i++) 
    {        
       printf(" , %d", arr[i]);
    }
    printf(" ]\n");
}

void combine( int* data , int dataLen,int * out , int outLen ,int tag )
{  
    for(int i = dataLen; i >0; i--)
    {
        
        int vol=data[i-1] ;
        if(i != dataLen && vol==data[i])continue ;
        if(vol==tag)
        {            
            out[outLen]=vol ;
            cbk_print(out,outLen+1) ;            
            break ;
        }
        if(vol>tag)
        {            
            break ;
        }        
        out[outLen]=vol ;                 
        combine(data , i-1,out  , outLen+1 , tag-vol);                               
    }
}

べ断桥烟雨ミ 2021-10-08
  • 打赏
  • 举报
回复 1
  1. candidates.sort()能够保证元素从小到大排序,方便进行元素搜索;
  2. dp数组用于存储构成各目标数值的所有组合的索引;
  3. 对于target == 0的情况,只可能是空集;
  4. 对于target > 0的情况,从小到大依次选择 1 个元素x,查找是否有组合方式的所有元素位于选取的元素左侧,且累加值为target - x,将x添加刀组合末尾,构成满足元素综合为target的新组合方式;
  5. dp中组合方式的索引值转换为实际元素值,用字典进行去重。
class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        candidates.sort()
        dp = [[] for _ in range(target + 1)]
        dp[0].append([])
        for i in range(1, target + 1):
            for j in range(len(candidates)):
                if candidates[j] > i:
                    break
                for k in range(len(dp[i - candidates[j]])):
                    temp = dp[i - candidates[j]][k][:]
                    if len(temp) > 0 and temp[-1] >= j:
                        continue
                    temp.append(j)
                    dp[i].append(temp)
        res = []
        check = {}
        for temp in dp[target]:
            value = [candidates[t] for t in temp]
            try:
                check[str(value)] += 1
            except KeyError:
                check[str(value)] = 1
                res.append(value)
        return res
圣☆哥 2021-09-23
  • 打赏
  • 举报
回复

通过try-except进行解集去重时,check[str(value)] /= 1check[str(value)] %= 1等等应该也对吧。

几何螃蟹 2021-09-16
  • 打赏
  • 举报
回复
这ABCD选的是个寂寞,是在考for循环的条件吗…
  • 打赏
  • 举报
回复

回溯算法解决

A3181521 2021-08-12
  • 打赏
  • 举报
回复

假的吧

11,201

社区成员

发帖
与我相关
我的任务
社区描述
Study well and make progress every day
其他 企业社区
社区管理员
  • 每日一练社区
  • CSDN学习
  • 幻灰龙
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧