Leetcode_40_CombinationSumII--数组元素组合,和为目标值,一个元素只可用一次,输出每种组合,每种组合唯一
Posted 二十六画生的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode_40_CombinationSumII--数组元素组合,和为目标值,一个元素只可用一次,输出每种组合,每种组合唯一相关的知识,希望对你有一定的参考价值。
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sum to target
.
Each number in candidates
may only be used once in the combination.
Note: The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8 Output: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5 Output: [ [1,2,2], [5] ]
Constraints:
1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30
package com.backtrack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Author you guess
* @Date 2022/5/2 00:14
* @Version 1.0
* @Desc 回溯
* 本题比较经典,回溯法!
* 数组元素组合,和为目标值,一个元素只可用一次,输出每种组合,每种组合唯一
*/
public class Leetcode_40_CombinationSumII
/**
* 正确方法:
* Runtime: 5 ms, faster than 65.47% of Java online submissions for Combination Sum II.
* Memory Usage: 42.7 MB, less than 80.23% of Java online submissions for Combination Sum II.
* RIGHT Answer
* Input
* [10,1,2,7,6,1,5]
* 8
* Output
* [[1,1,6],[1,2,5],[1,7],[1,2,5],[1,7],[2,6]]
* Expected
* [[1,1,6],[1,2,5],[1,7],[2,6]]
*
* @param candidates
* @param target
* @return
*/
public List<List<Integer>> combinationSum2(int[] candidates, int target)
List<List<Integer>> result = new ArrayList();
List<Integer> subResult = new ArrayList();
Arrays.sort(candidates);
//无需排序,直接下一步
combinationSum(candidates, 0, target, subResult, result);
return result;
//方法重载
private void combinationSum(int[] candidates, int startIndex, int target, List<Integer> subResult, List<List<Integer>> result)
if (target < 0)
return; // No combination is possible
if (target == 0)
//需要使用新的集合对象,不然当subSet元素变化时allSet也会同时变化
result.add(new ArrayList(subResult)); // If target is reached, add this combination to result
return;
/**
* Use startIndex so that same candidate values are not picked again
* Without startIndex, if we use 0, we will get permutations,
* i.e. repeat of same combinations but in different orders. Try it
*/
for (int i = startIndex; i < candidates.length; i++)
// if (i > 0 && candidates[i - 1] == candidates[i])
// continue;
// // 结果是[[1, 2, 5], [1, 7], [2, 6]],少了[1, 1, 6],是错误的。
//i大于起始位置才与上一位比较是否重复
if (startIndex < i && candidates[i - 1] == candidates[i])
continue;
// 结果是[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
subResult.add(candidates[i]);
int remainingTarget = target - candidates[i];
combinationSum(candidates, i + 1, remainingTarget, subResult, result);
//回溯,删除上次添加到末尾的元素
subResult.remove(subResult.size() - 1); // Backtrack, remove the last element added
public static void main(String[] args)
Leetcode_40_CombinationSumII main = new Leetcode_40_CombinationSumII();
// System.out.println(main.combinationSum2(new int[]10, 1, 2, 7, 6, 1, 5, 8));//[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
// System.out.println(main.combinationSum2(new int[]1, 1, 2, 2, 5, 5, 7));//[[1, 1, 5], [2, 5]]
System.out.println(main.combinationSum2(new int[]1, 1, 1, 3));//[[1, 1, 1]]
/**
* Wrong Answer
* Details
* Input
* [10,1,2,7,6,1,5]
* 8
* Output
* [[1,1,6],[1,2,5],[1,7],[1,2,5],[1,7],[2,6]]
* Expected
* [[1,1,6],[1,2,5],[1,7],[2,6]]
*
* @param candidates
* @param target
* @return
*/
public List<List<Integer>> combinationSum22(int[] candidates, int target)
List<List<Integer>> result = new ArrayList();
List<Integer> subResult = new ArrayList();
Arrays.sort(candidates);
//无需排序,直接下一步
combinationSum23(candidates, 0, target, subResult, result);
return result;
//方法重载
private void combinationSum23(int[] candidates, int startIndex, int target, List<Integer> subResult, List<List<Integer>> result)
if (target < 0)
return; // No combination is possible
if (target == 0)
//需要使用新的集合对象,不然当subSet元素变化时allSet也会同时变化
result.add(new ArrayList(subResult)); // If target is reached, add this combination to result
return;
for (int i = startIndex; i < candidates.length; i++)
subResult.add(candidates[i]);
int remainingTarget = target - candidates[i];
combinationSum(candidates, i + 1, remainingTarget, subResult, result);
//回溯,删除上次添加到末尾的元素
subResult.remove(subResult.size() - 1); // Backtrack, remove the last element added
以上是关于Leetcode_40_CombinationSumII--数组元素组合,和为目标值,一个元素只可用一次,输出每种组合,每种组合唯一的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode_40_CombinationSumII--数组元素组合,和为目标值,一个元素只可用一次,输出每种组合,每种组合唯一