Merge pull request #421 from X-shuffle/master

添加 0669.修剪二叉搜索树 Golang版本
This commit is contained in:
程序员Carl
2021-06-23 09:37:25 +08:00
committed by GitHub
9 changed files with 300 additions and 0 deletions

View File

@ -342,6 +342,46 @@ class Solution:
Go
> 主要在于递归中传递下一个数字
```go
func letterCombinations(digits string) []string {
lenth:=len(digits)
if lenth==0 ||lenth>4{
return nil
}
digitsMap:= [10]string{
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
}
res:=make([]string,0)
recursion("",digits,0,digitsMap,&res)
return res
}
func recursion(tempString ,digits string, Index int,digitsMap [10]string, res *[]string) {//index表示第几个数字
if len(tempString)==len(digits){//终止条件字符串长度等于digits的长度
*res=append(*res,tempString)
return
}
tmpK:=digits[Index]-'0' // 将index指向的数字转为int确定下一个数字
letter:=digitsMap[tmpK]// 取数字对应的字符集
for i:=0;i<len(letter);i++{
tempString=tempString+string(letter[i])//拼接结果
recursion(tempString,digits,Index+1,digitsMap,res)
tempString=tempString[:len(tempString)-1]//回溯
}
}
```
javaScript
```js

View File

@ -286,6 +286,39 @@ class Solution:
```
Go
> 主要在于递归中传递下一个数字
```go
func combinationSum(candidates []int, target int) [][]int {
var trcak []int
var res [][]int
backtracking(0,0,target,candidates,trcak,&res)
return res
}
func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int){
//终止条件
if sum==target{
tmp:=make([]int,len(trcak))
copy(tmp,trcak)//拷贝
*res=append(*res,tmp)//放入结果集
return
}
if sum>target{return}
//回溯
for i:=startIndex;i<len(candidates);i++{
//更新路径集合和sum
trcak=append(trcak,candidates[i])
sum+=candidates[i]
//递归
backtracking(i,sum,target,candidates,trcak,res)
//回溯
trcak=trcak[:len(trcak)-1]
sum-=candidates[i]
}
}
```
JavaScript
```js

View File

@ -314,6 +314,48 @@ class Solution:
```
Go
> 主要在于如何在回溯中去重
```go
func combinationSum2(candidates []int, target int) [][]int {
var trcak []int
var res [][]int
var history map[int]bool
history=make(map[int]bool)
sort.Ints(candidates)
backtracking(0,0,target,candidates,trcak,&res,history)
return res
}
func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int,history map[int]bool){
//终止条件
if sum==target{
tmp:=make([]int,len(trcak))
copy(tmp,trcak)//拷贝
*res=append(*res,tmp)//放入结果集
return
}
if sum>target{return}
//回溯
// used[i - 1] == true说明同一树支candidates[i - 1]使用过
// used[i - 1] == false说明同一树层candidates[i - 1]使用过
for i:=startIndex;i<len(candidates);i++{
if i>0&&candidates[i]==candidates[i-1]&&history[i-1]==false{
continue
}
//更新路径集合和sum
trcak=append(trcak,candidates[i])
sum+=candidates[i]
history[i]=true
//递归
backtracking(i+1,sum,target,candidates,trcak,res,history)
//回溯
trcak=trcak[:len(trcak)-1]
sum-=candidates[i]
history[i]=false
}
}
```
javaScript
```js

View File

@ -407,6 +407,47 @@ var restoreIpAddresses = function(s) {
}
};
```
Go
> 回溯(对于前导 0的IP特别注意s[startIndex]=='0'的判断不应该写成s[startIndex]==0因为s截取出来不是数字
```go
func restoreIpAddresses(s string) []string {
var res,path []string
backTracking(s,path,0,&res)
return res
}
func backTracking(s string,path []string,startIndex int,res *[]string){
//终止条件
if startIndex==len(s)&&len(path)==4{
tmpIpString:=path[0]+"."+path[1]+"."+path[2]+"."+path[3]
*res=append(*res,tmpIpString)
}
for i:=startIndex;i<len(s);i++{
//处理
path:=append(path,s[startIndex:i+1])
if i-startIndex+1<=3&&len(path)<=4&&isNormalIp(s,startIndex,i){
//递归
backTracking(s,path,i+1,res)
}else {//如果首尾超过了3个或路径多余4个或前导为0或大于255直接回退
return
}
//回溯
path=path[:len(path)-1]
}
}
func isNormalIp(s string,startIndex,end int)bool{
checkInt,_:=strconv.Atoi(s[startIndex:end+1])
if end-startIndex+1>1&&s[startIndex]=='0'{//对于前导 0的IP特别注意s[startIndex]=='0'的判断不应该写成s[startIndex]==0因为s截取出来不是数字
return false
}
if checkInt>255{
return false
}
return true
}
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)

View File

@ -258,6 +258,29 @@ class Solution:
Go
> 递归(隐含回溯)
```go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
//递归(隐含回溯)
func sortedArrayToBST(nums []int) *TreeNode {
if len(nums)==0{return nil}//终止条件,最后数组为空则可以返回
root:=&TreeNode{nums[len(nums)/2],nil,nil}//按照BSL的特点从中间构造节点
root.Left=sortedArrayToBST(nums[:len(nums)/2])//数组的左边为左子树
root.Right=sortedArrayToBST(nums[len(nums)/2+1:])//数字的右边为右子树
return root
}
```
-----------------------

View File

@ -312,6 +312,50 @@ class Solution:
```
Go
> 注意切片go切片是披着值类型外衣的引用类型
```go
func partition(s string) [][]string {
var tmpString []string//切割字符串集合
var res [][]string//结果集合
backTracking(s,tmpString,0,&res)
return res
}
func backTracking(s string,tmpString []string,startIndex int,res *[][]string){
if startIndex==len(s){//到达字符串末尾了
//进行一次切片拷贝怕之后的操作影响tmpString切片内的值
t := make([]string, len(tmpString))
copy(t, tmpString)
*res=append(*res,t)
}
for i:=startIndex;i<len(s);i++{
//处理首先通过startIndex和i判断切割的区间进而判断该区间的字符串是否为回文若为回文则加入到tmpString否则继续后移找到回文区间这里为一层处理
if isPartition(s,startIndex,i){
tmpString=append(tmpString,s[startIndex:i+1])
}else{
continue
}
//递归
backTracking(s,tmpString,i+1,res)
//回溯
tmpString=tmpString[:len(tmpString)-1]
}
}
//判断是否为回文
func isPartition(s string,startIndex,end int)bool{
left:=startIndex
right:=end
for ;left<right;{
if s[left]!=s[right]{
return false
}
//移动左右指针
left++
right--
}
return true
}
```
javaScript

View File

@ -284,6 +284,37 @@ class Solution:
Go
> 回溯+减枝
```go
func combinationSum3(k int, n int) [][]int {
var track []int// 遍历路径
var result [][]int// 存放结果集
backTree(n,k,1,&track,&result)
return result
}
func backTree(n,k,startIndex int,track *[]int,result *[][]int){
if len(*track)==k{
var sum int
tmp:=make([]int,k)
for k,v:=range *track{
sum+=v
tmp[k]=v
}
if sum==n{
*result=append(*result,tmp)
}
return
}
for i:=startIndex;i<=9-(k-len(*track))+1;i++{//减枝k-len(*track)表示还剩多少个可填充的元素)
*track=append(*track,i)//记录路径
backTree(n,k,i+1,track,result)//递归
*track=(*track)[:len(*track)-1]//回溯
}
}
```
javaScript:
```js

View File

@ -219,6 +219,26 @@ class Solution:
Go
> 弄一个sum暂存其和值
```go
//右中左
func bstToGst(root *TreeNode) *TreeNode {
var sum int
RightMLeft(root,&sum)
return root
}
func RightMLeft(root *TreeNode,sum *int) *TreeNode {
if root==nil{return nil}//终止条件,遇到空节点就返回
RightMLeft(root.Right,sum)//先遍历右边
temp:=*sum//暂存总和值
*sum+=root.Val//将总和值变更
root.Val+=temp//更新节点值
RightMLeft(root.Left,sum)//遍历左节点
return root
}
```
-----------------------

View File

@ -286,7 +286,33 @@ class Solution:
return root
```
Go
```go
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root==nil{
return nil
}
if root.Val<low{//如果该节点值小于最小值,则该节点更换为该节点的右节点值,继续遍历
right:=trimBST(root.Right,low,high)
return right
}
if root.Val>high{//如果该节点的值大于最大值,则该节点更换为该节点的左节点值,继续遍历
left:=trimBST(root.Left,low,high)
return left
}
root.Left=trimBST(root.Left,low,high)
root.Right=trimBST(root.Right,low,high)
return root
}
```