zoukankan      html  css  js  c++  java
  • [Swift]LeetCode32. 最长有效括号 | Longest Valid Parentheses

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9898451.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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:

    输入: ")()())"
    输出: 4
    解释: 最长有效括号子串为 "()()"

    使用堆栈算法

    我们可以在扫描给定字符串时使用堆栈来检查目前为止扫描的字符串是否有效,以及最长有效字符串的长度,而不是查找每个可能的字符串并检查其有效性。为了做到这一点,我们从推动开始-1- 1到堆栈。

    每一个 文本{'('}'('遇到,我们将其索引推入堆栈。

    每一个 文本{')'}')'遇到,我们弹出最顶层的元素并从堆栈的顶部元素中减去当前元素的索引,这给出了当前遇到的有效括号字符串的长度。如果在弹出元素时,堆栈变空,我们将当前元素的索引推送到堆栈。通过这种方式,我们继续计算有效子串的长度,并在结尾返回最长有效字符串的长度。

    2828ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         var maxans:Int = 0
     4         var stack:Stack<Int> = Stack<Int>()
     5         stack.push(-1)
     6         for i in 0..<s.count
     7         {
     8             if s.charAt(i) == "("
     9             {
    10                 stack.push(i)
    11             }
    12             else
    13             {
    14                 stack.pop()
    15                 if stack.isEmpty()
    16                 {
    17                     stack.push(i)
    18                 }
    19                 else
    20                 {
    21                     maxans = max(maxans, i - stack.getLast()!)
    22                 }
    23             }
    24         }
    25         return maxans
    26     }
    27 }
    28 extension String {
    29     //获取指定索引位置的字符,返回为字符串形式
    30     func charAt(_ num:Int) -> String
    31     {
    32         let index = self.index(self.startIndex,offsetBy: num)
    33         return String(self[index])
    34     }
    35 }
    36 
    37 public struct Stack<T> {
    38     
    39     // 泛型数组:用于存储数据元素
    40     fileprivate var stack: [T] 
    41 
    42 
    43     /// 构造函数:创建一个空的堆栈
    44     public init() {
    45         stack = [T]()
    46     }
    47     
    48     //通过既定数组构造堆栈
    49     init(_ arr:[T]){
    50         stack = arr
    51     }
    52     
    53     // 如果定义了默认值,则可以在调用函数时省略该参数
    54     init(_ elements: T...) {
    55         stack = elements
    56     }
    57     
    58     // 检查堆栈是否为空
    59     // - returns: 如果堆栈为空,则返回true,否则返回false
    60     public func isEmpty() -> Bool {
    61         return stack.isEmpty
    62     }
    63     
    64     // 入堆栈操作:将元素添加到堆栈的末尾
    65     public mutating func push(_ element: T) {
    66         stack.append(element)
    67     }
    68     
    69     // 出堆栈操作:删除并返回堆栈中的第一个元素
    70     public mutating func pop() -> T? {
    71         return stack.removeLast()
    72     }
    73  
    74     // 返回堆栈中的第一个元素(不删除)
    75     public func getLast() -> T? {
    76         return stack.last!
    77     }
    78 }

    16ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         let s = Array(s.characters)
     4         let len = s.count
     5         var max = Array(repeating: 0, count: len)
     6         var i = len-2
     7         var res = 0
     8         while i >= 0 {
     9             // find max[i]
    10             if s[i] == ")" {
    11                 i -= 1
    12                 continue
    13             }
    14             
    15             // s[i] = '('
    16             if s[i+1] == ")" {
    17                 max[i] = 2 + (i < len-2 ? max[i+2] : 0)
    18             } else {
    19                 let j = i + 1 + max[i+1];
    20                 if j < len && s[j] == ")" {
    21                     max[i] = 2 + max[i+1] + (j < len-1 ? max[j+1] : 0)
    22                 }
    23             }
    24             
    25             if max[i] > res { res = max[i] }
    26             
    27             i -= 1
    28         }
    29         
    30         return res
    31     }
    32 }

    20ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         
     4         guard s.count>0 else { return 0}
     5         
     6         var dp = Array(repeating:0,count:s.count)
     7         var sarr = Array(s.characters)
     8         var maxLen = 0
     9     
    10         //print(sarr)
    11         for i in 1..<sarr.count {
    12             if(sarr[i]==")") {
    13                 if(sarr[i-1]=="(") {  //()
    14                 dp[i] = (i>=2 ? dp[i-2]: 0) + 2
    15                 //print("i:",i,"dp[i]:",dp[i])
    16                 
    17                 }
    18                 else {  // ))
    19                     var prevIdx = i-dp[i-1]-1
    20                     //print("prevIdx:",prevIdx)
    21                     //print(dp)
    22                 
    23                     if(prevIdx>=0 && sarr[prevIdx] == "(") {  //We found another enclosing parantheses
    24                         dp[i] = dp[i-1] + 2 + (prevIdx-1>=0 ? dp[prevIdx-1] : 0)
    25                     }
    26                 }
    27             }
    28         
    29             if(dp[i]>=0) {
    30                 maxLen = max(dp[i],maxLen)
    31             }
    32         }
    33     
    34         return maxLen
    35     }
    36 }

    24ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         if s.count == 0{
     4             return 0
     5         }
     6         
     7         var stack = [Int]()
     8         stack.append(-1)
     9         var arr = Array(s)
    10         var res = 0
    11         for i in 0..<arr.count{
    12             if arr[i] == ")"{
    13                 if stack.count > 1 && arr[stack.last!] == "("{
    14                     stack.removeLast()
    15                     res = max(res, i - stack.last!)
    16                 }else{
    17                     stack.append(i)
    18                 }
    19             }else{
    20                 stack.append(i)
    21             }
    22         }
    23         return res
    24     }
    25 }

    40ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         typealias Element = (index: Int, isOpening: Bool)
     4         var stack = [Element]()
     5         var maxCount = 0
     6         for (i, char) in s.enumerated() {
     7             if char == "(" {
     8                 stack.append((index: i, isOpening: true))
     9             } else {
    10                 if !stack.isEmpty && stack.last!.isOpening {
    11                     stack.removeLast()
    12                     let lastIndex = stack.last?.index ?? -1
    13                     let currentCount = i - lastIndex
    14                     maxCount = max(maxCount, currentCount)
    15                 } else {
    16                     stack.append((index: i, isOpening: false))
    17                 }
    18             }
    19         }
    20         return maxCount
    21     }
    22 }

    48ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         var stack: [Int] = [-1]
     4         var array = Array(s)
     5         var res = 0
     6         for i in 0..<array.count {
     7             if array[i] == "(" {
     8                 stack.append(i)
     9             } else if array[i] == ")" {
    10                 stack.removeLast()
    11                 if !stack.isEmpty {
    12                     if (i - stack.last!) > res {
    13                         res = (i - stack.last!)
    14                     }
    15                 } else {
    16                     stack.append(i)
    17                 }   
    18             }
    19         }
    20         return res
    21     }
    22 }

    56ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         var stack = Array<String>()
     4         var indexStack = Array<Int>()
     5         var i = 0
     6         for c in s{
     7             if c == ")"{
     8                 if stack.count == 0 || stack.last != "("{
     9                     stack.append(")")
    10                     indexStack.append(i)
    11                 }else{
    12                     stack.removeLast()
    13                     indexStack.removeLast()
    14                 }
    15             }else{
    16                 stack.append("(")
    17                 indexStack.append(i)
    18             }
    19             i += 1
    20         }
    21         var maxLength = 0
    22         var lastIndex = -1
    23         indexStack.append(s.count)
    24         for i in indexStack{
    25             let length = i - lastIndex - 1
    26             maxLength = maxLength < length ? length : maxLength
    27             lastIndex = i
    28         }
    29         return maxLength
    30     }
    31 }

    72ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         var stack = [-1]
     4         var left = 0 // 左括号剩余
     5         
     6         for char in s {
     7             if char == "(" {
     8                 stack.append(0)
     9                 left += 1
    10             } else {
    11                 if left > 0 {
    12                     left -= 1
    13                     let top = stack.last!
    14                     stack.removeLast()
    15                     let second = stack.last!
    16                     if top == 0 { // 左边即是括号
    17                         if second == -1 || second == 0 { // 边界 或 左括号
    18                             stack.append(2)
    19                         } else { // 数字
    20                             stack.removeLast()
    21                             stack.append(second + 2)
    22                         }
    23                     } else { // 数字
    24                         // 因为左括号数量大于0  因此second只能为左括号
    25                         stack.removeLast()
    26                         let third = stack.last!
    27                         if third == -1 || third == 0 {
    28                             stack.append(top + 2)
    29                         } else { // 加上前一个数字
    30                             stack.removeLast()
    31                             stack.append(third + top + 2)
    32                         }
    33                     }
    34                 } else {
    35                     stack.append(-1)
    36                 }
    37             }
    38         }
    39         
    40         var result = 0
    41         for answer in stack {
    42             result = max(answer, result)
    43         }
    44         return result
    45     }
    46 }

    88ms

     1 class Solution {
     2     func longestValidParentheses(_ s: String) -> Int {
     3         var stack: [Character] = []     // 模拟一个栈
     4         var symbols: [Int] = []         // 将括号打标记,遇到 ( 标记为-1,遇到 ) 判断是否与栈顶配对,如果配对打标记1,否则打标记-1
     5         
     6         for c in s {
     7             if c == "(" {
     8                 stack.append(c)
     9                 symbols.append(-1)
    10             } else if c == ")" {
    11                 if stack.count > 0 && stack.last == "(" {
    12                     let _ = stack.removeLast()
    13                     symbols.append(1)
    14                 } else {
    15                     stack.append(c)
    16                     symbols.append(-1)
    17                 }
    18             }
    19         }
    20         
    21         var count: Int = 0          // 累加标记的数值
    22         var tmpLength: Int = 0      // 临时保存的最长序列的长度
    23         var maxLength: Int = 0      // 有效的最长序列的长度
    24         
    25         /*
    26          )()())  ->  -1 -1 1 -1 1 -1
    27          从右边遍历累加,成对的有效序列的和肯定是0,遇到-1,说明连续的序列断了,就重新累计
    28          */
    29         for num in symbols.reversed() {
    30             count += num
    31             
    32             if count == -1 {
    33                 count = 0
    34                 maxLength = max(maxLength, tmpLength)
    35                 tmpLength = 0
    36             } else {
    37                 tmpLength += 1
    38             }
    39         }
    40         
    41         if count == 0 {
    42             maxLength = max(maxLength, tmpLength)
    43         }
    44         
    45         return maxLength
    46     }
    47 }
  • 相关阅读:
    得物小程序解析data加解密算法
    关于mysql启动报111错误问题的可能性
    我的php笔记(一)
    近期汇编学习@20181125
    近期汇编学习
    《汇编语言》第三章
    《汇编语言》第二章
    《汇编语言》实验一:查看CPU和内存,用机器指令和汇编指令编程
    《汇编语言》第一章
    【8086汇编-Day8】实验九
  • 原文地址:https://www.cnblogs.com/strengthen/p/9898451.html
Copyright © 2011-2022 走看看