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

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

相关推荐
张张123y1 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
likexuec2 小时前
数据结构(2)
数据结构
Navigator_Z3 小时前
LeetCode //C - 1317. Convert Integer to the Sum of Two No-Zero Integers
c语言·算法·leetcode
wo_jack3 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH3 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
量化分析码农4 小时前
【Python量化波动率实战 02】波动率会传染:EWMA 指数加权给近期行情更大话语权
后端
冻柠檬飞冰走茶4 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing034 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊4 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法