首页 > 试题广场 >

加起来和为目标值的组合(四)

[编程题]加起来和为目标值的组合(四)
  • 热度指数:1496 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个由不同整数构成的数组 nums 和一个整数 target ,请你从 nums 找出总和是 target 的组合的个数。解集中可以重复使用 nums 中的元素。且解集中数字顺序不同视为不同的组合。

数据范围: 数组长度满足 ,数组中的数满足 ,
示例1

输入

[1,2,3],4

输出

7

说明

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
示例2

输入

[9],10

输出

0
示例3

输入

[9],18

输出

1

说明

[[9,9]] 
public int combination (int[] nums, int target) {
        // write code here
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        Arrays.sort(nums);
        dfs(res, list, nums, target);
        return res.size();
    }
    public void dfs(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> list,
                    int[] nums, int target) {
        if(target == 0){
            res.add(new ArrayList<Integer>(list));
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > target) {
                return;
            }
            list.add(i);
            dfs(res, list, nums, target - nums[i]);
            list.remove(list.size() - 1);
        }
    }

发表于 2023-04-01 00:54:03 回复(0)
标准的回溯框架,写一个backtrack辅助函数就可以了,重点就是终止条件、已选择、达到条件
public int combination (int[] nums, int target) {
    backTrack(nums, target);
    return cnt;
}
public int sum = 0, cnt = 0;
public void backTrack(int[] nums, int target) {
    if (sum > target) return;
    if (sum == target) {
        cnt++;
        return;
    }
    for (int i = 0; i < nums.length; i++) {
        sum += nums[i];
        backTrack(nums, target);
        sum -= nums[i];
    }
}
发表于 2022-01-11 12:58:03 回复(0)
深度优先搜索,由于数组中每个数不限制选择次数,因此每一层深度都可以选相同的数。用rest表示还剩多少数需要凑,分为以下三种情况:
  1. rest=0时,表示凑足了target,方案数自增;
  2. 当剩下的rest<0时,表示凑过头了,当前的组合方案无效;
  3. 当rest>0时,就尝试当前选择数组中所有数的可能性,rest-=nums[i]后继续下一层的搜索。
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @param target int整型 
     * @return int整型
     */
    int count = 0;
    public int combination (int[] nums, int target) {
        // write code here
        dfs(nums, target);
        return count;
    }
    
    private void dfs(int[] nums, int rest) {
        if(rest < 0){
            return;     // 凑过头了,本次组合无效
        }
        if(rest == 0){
            // 凑足目标值了就添加答案
            count++;
        }else{
            // 否则遍历此时选所有数的可能,继续递归选下一个数
            for(int i = 0; i < nums.length; i++){
                dfs(nums, rest - nums[i]);
            }
        }
    }
}

编辑于 2021-12-17 14:30:14 回复(0)

问题信息

难度:
3条回答 3206浏览

热门推荐

通过挑战的用户

查看代码