【算法】Longest Valid Parentheses 最长

作者: 无良剑染 | 来源:发表于2020-03-18 12:43 被阅读0次

题目

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 "()()"

给出一个只含有 "("、")" 的字符串,寻找字符串中最长的有效括号的长度。

解题思路

这里就需要分析一下 "()" 的特性了:

  1. "()" 的长度为 2
  2. ”()“ 左右位置若存在有效括号,则可以进行拼接
  3. "()" 若有效,且其中间位置存在字符,则中间的字符串也一定为有效括号

依据这三点特性,可以考虑如下思路来寻找最长括号:

  1. 从左到右遍历字符串,找到有效的括号,并计算其本身的长度
    • 以找到 ")" 为 当前标识 ,再寻找与其匹配的 "(",若找到则为有效括号
    • 假设当前有效括号中间含有有效括号M,寻找与其匹配的 "("
      • 找到当前字符 ")" 的位置为 i ,每个有效括号的当前最长长度存进 max[i],
      • 当前位置 i 左移到 有效括号M 的左侧( 左移 max[i-1] + 1 位),即为当前有效括号的 "(" 的位置 j = i - 1 - max[i-1]
      • 当且仅当位置 j 的字符存在且为 "(" 时,当前有效括号的假设才成功,当前有效括号的长度为当前左右括号长度 2 加上 有效括号M 的长度 max[i-1],( 2 + max[i-1])
  2. 由于是从左到右遍历,所以若左边位置为有效括号(有效括号L),计算最长长度时,需要加上 有效括号L 的长度 max[j-1]
  3. 计算完 max[i] 与结果容器 res 做较大值比较,赋较大值给 res
  4. 遍历结束,返回 res 即为最长有效括号的长度

PS: 有效括号M 若存在,其长度为 max[i-1] 有值, 有效括号M 若不存在 max[i-1] 为 0,若 当前有效括号 中间位置没有字符时,i-1 位置为 "(",其在max的值max[i-1]也为 0 ,所以 当前有效括号 中间没有字符时的长度计算方式和 有效括号M 不存在时的计算方式是一致的,用 j = i - 1 - max[i-1] 寻找匹配 "(" 的方式可以同时解决。

代码实现

Runtime: 12 ms
Memory: 20.9 MB

func longestValidParentheses(_ s: String) -> Int {
        let len = s.count
        // 长度小于 2 的时候,成不了一组 () 所以返回 0
        if len < 2 {
            return 0
        }
        // 将 s 转换成数组,方便操作
        let s = Array(s)
        // max 数组 记录当前有效括号最大长度
        var max = Array(repeating: 0, count: len)
        // res 作为结果
        var res = 0
        // 从 1 开始遍历 s
        for i in 1 ..< len {
            // 只有当前字符为 ")" 时,才有可能出现有效括号
            if s[i] == ")" {
                // 用 i 减去 max[i-1] 的中间位置有效括号长度,再减去当前字符长度 1,即为与当前有效括号的 ( 的位置 j
                let j = i - 1 - max[i-1];
                // 只有当 j >= 0,并且 s[j] 为 ( 时,有效括号才匹配
                if j >= 0 && s[j] == "(" {
                    //有效括号匹配,更新 max[i] 的值,当前成对括号长度 2 ,中间位置有效括号长度 max[i-1],左侧有效括号长度 max[j-1],加和在一起
                    max[i] = 2 + max[i-1] + (j > 1 ? max[j-1] : 0)
                    //更新较大值到 res
                    res = max[i] > res ? max[i] : res
                }
            }
        }
        return res
    }

代码地址:https://github.com/sinianshou/EGSwiftLearning

相关文章

网友评论

    本文标题:【算法】Longest Valid Parentheses 最长

    本文链接:https://www.haomeiwen.com/subject/jwhqyhtx.html