题解 | #最长的括号子串#

最长的括号子串

http://www.nowcoder.com/practice/45fd68024a4c4e97a8d6c45fc61dc6ad

正向逆向结合法

思路:

1、定义三个变量:

  1. leftNum : 表示左括号的数量
  2. rightNum: 表示右括号的数量
  3. maxLen:表示合法括号的最大长度

2、正向遍历

从左往右遍历一次原始括号字符串:

  1. 如果碰到左括号:'(',则 leftNum++;
  2. 如果碰到右括号:')',则 rightNum++;
  3. 如果左右括号数目相等,那么说明此时是一个合法的括号子串,就要更新最大长度:max(maxLen, leftNum + rightNum);
  4. 如果右边的括号数量大于左边的括号数量,也就是rightNum > leftNum, 则说明括号非法,说明此时这个')'加进来后,使得括号子串非法,那么此时也就是说明加进来的这个')' 将前面的合法括号子串和后面的进行了一个分割,所以此时就需要重置左右括号数量为0;例如:
    图片说明

3、逆向遍历

从右往左遍历一次原始括号字符串

  1. 如果碰到左括号:'(',则 leftNum++;

  2. 如果碰到右括号:')',则 rightNum++;

  3. 如果左右括号数目相等,那么说明此时是一个合法的括号子串,就要更新最大长度:max(maxLen, leftNum + rightNum);

  4. 如果左边的括号数量大于右边的括号数量,也就是 leftNum > rightNum , 则说明括号非法,说明此时这个'('加进来后,使得括号子串非法,那么此时也就是说明加进来的这个'(' 将前面的合法括号子串和后面的进行了一个分割,所以此时就需要重置左右括号数量为0;(此处逻辑和第二步类似)

    思考:那么为什么要逆向遍历一次?

    请看如下情况:
    当出现第②种情况的时候,会出现左右括号数量不一致的情况,那么可以再次进行一次逆向遍历,然后求出长度,更新长度,才是最终的长度;
    图片说明

    代码:

    import java.util.*;
    public class Solution {
     /**
      * @param s string字符串 
      * @return int整型
      */
     public int longestValidParentheses (String s) {
         if(s == null || s == ""){
             return 0;
         }
         int len = s.length();
         int leftNum = 0;
         int rightNum = 0;
         int maxLen = 0;
         // 左 --> 右
         for(int i = 0; i<len; i++){
             char c = s.charAt(i);
             if(c == '('){
                 leftNum++;
             }else{
                 rightNum++;
             }
             if(leftNum == rightNum){
                 maxLen = Math.max(maxLen, leftNum + rightNum);
             }else if(rightNum > leftNum){
                 leftNum = 0;
                 rightNum = 0;
             }
         }
    
         // 从右到左
         leftNum = 0;
         rightNum = 0;
         for(int i = len-1; i>=0; i--){
             char c = s.charAt(i);
             if(c == '('){
                 leftNum++;
             }else{
                 rightNum++;
             }
             if(leftNum == rightNum){
                 maxLen = Math.max(maxLen, leftNum + rightNum);
             }else if(rightNum < leftNum){
                 leftNum = 0;
                 rightNum = 0;
             }
         }
         return maxLen;
     }
    }
全部评论

相关推荐

02-14 12:40
门头沟学院 Java
程序员花海:1.面试要求必须Java笔试不一定 2.难度对等秋招 远超于日常实习是因为同一批次且转正很多 竞争压力大 3.第一个加点指标,上线了就把接口性能加上去 使用本地缓存这个不算亮点 只是技术选型,要把为什么采用这个和背后的思考写出来而不是单纯堆叠技术没意义 4.八股要一直看 很容易忘记 5.拼团交易这个老问题 堆积技术 另外建议你把奖项合并到教育背景 没必要拆出来放最后
我的简历长这样
点赞 评论 收藏
分享
程序员小白条:三方不签,不就是纯实习骗人吗,还是小公司,没毛了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务