1. 程式人生 > >[Swift]LeetCode32. 最長有效括號 | Longest Valid Parentheses

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

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 }