LeetCode第40题 Combination Sum II
/*
Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
Each number in candidates may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
*/
import java.util.*;
public class CombinationSumII{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入一串整数,并用空格隔开,以回车结束");
// 一次读一行:https://www.cnblogs.com/liyao0312/p/11202393.html
String[] str = sc.nextLine().split(" ");
int nums[]=new int[str.length];
for(int i=0;i<nums.length;i++){
// 字符串转Int
nums[i]=Integer.parseInt(str[i]);
}
// Integer[] nums = temp.toArray(new Integer[temp.size()]);
// int[] nums = temp.stream().mapToInt(Integer::valueOf).toArray();
System.out.println("输入目标:");
int target = sc.nextInt();
sc.close();
CombinationSumII cs = new CombinationSumII();
List<List<Integer>> result = cs.combinationSum(nums, target);
System.out.println(result);
}
// 穷举的办法
public List<List<Integer>> combinationSum(int[] nums,int target){
List<List<Integer>> list = new ArrayList<>();
backtrack(list,nums,target,new ArrayList<Integer>(),0);
// return list;
return removeDuplicate(list);
}
private void backtrack(List<List<Integer>> list,int[] nums,int remaind,List<Integer> tempList,int start){
if (remaind < 0) {
return;
}else if(remaind == 0) {
list.add(new ArrayList<>(tempList));
}else{
for (int i=start;i<nums.length;i++){
tempList.add(nums[i]);
// jian start=i -> start=i+1
backtrack(list,nums,remaind-nums[i],tempList,i+1);
// backtrack运行完只有两种可能:remaind==0 or ramaind < 0
tempList.remove(tempList.size()-1);
}
}
}
private List<List<Integer>> removeDuplicate(List<List<Integer>> list) {
Map<String, String> ans = new HashMap<String, String>();
for (int i = 0; i < list.size(); i++) {
List<Integer> l = list.get(i);
// 对list容器排序
Collections.sort(l);
String key = "";
for (int j = 0; j < l.size() - 1; j++) {
// 将数值拼接成字符串
key = key + l.get(j) + ",";
}
key = key + l.get(l.size() - 1);
// 若key存在,则覆盖之前的value
ans.put(key, "");
}
List<List<Integer>> ans_list = new ArrayList<List<Integer>>();
// 遍历去重后的map的KeySet
for (String k : ans.keySet()) {
String[] l = k.split(",");
// 遍历list,将字符转化为整数:Integer.parseInt
List<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < l.length; i++) {
int c = Integer.parseInt(l[i]);
temp.add(c);
}
ans_list.add(temp);
}
return ans_list;
}
}