算法leetcode|40. 组合总和 II(rust重拳出击)
创始人
2024-06-02 14:50:29
0

文章目录

  • 39. 组合总和:
    • 样例 1:
    • 样例 2:
    • 提示:
  • 分析:
  • 题解:
    • rust
    • go
    • c++
    • c
    • python
    • java


39. 组合总和:

给定一个候选人编号的集合 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]]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

分析:

  • 面对这道算法题目,二当家的陷入了沉思。
  • 遍历或者递归,递归比较直观,深度优先,回溯。
  • 题目要求所有可能的组合,不能重复,本来是需要想办法去重的,但是我们可以曲线救国,我们可以计数去重,还可以排序,排序可以助力剪枝,当处理的数字已经大于目标和时,后面的数字就可以跳过了。
  • 计数排序,去重,计数,排序,一下子都搞定。

题解:

rust

impl Solution {pub fn combination_sum2(candidates: Vec, target: i32) -> Vec> {fn dfs(nums: &Vec, target: i32, num: i32, row: &mut Vec, ans: &mut Vec>) {if target == 0 {// 符合条件的一个组合ans.push(row.clone());return;}if num as usize == nums.len() || target < num {// 尝试到底,开始回溯return;}let count = nums[num as usize].min(target / num);(1..count + 1).for_each(|i| {// 选择当前下标数字row.push(num);dfs(nums, target - num * i, num + 1, row, ans);});row.resize(row.len() - count as usize, 0);// 跳过当前下标数字dfs(nums, target, num + 1, row, ans);}// 1 <= candidates[i] <= 50let mut nums = vec![0; 51];candidates.iter().for_each(|&c| {nums[c as usize] += 1;});let mut ans = Vec::new();// 递归深度优先回溯套娃大法dfs(&nums, target, 1, &mut Vec::new(), &mut ans);return ans;}
}

go

func combinationSum2(candidates []int, target int) [][]int {var ans [][]int// 1 <= candidates[i] <= 50nums := make([]int, 51)for _, c := range candidates {nums[c]++}var dfs func(int, int, []int)dfs = func(target int, num int, row []int) {if target == 0 {// 符合条件的一个组合ans = append(ans, append([]int{}, row...))return}if num == len(nums) || target < num {// 尝试到底,开始回溯return}count := target / numif nums[num] < count {count = nums[num]}// 选择当前下标数字for i := 1; i <= count; i++ {row = append(row, num)dfs(target-num*i, num+1, row)}row = row[:len(row)-count]// 跳过当前下标数字dfs(target, num+1, row)}dfs(target, 1, []int{})return ans
}

c++

class Solution {
private:void dfs(vector& nums, int target, int num, vector& row, vector>& ans) {if (target == 0) {// 符合条件的一个组合ans.emplace_back(row);return;}if (num == nums.size() || target < num) {// 尝试到底,开始回溯return;}int count = min(target / num, nums[num]);for (int i = 1; i <= count; ++i) {// 选择当前下标数字row.emplace_back(num);dfs(nums, target - num * i, num + 1, row, ans);}for (int i = 1; i <= count; ++i) {row.pop_back();}// 跳过当前下标数字dfs(nums, target, num + 1, row, ans);}
public:vector> combinationSum2(vector& candidates, int target) {vector> ans;vector row;vector nums(51);for (int c: candidates) {++nums[c];}dfs(nums, target, 1, row, ans);return ans;}
};

c

void dfs(int *nums, int numsSize, int target, int num, int *row, int rowSize, int **ans, int *returnSize,int **returnColumnSizes) {if (target == 0) {// 符合条件的一个组合ans[*returnSize] = (int *) malloc(sizeof(int) * rowSize);memcpy(ans[*returnSize], row, sizeof(int) * rowSize);(*returnColumnSizes)[*returnSize] = rowSize;++(*returnSize);return;}if (num == numsSize || target < num) {// 尝试到底,开始回溯return;}int count = fmin(target / num, nums[num]);for (int i = 1; i <= count; ++i) {// 选择当前下标数字row[rowSize + i - 1] = num;dfs(nums, numsSize, target - num * i, num + 1, row, rowSize + i, ans, returnSize, returnColumnSizes);}// 跳过当前下标数字dfs(nums, numsSize, target, num + 1, row, rowSize, ans, returnSize, returnColumnSizes);
}/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/
int **combinationSum2(int *candidates, int candidatesSize, int target, int *returnSize, int **returnColumnSizes) {*returnSize = 0;*returnColumnSizes = (int *) malloc(sizeof(int) * 150);int **ans = (int **) malloc(sizeof(int *) * 150);int row[target];int nums[51];memset(nums, 0, sizeof(nums));for (int i = 0; i < candidatesSize; ++i) {++nums[candidates[i]];}dfs(nums, 51, target, 1, row, 0, ans, returnSize, returnColumnSizes);return ans;
}

python

class Solution:def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:ans = []nums = [0] * 51for c in candidates:nums[c] += 1def dfs(target: int, num: int, row: List[int]):if target == 0:# 符合条件的一个组合ans.append(row.copy())returnif num == len(nums) or target < num:# 尝试到底,开始回溯returncount = min(target // num, nums[num])for i in range(1, count + 1):row.append(num)dfs(target - num * i, num + 1, row)for i in range(1, count + 1):row.pop()# 跳过当前下标数字dfs(target, num + 1, row)dfs(target, 1, [])return ans

java

class Solution {public List> combinationSum2(int[] candidates, int target) {// 1 <= candidates[i] <= 50int[] nums = new int[51];for (int c : candidates) {++nums[c];}List> ans = new ArrayList<>();// 递归深度优先回溯套娃大法this.dfs(nums, target, 1, new LinkedList<>(), ans);return ans;}private void dfs(int[] nums, int target, int num, Deque row, List> ans) {if (target == 0) {// 符合条件的一个组合ans.add(new ArrayList<>(row));return;}if (num == nums.length || target < num) {// 尝试到底,开始回溯return;}int count = Math.min(target / num, nums[num]);for (int i = 1; i <= count; ++i) {// 选择当前下标数字row.addLast(num);this.dfs(nums, target - num * i, num + 1, row, ans);}for (int i = 1; i <= count; ++i) {row.pollLast();}// 跳过当前下标数字this.dfs(nums, target, num + 1, row, ans);}
}

非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...