面试题 生成有效的括号序列(递归 回溯)

1 篇文章 0 订阅
1 篇文章 0 订阅

题目描述

字符串生成:有效的括号为只包括’{’,’}’,’[’,’]’ 的字符串,给定一个输入参数N,N表括号的对数,输出所有有效的字符串序列
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
样例1: 输入:N=1,输出:["[]","{}"]
样例3: 输入:N=2,输出:["[[]]","[{}]","[][]","[]{}","{}[]","{}{}","{[]}","{{}}"]

var leftParenthesis = [2]string{"[", "{"}

func getRightParenthesis(s string) string {
	var res string
	switch s {
	case "[":
		res = "]"
	case "{":
		res = "}"
	}
	return res
}

func createParenthesis(curStr string, leftCount, rightCount, n int, leftStack Stack, res *[]string) {
	// 递归退出条件
	if leftCount == n && rightCount == n && leftStack.length <= 0 {
		*res = append(*res, curStr)
		return
	}
	for i := 0; i < 2; i++ {
		//循环尝试不同种类的括号
		temp := leftParenthesis[i]
		if leftCount < n { //插入左括号的判断条件
			leftStack.Push(temp)
			createParenthesis(curStr+temp, leftCount+1, rightCount, n, leftStack, res)
			leftStack.Pop() // 回溯思想,进行一次尝试后还原现场
		}
		if rightCount < n && rightCount < leftCount && leftStack.length > 0 { //插入右括号的判断条件
			rightParenthesis := getRightParenthesis(temp)
			if leftStack.top.value.(string) == temp { //判断左右括号是否匹配
				tempStack := leftStack.Pop()
				createParenthesis(curStr+rightParenthesis, leftCount, rightCount+1, n, leftStack, res)
				leftStack.Push(tempStack.(string)) // 回溯思想,进行一次尝试后还原现场
			}
		}
	}
}

func generateParenthesis(n int) []string {
	if n <= 0 {
		return nil
	}
	res := make([]string, 0)
	var leftStack = Stack{nil, 0}
	leftCount, rightCount := 0, 0
	createParenthesis("", leftCount, rightCount, n, leftStack, &res)
	return res
}

func main() {
	result := generateParenthesis(2)
	fmt.Printf("result size is %d,\nParenthesis is %s", len(result), result)
}

引入栈,判断括号有效性

因为插入右括号的时候,要判断该右括号和最新的左括号是否匹配,只有匹配的括号才能插入

type (
	Stack struct {
		top    *node
		length int
	}
	node struct {
		value interface{}
		prev  *node
	}
)

// Create a new stack
func New() *Stack {
	return &Stack{nil, 0}
}

// Return the number of items in the stack
func (this *Stack) Len() int {
	return this.length
}

// View the top item on the stack
func (this *Stack) Peek() interface{} {
	if this.length == 0 {
		return nil
	}
	return this.top.value
}

// Pop the top item of the stack and return it
func (this *Stack) Pop() interface{} {
	if this.length == 0 {
		return nil
	}

	n := this.top
	this.top = n.prev
	this.length--
	return n.value
}

// Push a value onto the top of the stack
func (this *Stack) Push(value interface{}) {
	n := &node{value, this.top}
	this.top = n
	this.length++
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值