zoukankan      html  css  js  c++  java
  • [LeetCode] Longest Valid Parentheses

    This problem is a nice extension of the Valid Parentheses problem.

    There are several ways to solve it. The first idea is also to use a stack. However, in this time, we push the index instead of the character itself into the stack. What indexes do we push? Well, we push the indexes which seperate two valid parentheses.

    Let's see an example "()(()" first. In this example, it is clear that the first two are valid and the last two are also valid. Thus the third characters seperate two valid parentheses. We push its index 3 into the stack. Then the longest valid parentheses is either on the left side of it or on the right side of it. For strings that have more than one such indexes, like "())())()", we push all of them into the stack. Then we visit each valid parentheses separated by them and find the longest length. 

    How do we obtain these indexes? In fact, you can simply follow the way in Valid Parentheses. Each time a mismatch occurrs, the current index is what we need.

    You may run the following code on the above examples to get an understanding of how it works.

     1 class Solution {
     2 public:
     3     int longestValidParentheses (string s) {
     4         stack<int> indexes;
     5         for (int i = 0; i < (int)s.length(); i++) {
     6             if (s[i] == '(' || indexes.empty() || s[indexes.top()] != '(')
     7                 indexes.push(i);
     8             else indexes.pop();
     9         }
    10         if (indexes.empty()) return s.length();
    11         int maxlen = 0, left = 0, right = s.length() - 1;
    12         while (!indexes.empty()) {
    13             left = indexes.top();
    14             indexes.pop();
    15             maxlen = max(maxlen, right - left);
    16             right = left - 1;
    17         }
    18         maxlen = max(maxlen, left);
    19         return maxlen;
    20     }
    21 };

     Of course, this problem also has a Dynamic Programming solution. Let's define P[i] to be the length of the longest valid parentheses end at i. Then state equations are:

    1. P[i] = 0 if s[i] == '(' (No valid parentheses end with '(');
    2. P[i] = P[i - 2] + 2 if s[i] == ')' and s[i - 1] == '(', for example, s = '()()';
    3. P[i] = P[i - P[i - 1] - 2] + P[i - 1] + 2 if s[i] == ')' and s[i - 1] == ')' and s[i - P[i - 1] - 1] == '(', for example, s = '(())'.

    Putting these together, we have the following code.

     1 class Solution {
     2 public:
     3     int longestValidParentheses(string s) {
     4         vector<int> dp(s.length(), 0);
     5         int maxlen = 0;
     6         for (int i = 1; i < (int)s.length(); i++) {
     7             if (s[i] == ')') {
     8                 if (s[i - 1] == '(')
     9                     dp[i] = 2 + (i - 2 >= 0 ? dp[i - 2] : 0);
    10                 else if (i - dp[i - 1] - 1 >= 0 && s[i - dp[i - 1] - 1] == '(')
    11                     dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
    12                 maxlen = max(maxlen, dp[i]);
    13             }
    14         }
    15         return maxlen;
    16     }
    17 };

     You may even notice that case 3 above has already includede case 2. So the code can be further shorten to below.

     1 class Solution {
     2 public:
     3     int longestValidParentheses(string s) {
     4         vector<int> dp(s.length(), 0);
     5         int maxlen = 0;
     6         for (int i = 1; i < (int)s.length(); i++) {
     7             if (s[i] == ')' && i - dp[i - 1] - 1 >= 0 && s[i - dp[i - 1] - 1] == '(') {
     8                 dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
     9                 maxlen = max(maxlen, dp[i]);
    10             }
    11         }
    12         return maxlen;
    13     }
    14 };
  • 相关阅读:
    一波骚操作,我把 SQL 执行效率提高了 10,000,000 倍!
    如何优雅地根治null值引起的Bug!
    解锁新姿势:探讨复杂的 if-else 语句“优雅处理”的思路
    39 个奇葩代码注释,看完笑哭了。。。
    只要学会它,再多 Bug 也不怕
    SpringBoot 快速整合Mybatis(去XML化+注解进阶)
    Java 并发异步编程,原来十个接口的活现在只需要一个接口就搞定!
    微服务 2.0 技术栈选型手册
    如何设计 API 接口,实现统一格式返回?
    别在 Java 代码里乱打日志了,这才是打印日志的正确姿势!
  • 原文地址:https://www.cnblogs.com/jcliBlogger/p/4573582.html
Copyright © 2011-2022 走看看