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

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

相关推荐
小小龙学IT14 分钟前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研2 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
2501_906565122 小时前
数学之美探究
算法
oier_Asad.Chen2 小时前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
cfm_29142 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
IT_陈寒3 小时前
Python的GIL让我多写了500行代码
前端·人工智能·后端
C++ 老炮儿的技术栈3 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011163 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据3 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
leisoo80974 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法