• leetCode 32. Longest Valid Parentheses


    Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

    Example 1:

    Input: "(()"
    Output: 2
    Explanation: The longest valid parentheses substring is "()"
    

    Example 2:

    Input: ")()())"
    Output: 4
    Explanation: The longest valid parentheses substring is "()()"

    超过17.81%,不是用的栈。

    基本思路是:

      从左至右遍历字符串,找出所有这样的子串[begin,end],其任意的子串的左括号数量>有括号数量。将这样的区间放入一个区间链表left中。

      然后从右至左遍历字符串,找出所有这样的字符串[begin,end],其任意的子串的右括号数量>左括号的数量。 将这样的区间放入一个区间链表right中。

      取两个区间集合left,right的交集。最大的子区间的元素数量就是最终结果。

     

      当然区间取交集时,用二分查找还能更快,懒得写了。时间复杂度应该为O(n^2)。

     1 class Solution {
     2     class Perfect {
     3         int start;
     4         int end;
     5 
     6         public Perfect(int start, int end) {
     7             this.start = start;
     8             this.end = end;
     9         }
    10 
    11         @Override
    12         public String toString() {
    13             return "[" + start +
    14                     "," + end +
    15                     ']';
    16         }
    17     }
    18 
    19     public int longestValidParentheses(String s) {
    20         int LL = 0, LR = 0, RL = 0, RR = 0;
    21         List<Perfect> left = new ArrayList<>();
    22         List<Perfect> right = new ArrayList<>();
    23         int RLborder=s.length()-1,LRborder=0;
    24         for (int i = 0; i < s.length(); i++) {
    25             //L-->R
    26             if (s.charAt(i) == '(')
    27                 ++LL;
    28             else
    29                 ++LR;
    30             if (LR > LL) {
    31                 int start = i - (LL + LR) + 1;//有问题
    32                 int end = i - 1;
    33                 if (start >= 0 && end >= 0 && start < end)
    34                     left.add(new Perfect(start, end));
    35                 LR = LL = 0;
    36                 LRborder=i+1;
    37             }
    38             if (i == s.length() - 1 && LR == LL && LR != 0) {
    39                 left.add(new Perfect(s.length() - LR - LL, s.length() - 1));
    40             }
    41 
    42 
    43             //R-->L
    44             if (s.charAt(s.length() - 1 - i) == '(')
    45                 ++RL;
    46             else
    47                 ++RR;
    48             if (RL > RR) {
    49                 int start = s.length() - i;
    50                 int end = s.length() - 1 - i + RL + RR - 1;
    51                 if (start >= 0 && end <= s.length() - 1 && start < end)
    52                     right.add(new Perfect(start, end));
    53                 RL = RR = 0;
    54                 RLborder=s.length()-1-i-1;
    55             }
    56             if (s.length() - 1 - i == 0 && RL == RR && RL != 0) {
    57                 right.add(new Perfect(0, RL + RR - 1));
    58             }
    59         }
    60         if (LR < LL && s.length()-LRborder !=1) {
    61             left.add(new Perfect(LRborder,s.length()-1));
    62         }
    63         if (RL < RR && RLborder-0!=1) {
    64             right.add(new Perfect(0, RLborder));
    65         }
    66 
    67 
    68         for (int j = 0; j < left.size(); j++) {
    69             System.out.println(left.get(j));
    70         }
    71         System.out.println("*********");
    72         for (int j = right.size() - 1; j >= 0; --j) {
    73             System.out.println(right.get(j));
    74         }
    75 
    76         //取left和right的交集
    77         int res = 0;
    78         for (int i = 0; i < left.size(); i++) {
    79             //left的i位置区间和right的j区间做交集
    80             for (int j = right.size()-1; j >=0; j--) {
    81                 int maxStart = Math.max(left.get(i).start, right.get(j).start);
    82                 int minEnd = Math.min(left.get(i).end, right.get(j).end);
    83                 if (maxStart < minEnd) {
    84                     res = res < minEnd - maxStart +1  ? minEnd - maxStart+1 : res;
    85                 }else if (left.get(i).start > right.get(j).end){
    86                     continue;
    87                 }else
    88                     break;
    89             }
    90         }
    91         return res;
    92     }
    93 }

     来一个猛的,动态规划解法,超过84.29%

    基本思路是:

      d[i]:表示以i结尾的最长匹配的字符串长度。

      最完美匹配字符串定义:(代码中用len表示)

        像这样的:(), (()),(((())))。

      我们只需要看i位置的最完美匹配字符串能否和前面的最长匹配字符串能不能连在一起构成一个较大的最长匹配字符串即可。

     1 class Solution {
     2     public int longestValidParentheses(String s) {
     3         int[] d = new int[s.length()];
     4         int max = 0;
     5 
     6         for (int i = 1; i < s.length(); i++) {
     7             //查找以i位置结尾的最完美匹配
     8             int len = 0;
     9             if (i-1-d[i-1]>=0 && s.charAt(i) == ')' && '(' == s.charAt(i - 1 - d[i - 1])){// (())
    10                 len=d[i-1]+2;
    11             }else if (!(s.charAt(i)==')' && s.charAt(i-1)=='(')){// ())
    12                 len=0;
    13             }else {// (() || ()
    14                 len = 2;
    15             }
    16 
    17 
    18             if (i-len>=0 && len!=0){
    19                 d[i]=d[i-len]+len;
    20             }else {
    21                 d[i]=len;
    22             }
    23 
    24             max = (max < d[i]) ? d[i] : max;
    25         }
    26         return max;
    27     }
    28 }
  • 相关阅读:
    数据可视化需要简化编程
    设计模式之工厂模式
    LinCode落单的数
    怎样安装解压版MySQL
    程序阅读:简单C++学生信息管理系统
    中缀式变后缀式
    jquery动态创建表格
    Android笔记——Activity中的回传数据案例(装备选择)
    A mail sent to Google chromium.org Groups for Help
    Eclipse导入MyEclipseproject(web项目显示为java项目解决的方法)
  • 原文地址:https://www.cnblogs.com/yfs123456/p/10990728.html
Copyright © 2020-2023  润新知