当前位置: 首页 > article >正文

【Leetcode 每日一题】40. 组合总和 II

问题背景

给定一个候选人编号的集合 c a n d i d a t e s candidates candidates 和一个目标数 t a r g e t target target,找出 c a n d i d a t e s candidates candidates 中所有可以使数字和为 t a r g e t target target 的组合。
c a n d i d a t e s candidates candidates 中的每个数字在每个组合中只能使用 一次
注意:解集不能包含重复的组合。

数据约束

  • 1 ≤ c a n d i d a t e s . l e n g t h ≤ 100 1 \le candidates.length \le 100 1candidates.length100
  • 1 ≤ c a n d i d a t e s [ i ] ≤ 50 1 \le candidates[i] \le 50 1candidates[i]50
  • 1 ≤ t a r g e t ≤ 30 1 \le target \le 30 1target30

解题过程

算是回溯的例题,由于结果不能重复,要先将数组进行排序,方便在过程中跳已经处理过的相等元素。

具体实现

递归

class Solution {

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(0, target, candidates, res, path);
        return res;
    }

    private void dfs(int i, int target, int[] candidates, List<List<Integer>> res, List<Integer> path) {
        if(target == 0) {
            res.add(new ArrayList(path));
            return;
        }
        if(i == candidates.length) {
            return;
        }
        int cur = candidates[i];
        if(target < cur) {
            return;
        }
        path.add(cur);
        dfs(i + 1, target - cur, candidates, res, path);
        path.remove(path.size() - 1);
        i++;
        while(i < candidates.length && candidates[i] == cur) {
            i++;
        }
        dfs(i, target, candidates, res, path);
    }
}

递推

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(0, target, candidates, res, path);
        return res;
    }

    private void dfs(int i, int target, int[] candidates, List<List<Integer>> res, List<Integer> path) {
        if(target == 0) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int j = i; j < candidates.length && candidates[j] <= target; j++) {
            if(j > i && candidates[j] == candidates[j - 1]) {
                continue;
            }
            path.add(candidates[j]);
            dfs(j + 1, target - candidates[j], candidates, res, path);
            path.remove(path.size() - 1);
        }
    }
}

http://www.kler.cn/a/520624.html

相关文章:

  • 通过亚马逊云科技Bedrock打造自定义AI智能体Agent(上)
  • freeswitch在centos上编译过程
  • Mybatis配置文件详解
  • 【ComfyUI专栏】推荐几个常用的云端ComfyUI平台
  • [笔记] 极狐GitLab实例 : 手动备份步骤总结
  • AI赋能医疗:智慧医疗系统源码与互联网医院APP的核心技术剖析
  • 股指期货的交易规则及细节详解
  • web前端4--css盒模型
  • 渗透测试技法之口令安全
  • Day35:字符串的大小写转换
  • MFC常用操作
  • vue 返回页面时刷新
  • DBO优化LSBoost回归预测matlab
  • Android各个版本存储权限适配
  • C++中类的使用
  • C语言的灵魂——指针(1)
  • vscode如何安装vue语法支持
  • BPMN.js详解
  • Qt 5.14.2 学习记录 —— 이십 QFile和多线程
  • OSCP - Proving Grounds - Press
  • Nginx中部署多个前端项目
  • Springboot集成Swagger和Springdoc详解
  • 【PyTorch】4.张量拼接操作
  • linux 内核学习方向以及职位
  • 论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(四)
  • shiro学习五:使用springboot整合shiro。在前面学习四的基础上,增加shiro的缓存机制,源码讲解:认证缓存、授权缓存。