leetcode40组合综合II

leetcode40 Combination Sum II

Posted by BY on February 15, 2019

前言

新的一年,好好学习

正文

问题来源

本问题来自leetcode上的40题。

问题描述

给定一个数组 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]
]

分析:

首先将candidates数组排序,采用回溯法求得解集

func combinationSum2(candidates []int, target int) [][]int {
    ret := make([][]int, 0)
    sort.Ints(candidates)
    temp := make([]int, 0)
    dfs(candidates,&ret,&temp,target,0,0)
    return ret
}

//返回结果数组长度未知,append需要更改slice指向,而非内容
func dfs(candidates []int, ret *[][]int, temp *[]int, target int, sum int, index int) {
    if sum == target {
    	//不可直接append(*ret, *temp),浅拷贝
	    slice := append([]int{}, (*temp)...)
        *ret = append(*ret, slice)
    } else if sum > target { //candidates已经经过排序,大于target就可停止递归
        return
    }
    for i := index; i < len(candidates); i++ {
        *temp = append(*temp, candidates[i])
        //因为采用回溯法,参数应该为sum+candidates[i]和1+i
        //而不能使用sum += candidates[i]后将sum作为参数(需要回溯)
        dfs(candidates,ret,temp,target,sum+candidates[i],1+i)
        *temp = (*temp)[:len(*temp)-1] 
        //去掉相同的结果
        for i+1 < len(candidates) && candidates[i] == candidates[i+1] {
            i++
        }
    }
}

总结:

勤思考。

结语

不管怎么样好好加油。