题目:
给定一串字符串,是由左右括号组成,要求判断左右括号是否匹配,不匹配的删除多于的括号使其匹配,返回正确的字符串
解题思路:
1定义两个指针check和delete,表示检查点和删除点,对应检查到哪个idx和应该删除哪个idx
2定义一个int型变量count,记录分数,遇到左括号+1,遇到右括号-1,当count=-1,表示右括号多出一个,就要删除右括号
3执行2之后,删除哪一个右括号,从头找,遇到第一个右括号且它的左边是左括号,就是删除点,删除
4,删除后形成一个新字符串,递归调用检查函数,知道检查完删除完
5右括号检查完,将字符串反转,同样逻辑开始检查左括号,知道左右括号都合规
代码:
package main
import(
"fmt"
)
//"(()))(()()))"
//第一次从左往右遍历,先检查右括号
func barcket(str string,check,delete int,par []string)string{
// check:=0
// delete:=0
// par:=[]string{"(",")"}
count:=0
//查找第一个多于括号的循环
//依然还是要循环
for i:=check;i<len(str)-1;i++{
// fmt.Printf("len==================%v\n",len(str))
// fmt.Printf("iiiiiiiiiiiiiii===%v\n",i)
// fmt.Println(string(str))
// fmt.Println(string(str[i]))
//先从左边往右找左括号“(”,找到+1,找到右括号-1,
if string(str[i])==par[0]{
count++
}
if string(str[i])==par[1]{
count--
}
fmt.Printf("count=====%v\n",count)
//count值变成-1,说明就找到了第一个多余的右括号,
if count<0{
//查找删除点的循环
//这个for循环里先找删除位置,即遇到的第一个左边是左括号的右括号
for j:=delete;j<=i;j++{
if string(str[j])==par[1] && string(str[j-1])==par[0] && j<len(str){
fmt.Println(string(str[j]),string(str[j-1]),j)
//找到后将其删除,跳出查找删除点的循环
str=string(str[0:j])+string(str[j+1:len(str)])
fmt.Println(str)
break
}
}
fmt.Printf("after delete =new str==%v\n",str)
//递归调用,传值是新的字符串和检查点删除点是0值的指针
barcket(str,0,0,par)
return str//return//这里一定要break或者return,不然递归出来后就又接着进入最外层for循环的下一个idx继续执行了
}
}
fmt.Println(str)
// par=[]string{")","("}
fmt.Println(check,delete)
//前面第一个for循环表示正序检查完-删除完,或者没有多余的右括号需要删除了,就要进行下一步,反转字符串,检查左括号是否多于
//这里加if判断,就是要判断执行到哪一步,是执行检查左括号还是右括号,检查完右括号之后str[0]肯定是“(”才能进入下一步反转进行检查左括号
//否则就是左右检查都执行完了,直接返回return
if par[0]=="("{
par=[]string{")","("}
barcket(reverseString([]byte(str)),check,delete,par)
reverseString([]byte(str))
fmt.Println(str)
}else{
return str
}
return str
}
func reverseString(r []byte) string{
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
// fmt.Printf("after delete =new str==%v\n",string(r))
return string(r)
}
func main(){
str:="(()))(()()))"
check:=0
delete:=0
par:=[]string{"(",")"}
// par:=[]string{")","("}
barcket(str,check,delete,par)
// reverseString([]byte(str))
// barcket(reverseString([]byte(str)),check,delete,par)
}
执行过程:
这里有几个我遇到的小坑点总结下:
1 删除点循环for里面的return,如果没有这个return,就会从0删除所有负荷删除条件的括号
2代码第一个递归调用要在检查删除点循环的外层调用,即循环完了break出来再递归
3第一次调用递归后面一定要加上return,不然递归出来后会接着从进入删除点前的idx再来一遍循环
4右括号检查完反转进行左括号检查前,一定要加判断,如过par[0]是“(”才进,这就控制了检查左括号还是右括号
以上就是我看左神视频自己用go实现的代码,不得不佩服大神的代码,记录下来供自己学习