前端算法(30)

57 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

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

题目解析

思路一

用栈进行括号匹配,栈中保存字符索引,最后栈中剩下无法匹配的括号的索引,在新建一个与字符串等长的数组,元素全部填0,将不能匹配的索引值置为1,最后统计连续出现的0的个数,即为连续括号数

/**
 * @param {string} s
 * @return {number}
 */
var longestValidParentheses = function(s) {
    // 用栈保存匹配状态
    let stack = []
    // 匹配数量
    let times = 0
    // 最大值
    let max = 0
    // 字符串长度
    let sLen = s.length
    // 字符串索引
    let index = 0
    // 当前字符
    let char = ''
    // 遍历字符串,栈中保存字符索引
    while (index < sLen) {
        char = s.charAt(index)
        // 遇到左括号,直接入栈
        if (char === '(') {
            stack.push(index)
        } else {
            // 遇到又括号,如果栈顶是左括号,出栈
            if (s[stack[stack.length - 1]] === '(') {
                stack.pop()
            } else {
                // 否则,入栈
                stack.push(index)
            }
        }
        index++
    }
    // 新建一个数组,将无法匹配的索引置1
    const arr = new Array(s.length).fill(0)
    for (let i = 0; i < stack.length; i++) {
        arr[stack[i]] = 1
    }
    // 统计连续出现的0的数量,就是匹配的括号数
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === 1) {
            times = 0
        } else {
            times++
            if (times > max) {
                max = times
            }
        }
    }
    return max
};

思路二

var longestValidParentheses = function(s) {
//栈保存字符串当前位置之前的所有'('的索引
let left = -1,res = 0,n=s.length,stack = [-1] 
    for(let i =0;i<n;i++){
     //每遇到一个'('就将其索引入栈
        if(s[i]=='(') stack.push(i)
        else { 
        //若栈不为空,则弹出栈顶索引 此时此位置一定在当前有效括号内
                stack.pop()
                if(!stack.length){
                //若出栈后栈变为空,有效括号长度可从最初位置算起
                    stack.push(i)
                }else {
                //若不为空,则有效括号长度需从当前栈顶索引之后算起
                    res = Math.max(res,i-stack[stack.length-1])
            }
        }
    }
    return res
};