前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021-07-03:给定一个只由左括号和右括号的字符串,返回最长的有效括号子串的长度。

2021-07-03:给定一个只由左括号和右括号的字符串,返回最长的有效括号子串的长度。

作者头像
福大大架构师每日一题
发布2021-08-05 16:15:22
6510
发布2021-08-05 16:15:22
举报

2021-07-03:给定一个只由左括号和右括号的字符串,返回最长的有效括号子串的长度。

福大大 答案2021-07-03:

1.正向反向。时间复杂度:O(N)。空间复杂度:O(1)。

用栈的思想。遇到(,left加1;遇到),right加1。这个容易想到。

只有当left==right的时候,才统计长度。这个很难想到。

先正向求出长度,然后反向求出长度。这个很难想到。

2.动态规划。时间复杂度:O(N)。空间复杂度:O(N)。

代码用golang编写。代码如下:

代码语言:javascript
复制
package main

import "fmt"

func main() {
    s := "(()()"

    //正向反向
    ret := longestValidParentheses(s)
    fmt.Println("正向反向:", ret)

    //动态规划
    ret2 := longestValidParentheses2(s)
    fmt.Println("动态规划:", ret2)
}

func longestValidParentheses(s string) int {
    N := len(s)
    if N <= 1 {
        return 0
    }
    return getMax(longestValidParenthesesZheng(s), longestValidParenthesesFan(s))
}

func longestValidParenthesesZheng(s string) int {
    N := len(s)
    ans := 0
    left := 0
    right := 0
    for i := 0; i < N; i++ {
        if s[i] == '(' {
            left++
        } else {
            right++
        }
        if left == right {
            ans = getMax(ans, left)
        } else if right > left {
            left = 0
            right = 0
        }
    }
    return ans * 2
}

func longestValidParenthesesFan(s string) int {
    N := len(s)
    ans := 0
    left := 0
    right := 0
    for i := N - 1; i >= 0; i-- {
        if s[i] == '(' {
            left++
        } else {
            right++
        }
        if left == right {
            ans = getMax(ans, left)
        } else if left > right {
            left = 0
            right = 0
        }
    }
    return ans * 2
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

// s只由(和)组成
// 求最长有效括号子串长度
func longestValidParentheses2(s string) int {
    if len(s) < 2 {
        return 0
    }
    // dp[i] : 子串必须以i位置结尾的情况下,往左最远能扩出多长的有效区域
    dp := make([]int, len(s))
    // dp[0] = 0; (  )
    pre := 0
    ans := 0
    for i := 1; i < len(s); i++ {
        if s[i] == ')' {
            // 当前谁和i位置的),去配!
            pre = i - dp[i-1] - 1 // 与str[i]配对的左括号的位置 pre
            if pre >= 0 && s[pre] == '(' {
                if pre > 0 {
                    dp[i] = dp[i-1] + 2 + dp[pre-1]
                } else {
                    dp[i] = dp[i-1] + 2
                }
            }
        }
        ans = getMax(ans, dp[i])
    }
    return ans
}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzu/coding-for-great-offer/blob/main/src/class14/Code01_Parentheses.java)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档