括号生成
golang的错误解法:这里会由于append底层会创建一个新的切片,然后把老的切片中的元素往这个新的切片中加,最后把新的添加元素加入到新的切片中,最后返回新的切片,因此helper中的list不会影响到外层的list
func generateParenthesis(n int) []string {list := make([]string,0)helper(n,n,"",list)return list // []}func helper(left int,right int,str string,list []string) {if right == 0 {// 不会影响到外部,append在底层会创建一个新的list来添加,添加以后再把新的list返回,但返回的结果不会影响到实参list = append(list,str)return}if left==right{str1 := str + "("helper(left-1,right,str1,list)}else{if left > 0{str1 := str + "("helper(left-1,right,str1,list)}str2 := str + ")"helper(left,right-1,str2,list)}}
golang正确解法:需要将外层list中的切片的地址传递给helper,那么在执行*list = append(*list,str)的时候相当于将外层的list引用到了新的切片地址
func generateParenthesis(n int) []string {list := make([]string,0)helper(n,n,"",&list)return list // []}func helper(left int,right int,str string,list *[]string) {if right == 0 {// 通过*list添加可以影响到外部,相当于把generateParenthesis中的list指向改变了*list = append(*list,str)return}if left==right{str1 := str + "("helper(left-1,right,str1,list)}else{if left > 0{str1 := str + "("helper(left-1,right,str1,list)}str2 := str + ")"helper(left,right-1,str2,list)}}
指针,切片的相关用法介绍
直接通过list[idx]来进行修改,修改的结果会影响到外部的实参
list[idx]相当于直接修改其对应空间的下标为idx的值
func generateParenthesis(n int) []string {list2 := make([]string,1)test2(list2)return list2 //["()()"]}func test2(list1 []string) {// 直接修改会影响外部,前提是list1有这样的空间下标list1[0] = "()()"}

通过append()+直接传入切片来修改,修改的结果不会影响到外部的实参
append创造了一个新的切片,这个新的切片给了形参,但实参不受影响。刚传入的时候,形参和实参都是指向同一块空间,但append以后形参指向了其他的空间,导致实参不受影响
func generateParenthesis(n int) []string {list := make([]string,0)test(list)return list //[]}func test(list []string) {// 通过append添加的结果不会影响外部list = append(list,"()()","()()","()()")}

通过append()+传入切片的地址来修改,修改的结果会影响到外部的实参
实际上是通过修改实参的指向
func generateParenthesis(n int) []string {list := make([]string,0)test3(&list)return list //[“()()”]}func test3(listptr *[]string){// 会影响到外部,修改的是实参的指向*listptr = append(*listptr,"()()")}

总结:
golang中对于基本数据类型,如果希望函数内的操作可以影响到实参,那么就应该传入基本数据类型的地址值,函数内所有的操作都是对*v进行操作
golang中对于引用数据类型,如果希望函数内的操作可以影响到实惨,推荐传递引用数据类型的地址值,函数内的所有操作都是对*slice进行操作。
总之传入的实参是地址的话,函数内对*v的操作本质上都是对外部实参对操作。
算法训练营永久vip学习班【目前主要采用的编程语言是go语言】
golang算法训练营报名详情如下,快加入我们吧,永久授课和学习,我自己负责的课程会一直维护下去~
奔跑的小梁,公众号:梁霖编程工具库算法训练营golang专题刷题来啦!!!
文章转载自梁霖编程工具库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




