75 含有 k 个元素的组合
给定两个整数 n
和 k
,返回 1 ... n
中所有可能的 k
个数的组合。
力扣https://leetcode-cn.com/problems/uUsW3B/
//要查询n个数字中k个数的组合,先想到深度优先探索
//首先明确跳出条件,k==0的时候说明排列完毕,当数组长小于k的时候可以不必排列
//start 开始的坐标用于避免重复 k 还需要几个数 res 最终结果 original 上次排序的值 arr 数组中的值
func dfscombine(start,k int,res *[][]int,orignal,arr []int){
if k==0{
*res = append(*res,orignal)
return
}
for i:=start;i<len(arr)-k+1;i++{
tmp:=make([]int,len(orignal))
copy(tmp,orignal)
tmp = append(tmp,arr[i])
dfscombine(i+1,k-1,res,tmp,arr)
}
}
func combine(n,k int)[][]int{
var arr []int
var res [][]int
for i:=1;i<=n;i++{
arr = append(arr,i)
}
dfscombine(0,k,&res,[]int{},arr)
return res
}
76 允许重复选择元素的组合
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
输入: candidates =[2,3,6,7],
target =7
输出: [[7],[2,2,3]]
力扣https://leetcode-cn.com/problems/Ygoe9J/
//求所有数组值的和为target的和
//跳出条件,当sum==target 此时结果正确,当sum>target跳出,sum<target继续
//candidates 所有的数组,因为允许重复使用某个值 res 用于存储最后结果
//arr 存储之前所有的结果 target 目标值 index 索引代表当前走到了哪一步,防止重复
func innerCombinationSum(candidates []int,res *[][]int,arr []int,target,index int){
var sum int
for i:=0;i<len(arr);i++{
sum = sum + arr[i]
}
if sum==target{
*res = append(*res,arr)
}else{
for i:=index;i<len(candidates);i++{
tmp:=make([]int,len(arr))
copy(tmp,arr)
if candidates[i]+sum>target{
continue
}
tmp = append(tmp,candidates[i])
innerCombinationSum(candidates,res,tmp,target,i)
}
}
}
func combinationSum(candidates []int, target int) [][]int {
var res [][]int
innerCombinationSum(candidates,&res,[]int{},target,0)
return res
}
77 含有重复元素集合的组合
给定一个可能有重复数字的整数数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次,解集不能包含重复的组合。
力扣https://leetcode-cn.com/problems/4sjJUc/
//与上一题对照来看,区别只在于数组中含有重复,以及数字只使用一次
//使用armap,去掉重复
//使用index = i+1解决数字只能使用一次
//使用sort解决顺序问题
func innerCombinationSumV2(candidates []int,res *[][]int,arr []int,target,index int){
var sum int
for i:=0;i<len(arr);i++{
sum = sum + arr[i]
}
if sum==target{
*res = append(*res,arr)
}else if sum >target{
return
}else{
armap:=make(map[int]bool)
for i:=index;i<len(candidates);i++{
if armap[candidates[i]]{
continue
}else {
armap[candidates[i]] = true
}
tmp:=make([]int,len(arr))
copy(tmp,arr)
if candidates[i]+sum>target{
continue
}
tmp = append(tmp,candidates[i])
innerCombinationSumV2(candidates,res,tmp,target,i+1)
}
}
}
func combinationSum2(candidates []int, target int) [][]int {
var res [][]int
sort.Ints(candidates)
innerCombinationSumV2(candidates,&res,[]int{},target,0)
return res
}
78 没有重复元素集合的全排列
给定一个不含重复数字的整数数组 nums
,返回其 所有可能的全排列 。可以 按任意顺序 返回答案。
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
https://leetcode-cn.com/problems/VvJkup/https://leetcode-cn.com/problems/VvJkup/
//全排列第一个想到深度优先探索
//res作为结果 nums表示原先数组的值 arr表示结果
func innerPermute(res *[][]int,nums []int,arr []int){
if len(nums)==0{
*res = append(*res,arr)
return
}
for i:=0;i<len(nums);i++{
tmpnum:=make([]int,len(nums))
copy(tmpnum,nums)
tmparr:=make([]int,len(arr))
copy(tmparr,arr)
tmparr = append(tmparr,nums[i])
tmpnum = append(tmpnum[:i], tmpnum[i+1:]...)
innerPermute(res,tmpnum,tmparr)
}
}
func permute(nums []int) [][]int {
var res [][]int
innerPermute(&res,nums,[]int{})
return res
}
79 含有重复元素集合的全排列
给定一个可包含重复数字的整数集合 nums
,按任意顺序 返回它所有不重复的全排列。
力扣https://leetcode-cn.com/problems/7p8L0Z/
//与上一题区别只在于一个含有重复一个没有重复,解决重复即可
func innerPermuteUnique(res *[][]int,nums []int,arr []int){
if len(nums)==0{
*res = append(*res,arr)
return
}
tmpmap:=make(map[int]bool)
for i:=0;i<len(nums);i++{
if tmpmap[nums[i]] == true{
continue
}else{
tmpmap[nums[i]] = true
}
tmpnum:=make([]int,len(nums))
copy(tmpnum,nums)
tmparr:=make([]int,len(arr))
copy(tmparr,arr)
tmparr = append(tmparr,nums[i])
tmpnum = append(tmpnum[:i], tmpnum[i+1:]...)
innerPermuteUnique(res,tmpnum,tmparr)
}
}
func permuteUnique(nums []int) [][]int {
var res [][]int
innerPermuteUnique(&res,nums,[]int{})
return res
}
80 复原ip
https://leetcode-cn.com/problems/0on3uN/https://leetcode-cn.com/problems/0on3uN/
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能从 s 获得的 有效 IP 地址 。你可以按任何顺序返回答案。
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。
func isValidIp(str string)bool{
if len(str)==0||len(str)>3{
return false
}
num,_:=strconv.Atoi(str)
if num>255{
return false
}
if str[0]=='0'&&len(str)>1{
return false
}
return true
}
//要求所有可能,第一个想到深度优先遍历
//一定有4个.,当.没有的时候跳出
//0代表.的个数 str 代表已经拼接的 laststr代表上次剩余的
func innerRestoreIpAddresses(o int,str,laststr string,res *[]string ){
if o==0{
if isValidIp(laststr){
*res = append(*res,str+laststr)
}
return
}
//一个顿号最大3个值
for i:=0;i<len(laststr)&&i<3;i++{
if !isValidIp(laststr[:i+1]){
break
}
tmp:=str
tmp = tmp + laststr[:i+1]
tmp = tmp + "."
innerRestoreIpAddresses(o-1,tmp,laststr[i+1:],res)
}
}
func restoreIpAddresses(s string) []string {
var res []string
innerRestoreIpAddresses(3,"",s,&res)
return res
}
81 生成匹配的括号
https://leetcode-cn.com/problems/IDBivT/https://leetcode-cn.com/problems/IDBivT/正整数
n
代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
func innerGenerateParenthesis(n, open, close int, str string, strs *[]string) {
if open > n || close > open {
return
}
if len(str) == 2*n {
*strs = append(*strs, str)
return
}
innerGenerateParenthesis(n, open+1, close, str+"(", strs)
innerGenerateParenthesis(n, open, close+1, str+")", strs)
}
func generateParenthesis(n int) []string {
var strs []string
innerGenerateParenthesis(n, 0, 0, "", &strs)
return strs
}
82 分割回文子字符串
https://leetcode-cn.com/problems/M99OJA/https://leetcode-cn.com/problems/M99OJA/
给定一个字符串 s ,请将 s 分割成一些子串,使每个子串都是 回文串 ,返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
func isPalindromeV2(s string)bool{
start:=0
end:=len(s)-1
for start<=end{
if s[start]!=s[end]{
return false
}
start = start + 1
end = end - 1
}
return true
}
//要求所有的可能方案
//
func innerPartiton(original []string,laststr string ,res *[][]string){
if len(laststr)==0{
tmp:=make([]string,len(original))
copy(tmp,original)
*res = append(*res,tmp)
return
}
//长度从 1 到 len(laststr)
for i:=0;i<len(laststr);i++{
if isPalindromeV2(laststr[:i+1]){
tmp:=make([]string,len(original))
copy(tmp,original)
tmp = append(tmp,laststr[:i+1])
innerPartiton(tmp,laststr[i+1:],res)
}else{
continue
}
}
return
}
func partition(s string) [][]string {
var res [][]string
innerPartiton([]string{},s,&res)
return res
}