代码随想录算法训练营|day27

39.组合总和

对数组排序,方便剪枝;剪枝:当前path求和大于target进行下一轮循环
数组中元素可以重复取值,所以递归时可以取当前值

func combinationSum(candidates []int, target int) [][]int {
	res := [][]int{}
	path := []int{}
	sort.Ints(candidates)
	var help func(candidates []int, target, sum, startIndex int)
	help = func(candidates []int, target, sum, startIndex int) {
		if sum == target {
			tmp := make([]int, len(path))
			copy(tmp, path)
			res = append(res, tmp)
			return
		}
		for i := startIndex; i < len(candidates) && sum+candidates[i] <= target; i++ {
			sum += candidates[i]
			path = append(path, candidates[i])
			help(candidates, target, sum, i)
			sum -= candidates[i]
			path = path[:len(path)-1]
		}
	}
	help(candidates, target, 0, 0)
	return res
}

40.组合总和II

数组中有重复元素,要求结果集合不能重复
注意:去重同一层元素,used[i - 1] = false,说明是从前一个元素回溯回来的,若used[i - 1] = true说明是进入下一个递归取值

func combinationSum2(candidates []int, target int) [][]int {
	res := [][]int{}
	path := []int{}
	used := make([]bool, len(candidates))
	sort.Ints(candidates)
	var help func(candidates []int, target, sum, startIndex int)
	help = func(candidates []int, target, sum, startIndex int) {
		if sum == target {
			tmp := make([]int, len(path))
			copy(tmp, path)
			res = append(res, tmp)
			return
		}
		for i := startIndex; i < len(candidates) && sum+candidates[i] <= target; i++ {
			if i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false {
				continue
			}
			sum += candidates[i]
			used[i] = true
			path = append(path, candidates[i])
			help(candidates, target, sum, i+1)
			path = path[:len(path)-1]
			used[i] = false
			sum -= candidates[i]
		}
	}
	help(candidates, target, 0, 0)
	return res
}

131.分割回文串

当切割点在string长度位置,说明找到一组符合要求的结果
如果是回文串,递归寻找后面的回文串,回溯;否则跳过当前元素

func partition(s string) [][]string {
	res := [][]string{}
	path := []string{}

	var help func(s string, startIndex int)
	help = func(s string, startIndex int) {
		if startIndex == len(s) {
			tmp := make([]string, len(path))
			copy(tmp, path)
			res = append(res, tmp)
			return
		}
		for i := startIndex; i < len(s); i++ {
			str := s[startIndex : i+1]
			if isPalindrome(str) {
				path = append(path, str)
				help(s, i+1)
				path = path[:len(path)-1]
			}
		}
	}
	help(s, 0)
	return res
}

func isPalindrome(s string) bool {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		if s[i] != s[j] {
			return false
		}
	}
	return true
}

代码随想录文章详解

39.组合总和
40.组合总和II
131.分割回文串

总结

组合、切割、子集、排列、棋盘:N皇后,解数独等等
学习go语言map实现set
基本能实现回溯,代码随想录yyds

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值