[Swift]LeetCode32. 最長有效括號 | Longest Valid Parentheses

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-rfpyzxff-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.git

Example 1:github

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:app

輸入: ""
輸出: 4
解釋: 最長有效括號子串爲 )()())"()()"

使用堆棧算法

咱們能夠在掃描給定字符串時使用堆棧來檢查目前爲止掃描的字符串是否有效,以及最長有效字符串的長度,而不是查找每一個可能的字符串並檢查其有效性。爲了作到這一點,咱們從推進開始-1- 1到堆棧。函數

每個 \文本{'('}'('遇到,咱們將其索引推入堆棧。spa

每個 \文本{')'}')'遇到,咱們彈出最頂層的元素並從堆棧的頂部元素中減去當前元素的索引,這給出了當前遇到的有效括號字符串的長度。若是在彈出元素時,堆棧變空,咱們將當前元素的索引推送到堆棧。經過這種方式,咱們繼續計算有效子串的長度,並在結尾返回最長有效字符串的長度。code

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 }
相關文章
相關標籤/搜索