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

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

相关推荐
Star Learning Python2 分钟前
30道经典java面试题
java·开发语言
wearegogog1233 分钟前
NOMA下行链路用户与信道功率分配优化MATLAB实现
开发语言·matlab
程序员鱼皮3 分钟前
你的 IP 归属地,是咋被挖出来的?
前端·后端·计算机·程序员·互联网·编程经验
jiayong236 分钟前
Word图文混排实战技巧
开发语言·c#·word
hqwest7 分钟前
码上通QT实战27--系统设置02-加载用户列表
开发语言·qt·sqlite·qtablewidget
Ka1Yan7 分钟前
[链表] - 代码随想录 24. 两两交换链表中的节点
数据结构·链表
rit843249913 分钟前
有限元算法求解铁木辛柯梁梁静力问题实例
算法
智驱力人工智能15 分钟前
矿山皮带锚杆等异物识别 从事故预防到智慧矿山的工程实践 锚杆检测 矿山皮带铁丝异物AI预警系统 工厂皮带木桩异物实时预警技术
人工智能·算法·安全·yolo·目标检测·计算机视觉·边缘计算
Python_Study202517 分钟前
制造业企业如何构建高效数据采集系统:从挑战到实践
大数据·网络·数据结构·人工智能·架构
忆锦紫18 分钟前
图像降噪算法:中值滤波算法及MATLAB实现
图像处理·算法·matlab