491.递增子序列
很不一样的一个点就是这个无法通过比较相邻的两个元素来去重,因为这个是无序的。因为单层迭代中维护了一个set来记录重复元素。
hash := map[int]struct{}{}
hash[nums[i]] = struct{}{} //注意赋值的时候也是两个花括号
func findSubsequences(nums []int) [][]int {
ret := make([][]int, 0)
path := make([]int, 0)
var build func(int)
build = func(index int){
if len(path) > 1{
ret = append(ret, append([]int(nil), path...))
}
if len(nums) == index{
return
}
hash := map[int]struct{}{}
for i := index; i < len(nums); i++{
if len(path) != 0 && nums[i] < path[len(path) - 1]{
continue
}
if _, ok := hash[nums[i]]; ok{
continue
}
hash[nums[i]] = struct{}{}
path = append(path, nums[i])
build(i + 1)
path = path[:(len(path) - 1)]
}
}
build(0)
return ret
}
46.全排列
排列问题就是区分先后顺序的了,所以不需要用index来做限制。
但是必须保证树枝的不能重复,所以要创建一个used来确保上一层用过的下一层不会再用。
ps. used中i是与nums中i一一对应,并不是与nums中元素个数一一对应
func permute(nums []int) [][]int {
ret := make([][]int, 0)
path := make([]int, 0)
used := make([]bool, len(nums))
for i := 0; i < len(nums); i++{
used[i] = false
}
var build func()
build = func(){
if len(path) == len(nums){
ret = append(ret, append([]int(nil), path...))
}
for i := 0; i < len(nums);i++{
if used[i] {
continue
}
used[i] = true
path = append(path, nums[i])
build()
used[i] = false
path = path[:(len(path) - 1)]
}
}
build()
return ret
}
47.全排列 II
这里面给定的数组中就加入了重复的元素,所以就即要在层中去重,又要在枝中去重。
层中去重选择的是map,如果使用了[i] == [i - 1]的话好像还会影响了枝的选择,枝的去重还是选择传递了一个used
func permuteUnique(nums []int) [][]int {
sort.Ints(nums)
ret := make([][]int, 0)
path := make([]int, 0)
used := make([]bool, len(nums))
for i := 0 ; i < len(nums); i++{
used[i] = false
}
var build func()
build = func(){
if len(path) == len(nums){
ret = append(ret, append([]int(nil), path...))
}
hash := map[int]struct{}{}
for i := 0; i < len(nums); i++{
if _, ok := hash[nums[i]]; ok {continue}
if used[i] { continue }
used[i] = true
hash[nums[i]] = struct{}{}
path = append(path, nums[i])
build()
used[i] = false
path = path[:(len(path) - 1)]
}
}
build()
return ret
}