zoukankan      html  css  js  c++  java
  • leetcode每日一题(2020-07-04):32. 最长有效括号

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

    注意:我连续想错了两次题目意思,可以嵌套,只要左右匹配就好

    今日学习:
    1.察觉到异常的时候要把它揪出来想,不要忽视它

    题解:
    1.维护一个栈,但是栈中存的并不是左括号,而是左括号的索引,这样就可以每次都计算出子串的长度了
    2.左右遍历s,计算左右括号数量是否匹配
    3.这道题动规真难,没想明白,我放弃了

    // 错误题解:维护一个'('栈,但是想法有一些问题,有些情况没考虑进去
    var longestValidParentheses = function(s) {
        let res = 0, count = 0, later = 0
        let stack = []
        for(i = 0; i < s.length; i++) {
            if(s[i] == '(') {
                stack.push(s[i])
            }else {
                if(stack.length == 0) {
                    res = Math.max(res, count)
                    count = 0
                }else {
                    stack.pop()
                    count += 2
                }
            }
        }
        res = Math.max(res, count)
        return res
    }
    // 还是维护栈,但是栈存的是索引而不是括号
    var longestValidParentheses = function(s) {
        let start = s.indexOf('(')
        let end = s.lastIndexOf(')')
        if(start == -1 || end == -1 || start > end) return 0
        s = s.slice(start, end + 1)
        // 前四行可以处理掉一些极端情况,有没有都可以
        let maxLen = 0;
        // 预存索引-1,方便计算长度,也是作为新的开始
        const stack = [-1];
        for(let i = 0; i < s.length; i++) {
            const c = s[i];
            if(c == '(') {  // 左括号的索引入栈 
                stack.push(i);
                continue;      // 跳过,考察下一个符号
            }
            stack.pop();     // 遇到右括号,栈顶出栈
            if(stack.length == 0) { // 栈顶因此为空
                stack.push(i);         // 说明该更换“断点”索引了
            }else {                 // 计算有效的连续长度,挑战最大
                maxLen = Math.max(maxLen, i - stack[stack.length - 1]);
            }
        }
        return maxLen;
    };
    // 左右算括号数量的思想
    var longestValidParentheses = function(s) {
        let start = s.indexOf('(')
        let end = s.lastIndexOf(')')
        if(start == -1 || end == -1 || start > end) return 0
        s = s.slice(start, end + 1)
        // 前四行可以处理掉一些极端情况,有没有都可以
        let left = right = 0, maxLen = 0
        // 从左到右遍历
        for(let i = 0; i < s.length; i++) {
            //遇到左括号或者右括号,对应数量+1
            if(s.charAt(i) == '(') {
                left++
            }else {
                right++
            }
            // 如果数量相等,说明符合子串要求,计算当前长度
            // 如果右大于左,没有继续计算长度的必要,left和right归零
            if(left == right) {
                maxLen = Math.max(maxLen, 2 * left)
            }else if(right > left) {
                left = right = 0
            }
        }
        // 从右往左遍历,思路一致
        left = right = 0
        for(let i = s.length - 1; i >= 0; i--) {
            if(s.charAt(i) == ')') {
                right++
            }else {
                left++
            }
            if(left == right) {
                maxLen = Math.max(maxLen, 2 * left)
            }else if(left > right) {
                left = right = 0
            }
        }
        return maxLen
    }
    
  • 相关阅读:
    C#与数据库访问技术总结(十一)之数据阅读器(DataReader)1
    C#与数据库访问技术总结(十)之添加&删除
    C#与数据库访问技术总结(九)之实例
    C#与数据库访问技术总结(八)之ExecuteNonQuery方法
    C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例
    C#与数据库访问技术总结(七)综合示例
    C#与数据库访问技术总结(五)之Command对象的常用方法
    OS——进程简答题(1)
    LAMP/LNMP 一键安装脚本
    运维如何延续自己的职业生涯--萧田国2017年GOPS深圳站演讲内容
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13234183.html
Copyright © 2011-2022 走看看