合法的括号序列 | 记忆化搜索 Go

合法的括号序列

https://www.nowcoder.com/practice/cd3c583ac7054a18b164fbd4ec3247c4

题意

给定一个仅包含'('、')'和'?'三种字符构成的字符串,'?'字符可以代替左括号或者右括号。请问该字符串可以代表多少种不同的合法括号序列?

思路

看基本上都写的dp,来个记忆化搜索的代码吧

每个?字符都有两种可能,填左括号或是填右括号,可以枚举填哪个进行记忆化搜索

如何判断是合法的括号序列?只需要维护左括号比右括号多了几个就可以,也就是当前没有配对的右括号个数。假设为val,如果当前是左括号,那么下一次dfs的参数肯定是val+1;如果当前是右括号,下一次dfs参数是val-1,表示可以配对一个左括号。注意这里其实会有不合法情况,就是其实左边是没有左括号的,也就是val为负数的情况,需要在dfs开始就判断下。

边界条件就是如果遍历完了所有的字符串,如果左括号和右括号一样多,就是合法的,返回1;否则,返回0

这里是从1到n写的记忆化搜索,也可以从n到1,一样的思路

注意取模

package main

import "fmt"

func main() {
	/*
		给定一个仅包含'('、')'和'?'三种字符构成的字符串,'?'字符可以代替左括号或者右括号。请问该字符串可以代表多少种不同的合法括号序列?
	*/
	const MOD = 1_000_000_007
	var s string
	fmt.Scan(&s)
	n := len(s)
	s = " " + s
	var dfs func(int, int) int

	/*
		子问题:如果当前字符是?的话填什么 可以填左括号 也可以填右括号
		两种选择
		val表示没有配对的左括号数量
	*/
	dp := make([][]int, n+1)
	for i := 1; i <= n; i ++ {
		dp[i] = make([]int,n+1)
		for j := 0; j <= n; j ++{
			dp[i][j] = -1 
		}
	}
	
	dfs = func(idx int, val int) int {
		if val < 0 {
			return 0
		}
		if idx == n+1 {
			//结束
			if val == 0 {
				return 1
			} else {
				return 0
			}
		}
		if dp[idx][val] != -1 {
			return dp[idx][val]
		}
		var res = 0
		if s[idx] == '?' {
			//这一位填(
			res = (res + dfs(idx+1, val+1)) % MOD
			//这一位填) 
			res = (res + dfs(idx + 1, val - 1 )) % MOD
		}else if s[idx] == '(' {
			res = dfs(idx+1,val+1) 
		}else{
			res = dfs(idx+1,val-1) 
		}
		dp[idx][val] = res
		return res
	}
	fmt.Println(dfs(1,0))
}

#牛客创作赏金赛#
15天大厂真题带刷Go题解 文章被收录于专栏

15天大厂真题带刷Golang题解

全部评论

相关推荐

德科信息 华为OD岗位 20K+ 统招本科
点赞 评论 收藏
分享
断电再接线:1. 简历排版方面,你这内容比较少,一页放完。各模块之间建议用明显的分隔线分开,现在一眼看上去非常乱。教育经历留白太多。项目经历格式不统一。 2. 第一个项目,硬件设计太笼统,硬件架构规划是指板级电路设计还是FPGA逻辑设计?FPGA时序逻辑设计具体指的什么?实现的三个低速协议以及使用协议进行控制时序,是指什么? 3. 第二个项目,我觉得你可以和第一个项目整合一下,合并为一个项目。第二个项目说实话随便买个zynq开发板都有一直petalinux的教程,作为一个独立的项目不合适的,更像是一个小作业。 4. 第三个项目,项目内容这里,其实和环境搭建之类的东西提一嘴就好了,环境准备和编译安装工具链这种东西没多大必要写,实在要写的话可以 说 使用docker 独立sdk环境之类的。你说的这个工具我没用过,我用的比较多的是busybox和buildroot,是基于menuconfig进行配置的,如果scratch也是类似的模式的话,那我觉得这个项目也经不起细推。你可以往内核裁剪那方向靠,我说的这两个工具你也可以看看。 5. 你熟悉这些接口时序的话,你可以进一步去看一下驱动开发,然后面试的时候突出这个作为重点。第三个项目也可以将驱动开发给补充进去。因为单编内核和构建文件系统,其实很多时候是体力劳动。 6. 特长这里,独立成一个荣誉奖项的模块,把你获得的奖学金和竞赛奖项放一起。数模的话,写了国赛,美赛就不用写了。 7. 总的来说可以了,你简历上写的东西你只要都熟悉,找个实习还是没问题的。 8. 嵌入式分为硬件,底层软件和应用软件,看你的经历我建议你往底层靠,多去熟悉常用的通信接口,去看内核和驱动,网络编程这块也可以去了解一下。然后去**刷刷hot100
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务