标签:target combination nums 重复 元素 offer81 组合 result 数字
题目:
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
1.输入: candidates = [2,3,6,7], target = 7
输出: [[7],[2,2,3]]
2.输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
3.输入: candidates = [1], target = 2
输出: [[1,1]]
分析:
该题和之前的79和80相比大同小异,最主要的不同点在于当选择将数组nums下标为i的数字添加到组合combination中之后,由于nums[i]这个数字可能在组合中重复出现,因此递归调用函数helper时第三个参数传入的指仍然是i,这个参数没有变化,下一步仍然处理数组nums的下标为i的数字。
该题target是组合combination中元素之和的目标值,每当在组合中添加一个数字时,就从target中减去这个数字,当target等于0的时候,组合中的所有元素之和正好等于target,因此也就找到一个符合条件的组合。
当使用回溯法解决问题时尽可能剪枝来优化时间效率,因为题目中明确指出数组中的所有数字都是正整数,因此当组合中已有数字和已经大于目标值的时候(target<0)就没必要考虑数组中还没有处理的数字,因此再在组合中添加任意正整数元素之后和会更大,一定找不到新的符合条件的组合。
代码:
import java.util.LinkedList;
import java.util.List;
public class CombinationSum {
public static void main(String[] args) {
CombinationSum combinationSum = new CombinationSum();
int[] nums = {2,3,5};
List<List<Integer>> lists = combinationSum.combinationSum(nums, 8);
System.out.println(lists);
}
public List<List<Integer>> combinationSum(int[] nums, int target) {
List<List<Integer>> result = new LinkedList<>();
LinkedList<Integer> combination = new LinkedList<>();
helper(nums,target,0,result,combination);
return result;
}
private void helper(int[] nums, int target, int i, List<List<Integer>> result, LinkedList<Integer> combination) {
if (target == 0){
result.add(new LinkedList<>(combination));
//target>0的作用是剪枝,减少不必要的递归,具体分析中有写。
}else if (target >0 && i < nums.length){
helper(nums,target,i+1,result,combination);
combination.add(nums[i]);
// 由于一个数字可以重复在组合中出现,也就是说下一步可能选择同一个数字,因此下一步仍然处理下标为i的数字。
helper(nums,target-nums[i],i,result,combination);
combination.removeLast();
}
}
}
标签:target,combination,nums,重复,元素,offer81,组合,result,数字 来源: https://blog.csdn.net/Jiaodaqiaobiluo/article/details/122274531
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。