78. Subsets (含组合和排序)

leetcode

Posted by chl on May 6, 2019

题目

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

题意

题目很好理解,就是求数组的所有组合

题解

解法就是使用求组合的方法

代码

var ans [][]int
func subsets(nums []int) [][]int {
	ans = make([][]int,0)
	for i:=0;i<= len(nums);i++{
		Combination(i,0,nums,[]int{})
	}
	return ans
}

func Combination(number ,start int ,nums, res[]int){
	if number == len(res){
		//找到一个组合,输出
		ans = append(ans,append(make([]int,0),res...))
		return
	}

	for i:=start;i< len(nums);i++{
		res = append(res,nums[i])
		Combination(number,i+1,nums,res)
		res = res[:len(res)-1]
	}
}

总结

求组合的方法

func Combination(number ,start int ,nums, res[]int){
	if number == len(res){
		//找到一个组合,输出
		ans = append(ans,append(make([]int,0),res...))
		return
	}

	for i:=start;i< len(nums);i++{ 
		res = append(res,nums[i])
		Combination(number,i+1,nums,res)
		res = res[:len(res)-1]
	}
}

==需要十分熟悉掌握的==。
以上代码的大致思路就是:我们要从nums中获取number个元素的所有组合,那么就从start位置开始,如果当前res还没到达number个数,则从start位置开始加进去,然后再递归进去,在递归里面去增加res个数,直到满足number个,此时找到一个组合,return返回上层,在上层函数中将原来加进去的元素移除(因为该组合以求得),在取下一个元素加入到res中,求出另外一个组合。
就相当于一开始固定住了number-1个元素,在从number个位置开始追加元素进res来求出组合。

//求全排序
func Permutation(number int,nums,res[]int){
	if number == len(res){
		ans = append(ans,append(make([]int,0),res...))
		return
	}
	for i:=0;i< len(nums);i++{ //从0开始,才能列出每种情况
		if use[i]{ //使用use来避免单个元素重复出现,即已在res中的元素就跳过
			continue
		}
		use[i] = true
		res = append(res, nums[i])
		Permutation(number,nums,res)
		res = res[:len(res)-1]
		use[i]=false
	}
}

==排序也是需要掌握==,大致思路和组合一样,只是组合为了避免重复的情况,每次递归进去都是从下个位置开始,而排序则需要将相同元素的组合进行不同位置的排列,所有需要从0开始,这里使用use来避免res中已存在的元素再次加进res,即避免单个元素重复出现。

go中移除最后一个元素 res = res[:len(res)-1]
go中由于slice是引用类型,所以直接使用后文中可能变化的slice作为二维数组的元素是会变化的,所以需要在添加进二维数组的时候给他开辟空间ans = append(ans,append(make([]int,0),res...))