一、leetcode39 Combination Sum
问题描述:
Given a set of candidate numbers(C) and a target number (T), find all uniquecombinations in C where the candidate numbers sums to T.
The same repeatednumber may be chosen from C unlimited number of times.
Note:
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]
问题分析:
一个很明显的DFS(深度优先遍历)的问题,注意每个节点可以重复利用即可。
代码:
public class Solution39 { /*** 简单的DFS算法***/ public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> result = new ArrayList<>(); if(candidates == null || candidates.length == 0) return result; //先对数组进行排序 Arrays.sort(candidates); //每次遍历暂存节点数组 List<Integer> curr = new ArrayList<Integer>(); DFS_Search(candidates, target, 0 , curr, result); return result; } /*** * @paramcandidates-- 源数据数组 * @paramtarget -- 目标值 * @paramindex -- 该循环数组起始位置 * @paramcurr -- 暂存该次遍历中的所有节点 * @paramresult -- 结果数组 ***/ private void DFS_Search(int[] candidates, int target, int index, List<Integer> curr, List<List<Integer>> result) { //递归返回标志 if(target== 0){ List<Integer> temp = new ArrayList<Integer>(curr); result.add(temp); return; } else{ for (int i = index; i < candidates.length; i++){ if(candidates[i] > target) return; else { curr.add(candidates[i]); // 因为可以重复使用某个值,所以这里依然index使用i DFS_Search(candidates, target- candidates[i], i, curr, result); curr.remove(curr.size() - 1); } } } } }
二、leetcode-40 Combination Sum II
问题分析:
与前面Combination Sum问题相比,其区别在于不能再重复利用同一个值;而且数组中可能出现值相同的元素。
这里寻找匹配值同样还是应该用DFS算法,但与前面不同的是要注意考虑重复值的问题;
消除重复值的策略是:如果前面路径中使用了某一元素,则下一相同值元素才可以使用(还要注意考虑如多个元素值相同的情况)。
下面代码在Combination Sum基础上添加了一个用以记录上一个元素是否在路径中被使用的变量flag;在消除重复值时,仅需要判别flag即可。
代码:
public class Solution40 { public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> result = new ArrayList<>(); if(candidates == null || candidates.length == 0) return result; // 先对数组进行排序 Arrays.sort(candidates); List<Integer> curr = new ArrayList<>(); DFS_Search2(candidates, target, 0 , curr, result, false); return result; } /*** * @param candidates-- 源数据数组 * @param target -- 目标值 * @param index -- 该循环数组起始位置 * @param curr -- 暂存该次遍历中的所有节点 * @param result -- 结果数组 * @param flags -- 用以标志前一个元素是否被使用 * ***/ private void DFS_Search2(int[] candidates, int target, int index, List<Integer> curr, List<List<Integer>> result, boolean flags){ if(target == 0) { result.add(new ArrayList(curr)); return; } else { for(int i = index; i < candidates.length; i++) { // 处理有重复值情况 if((i >= 1) && candidates[i] == candidates[i - 1]) { if(!flags){ continue; } } if(candidates[i] > target) return; curr.add(candidates[i]); flags = true; DFS_Search2(candidates, target - candidates[i], i + 1, curr, result, true); curr.remove(curr.size() - 1); flags = false; } } } public static void main(String[] args){ int[] data = {2, 2, 2}; int target = 4; List<List<Integer>> results = new ArrayList<>(); results = new Solution40().combinationSum2(data, target); System.out.println(results); } }