LeetCode040组合总和II

20 阅读2分钟

题目:

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:
所有数字(包括目标数)都是正整数。解集不能包含重复的组合。

  • 示例 1:
  • 输入: candidates = [10,1,2,7,6,1,5], target = 8,
  • 所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

转存失败,建议直接上传图片文件

  • 示例 2:
  • 输入: candidates = [2,5,2,1,2], target = 5,
  • 所求解集为:
[
  [1,2,2],
  [5]
]

转存失败,建议直接上传图片文件

java:

public class Leetcode040 {

    static LinkedList<Integer> path = new LinkedList<>();
    static List<List<Integer>> ans = new LinkedList<>();
    static boolean[] used;
    static int sum = 0;

    public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
        used = new boolean[candidates.length];
        //加标志数组.用来判断是否使用过.
        Arrays.fill(used, false);
        //对数组进行排序.
        Arrays.sort(candidates);
        backTracking(candidates, target, 0);
        return ans;
    }

    private static void backTracking(int[] candidates, int target, int startIndex) {
        if (sum == target) {
            ans.add(new ArrayList<>(path));
        }
        for (int i = startIndex; i < candidates.length; i++) {
            if (sum + candidates[i] > target) {
                break;
            }
            //出现重复节点.同层的第一个节点已经被访问过.直接跳过.
            if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) {
                continue;
            }
            used[i] = true;
            sum += candidates[i];
            path.add(candidates[i]);
            //每个节点选择一次.
            backTracking(candidates, target, i + 1);
            used[i] = false;
            sum -= candidates[i];
            path.removeLast();
        }
    }

    public static void main(String[] args) {
        int[] candidates = {10, 1, 2, 7, 6, 1, 5};
        List<List<Integer>> sum2 = combinationSum2(candidates, 8);
        System.out.println(sum2);
    }
}

Go:

package LeetCode

import "sort"

var (
	res40  [][]int
	path40 []int
	used   []bool
)

func CombinationSum2(nums []int, target int) [][]int {
	res40, path40 = make([][]int, 0), make([]int, 0, len(nums))
	used = make([]bool, len(nums))
	sort.Ints(nums)
	dfs40(nums, target, 0)
	return res40
}

func dfs40(nums []int, target int, startIndex int) {
	//target不断减小.为0说明达到了目标值.
	if target == 0 {
		tmp := make([]int, len(path40))
		copy(tmp, path40)
		res40 = append(res40, tmp)
		return
	}

	for i := startIndex; i < len(nums); i++ {
		if nums[i] > target {
			break
		}
		//说明前面元素已经使用过了.不满足条件.
		if i > 0 && nums[i] == nums[i-1] && used[i-1] == false {
			continue
		}
		path40 = append(path40, nums[i])
		used[i] = true
		dfs40(nums, target-nums[i], i+1)
		used[i] = false
		path40 = path40[:len(path40)-1]
	}
}


func main() {
	nums := []int{10, 1, 2, 7, 6, 1, 5}
	sum2 := LeetCode.CombinationSum2(nums, 7)
	fmt.Println(sum2)
}

消失的人回不去的青春.





如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路