Gemini永久会员 Go 返回最长有效子串长度

Go 返回最长有效子串长度

以下是几种在 Go 中实现查找最长有效括号子串长度的方法:

方法一:动态规划

go 复制代码
func longestValidParentheses(s string) int {
    n := len(s)
    if n == 0 {
        return 0
    }
    
    dp := make([]int, n)
    maxLen := 0
    
    for i := 1; i < n; i++ {
        if s[i] == ')' {
            if s[i-1] == '(' {
                if i >= 2 {
                    dp[i] = dp[i-2] + 2
                } else {
                    dp[i] = 2
                }
            } else {
                prev := i - dp[i-1] - 1
                if prev >= 0 && s[prev] == '(' {
                    dp[i] = dp[i-1] + 2
                    if prev > 0 {
                        dp[i] += dp[prev-1]
                    }
                }
            }
            if dp[i] > maxLen {
                maxLen = dp[i]
            }
        }
    }
    
    return maxLen
}

方法二:栈

go 复制代码
func longestValidParentheses(s string) int {
    maxLen := 0
    stack := []int{-1} // 初始化栈底元素
    
    for i, char := range s {
        if char == '(' {
            stack = append(stack, i)
        } else {
            stack = stack[:len(stack)-1] // 弹出栈顶元素
            if len(stack) == 0 {
                stack = append(stack, i) // 记录新的基准点
            } else {
                currentLen := i - stack[len(stack)-1]
                if currentLen > maxLen {
                    maxLen = currentLen
                }
            }
        }
    }
    
    return maxLen
}

方法三:双向遍历(最优空间复杂度)

go 复制代码
func longestValidParentheses(s string) int {
    left, right, maxLen := 0, 0, 0
    
    // 从左到右遍历
    for i := 0; i < len(s); i++ {
        if s[i] == '(' {
            left++
        } else {
            right++
        }
        
        if left == right {
            if 2*right > maxLen {
                maxLen = 2 * right
            }
        } else if right > left {
            left, right = 0, 0
        }
    }
    
    left, right = 0, 0
    // 从右到左遍历
    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '(' {
            left++
        } else {
            right++
        }
        
        if left == right {
            if 2*left > maxLen {
                maxLen = 2 * left
            }
        } else if left > right {
            left, right = 0, 0
        }
    }
    
    return maxLen
}

使用示例

go 复制代码
package main

import "fmt"

func main() {
    fmt.Println(longestValidParentheses("(()"))      // 输出: 2
    fmt.Println(longestValidParentheses(")()())"))   // 输出: 4
    fmt.Println(longestValidParentheses(""))         // 输出: 0
    fmt.Println(longestValidParentheses("()(()"))    // 输出: 2
    fmt.Println(longestValidParentheses("()(())"))   // 输出: 6
}

方法比较

  1. 动态规划

    • 时间复杂度:O(n)
    • 空间复杂度:O(n)
    • 优点:直观易懂,容易实现
    • 缺点:需要额外的数组空间
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)
    • 优点:思路清晰,利用栈的特性
    • 缺点:同样需要额外空间
  2. 双向遍历

    • 时间复杂度:O(n)
    • 空间复杂度:O(1)
    • 优点:空间效率最高
    • 缺点:需要两次遍历

这些方法都能有效解决最长有效括号子串长度的问题,可以根据具体需求选择合适的方法。

相关推荐
通信仿真爱好者19 小时前
第【60期】--大规模MIMO系统信号检测算法误码率比较 --matlab完整代码+参考文章
算法·matlab·mimo·信号检测
梨子同志19 小时前
Docker
后端
woxiangkaile19 小时前
kernel6.1 新增驱动
后端
AI科技星19 小时前
全域谱分析:无穷维超复数信息场分形统一场论——自然、量子、金融多重分形第一性原理完整体系(中英双语终稿)
人工智能·python·算法·金融·乖乖数学·全域数学
utf8mb4安全女神19 小时前
【Redis数据库】哨兵集群/redis集群/安装配置/主从复制/数据持久化操作/数据结构/安全限制/PHP redis/
linux·服务器·数据结构·数据库·redis·缓存
高明珠20 小时前
麒麟 V10 SP1 踩坑:`./startup.sh` 报“解释器错误: 权限不够“,根因是 KySec
后端
用户83580861879120 小时前
基于Redis的分布式锁优化实践:从Redlock到自适应自旋的实现与思考
后端
掘金者阿豪20 小时前
想让短视频自动生产?用MoneyPrinterTurbo搭一个远程可控的AI创作平台
后端
先吃饱再说20 小时前
为什么堆能 O(log n) 插入?拆解完全二叉树的数组魔法
算法·排序算法
梨子同志20 小时前
开发工具
前端·后端