【LeetCode】每日一题(二十)32. 最长有效括号 栈动态规划

    技术2025-04-04  19

    32. 最长有效括号

    20200704

    难度:困难

    题目描述

    给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

    示例 1:

    输入: "(()" 输出: 2 解释: 最长有效括号子串为 "()"

    示例 2:

    输入: ")()())" 输出: 4 解释: 最长有效括号子串为 "()()"

    Solution

    class Solution { public int longestValidParentheses(String s) { int ans = 0; Stack<Integer> stack = new Stack<>(); stack.push(-1); for(int i = 0; i < s.length(); i++){ if(s.charAt(i) == '('){ stack.push(i); }else{ stack.pop(); if(stack.isEmpty()){ stack.push(i); }else{ ans = Math.max(ans, i-stack.peek()); } } } return ans; } } 动态规划 状态:dp[i]代表以下标i字符结尾的最长有效括号的长度状态转移: 若下标i的字符(记为s[i])为(,dp[i] = 0s[i] == ')' s[i-1] == '('时,dp[i] = dp[i-2] + 2s[i-1] == ')'时,这时要去除中间已经成为有效括号的部分来看,也就是看s[i-dp[i-1]-1]是(还是) 若s[i-dp[i-1]-1] == (,也就是有效括号的长度还会增加,dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2。其中dp[i-1]为中间段,dp[i-dp[i-1]-2] + 2为两边段。 class Solution { public int longestValidParentheses(String s) { int ans = 0; int dp[] = new int[s.length()]; for(int i = 1; i < s.length(); i++){ if(s.charAt(i) == ')'){ if(s.charAt(i-1) == '('){ dp[i] = i >= 2 ? dp[i-2] + 2 : 2; }else if(i-dp[i-1] > 0 && s.charAt(i-dp[i-1]-1) == '('){ dp[i] = dp[i-1] + (i-dp[i-1] >= 2 ? dp[i-dp[i-1]-2] : 0) + 2; } ans = Math.max(ans, dp[i]); } } return ans; } }

    欢迎关注公众号:GitKid,暂时每日分享LeetCode题解,在不断地学习中,公众号内容也在不断充实,欢迎扫码关注

    Processed: 0.009, SQL: 9