【前端面试常见算法题系列】32. 最长有效括号(困难)

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

一、题目描述

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

示例 1:

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

示例 2:

输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
复制代码

示例 3:

输入:s = ""
输出:0
复制代码

提示:

  • 0 <= s.length <= 3 * 104
  • s[i]'('')'

二、思路分析

题目要求我们找出最长有效(格式正确且连续)括号子串的长度,有三个限制条件:①括号组合;②返回的是长度;③长度要最长。

对于这种括号问题,我第一想法就是用栈解决。
力扣有一道题是 有效的括号 ,即判断给定的只包含 () 的字符串是否能够闭合,思路是遍历字符串元素的时候,遇到 ( 就压入栈,遇到 ) 就将栈顶元素出栈,最后判断栈是否为空就可以了(当然,如果遇到 ) 的时候,栈就为空了,自然就可以 return false 了)。

这道题难度提升了,但解决方法依然可以用栈,只不过不是压字符串元素入栈,而是 元素下标 入栈。思路如下:

  • -1 入栈(后面解释为什么)。
  • 遍历字符串元素时,遇到 ( 就将其下标入栈,然后继续遍历;
  • 如果遇到 ) 就将栈顶元素 pop 掉,这时候判断栈是否为空,①如果不为空则更新要返回的长度值,找 原来的长度用当前元素的下标减去栈顶元素的下标 的最大值【这就是为什么要实现压入 -1 的原因了:用下标来求长度的话,会发现差值始终为 1 】(那么可以推测出)②栈为空的话,就将当前元素的下标入栈,理由就跟一开始将 -1 入栈一样。
  • 结束遍历的时候返回长度值即可。

三、AC 代码

解法一:时间复杂度为 O(n),空间复杂度为 O(n)

class Solution {
public:
    int longestValidParentheses(string s) {
        int maxNum = 0;
        stack<int> stk;
        stk.push(-1);
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '(') {
                stk.push(i);
            } else {
                stk.pop();
                if (stk.empty()) {
                    stk.push(i);
                } else {
                    maxNum = max(maxNum, i - stk.top());
                }
            }
        }
        return maxNum;
    }
};
复制代码

Guess you like

Origin juejin.im/post/7076450999598055460