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

以下是使用动态规划解决最长有效括号子串长度的C++实现,包含详细注释和示例测试:

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int longestValidParentheses(string s) {
    int n = s.size();
    if (n <= 1) return 0;
    
    vector<int> dp(n, 0); // dp[i]表示以s[i]结尾的最长有效括号长度
    int max_len = 0;
    
    for (int i = 1; i < n; ++i) {
        if (s[i] == ')') {
            if (s[i-1] == '(') {
                // 情况1:形如 "...()"
                dp[i] = (i >= 2) ? dp[i-2] + 2 : 2;
            } else {
                // 情况2:形如 "...))"
                int prev_len = dp[i-1];
                int prev_start = i - prev_len;
                if (prev_start > 0 && s[prev_start-1] == '(') {
                    dp[i] = dp[i-1] + 2;
                    // 如果前面还有有效序列,可以合并
                    if (prev_start - 2 >= 0) {
                        dp[i] += dp[prev_start-2];
                    }
                }
            }
            max_len = max(max_len, dp[i]);
        }
        // 如果是'(',dp[i]保持为0
    }
    
    return max_len;
}

// 优化空间版本(使用栈的思想,但保持DP解法)
int longestValidParenthesesOptimized(string s) {
    int n = s.size();
    vector<int> dp(n, 0);
    int max_len = 0;
    
    for (int i = 1; i < n; ++i) {
        if (s[i] == ')') {
            if (s[i-1] == '(') {
                dp[i] = (i >= 2 ? dp[i-2] : 0) + 2;
            } else {
                int len = dp[i-1];
                if (i - len > 0 && s[i - len - 1] == '(') {
                    dp[i] = dp[i-1] + 2 + ((i - len - 2 >= 0) ? dp[i - len - 2] : 0);
                }
            }
            max_len = max(max_len, dp[i]);
        }
    }
    
    return max_len;
}

int main() {
    vector<string> test_cases = {
        "(()",       // 2
        ")()())",    // 4
        "",          // 0
        "()(())",    // 6
        "()(()",     // 2
        "((()))())", // 8
        "()((())",   // 6
    };
    
    for (const auto& s : test_cases) {
        cout << "Input: \"" << s << "\"\n";
        cout << "Output: " << longestValidParentheses(s) << "\n";
        cout << "Optimized Output: " << longestValidParenthesesOptimized(s) << "\n\n";
    }
    
    return 0;
}

关键点说明:

  1. 动态规划定义:

    • dp[i] 表示以 s[i] 结尾的最长有效括号子串长度
    • 初始化全为0,因为只有遇到)才可能形成有效子串
  2. 两种情况处理:

    • 情况1 :...()
      • 当s[i] == ')'且s[i-1] == '('时,直接形成新配对
      • 长度 = 前前位置的值 + 2
    • 情况2 :...))
      • 当s[i] == ')'且s[i-1] == ')'时,需要检查是否能与更前面的(配对
      • 计算前一个有效长度prev_len = dp[i-1]
      • 检查s[i-prev_len-1]是否是(
  3. 边界处理:

    • 访问dp[i-2]或dp[prev_start-2]时要确保索引不越界
    • 空字符串或单字符字符串直接返回0
  4. 优化空间:

    • 第二个实现是空间优化版本,但保持了相同的DP思路
    • 实际项目中可以使用更高效的栈方法(O(1)空间)

复杂度分析:

  • 时间复杂度:O(n)(单次遍历字符串)
  • 空间复杂度:O(n)(DP数组)

示例输出:

复制代码
Input: "(()"
Output: 2
Optimized Output: 2

Input: ")()())"
Output: 4
Optimized Output: 4

Input: ""
Output: 0
Optimized Output: 0

Input: "()(())"
Output: 6
Optimized Output: 6

Input: "()(()"
Output: 2
Optimized Output: 2

Input: "((()))()"
Output: 8
Optimized Output: 8

Input: "()((())"
Output: 6
Optimized Output: 6

这个实现正确处理了各种边界情况,包括嵌套括号和连续有效子串的合并。

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
weilx12343 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
大勇前进3 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习