LeetCode 2116. 判斷一個括號字串是否有效 思維
阿新 • • 發佈:2021-12-30
LeetCode 2116. 判斷一個括號字串是否有效
題目描述
一個括號字串是隻由 '('
和 ')'
組成的 非空 字串。如果一個字串滿足下面 任意 一個條件,那麼它就是有效的:
- 字串為
()
。 - 它可以表示為
AB
(A
與B
連線),其中A
和B
都是有效括號字串。 - 它可以表示為
(A)
,其中A
是一個有效括號字串。
給你一個括號字串 s
和一個字串 locked
,兩者長度都為n
。locked
是一個二進位制字串,只包含 '0'
和 '1'
。對於 locked
中 每一個 下標 i
:
- 如果
locked[i]
是'1'
,你 不能 改變s[i]
。 - 如果
locked[i]
是'0'
s[i]
變為'('
或者')'
。
如果你可以將 s
變為有效括號字串,請你返回 true
,否則返回 false
。
樣例
輸入:s = "))()))", locked = "010100" 輸出:true 解釋:locked[1] == '1' 和 locked[3] == '1',所以我們無法改變 s[1] 或者 s[3]。 我們可以將 s[0] 和 s[4] 變為 '(',不改變 s[2] 和 s[5],使 s 變為有效字串。 輸入:s = "()()", locked = "0000" 輸出:true 解釋:我們不需要做任何改變,因為 s 已經是有效字串了。 輸入:s = ")", locked = "0" 輸出:false 解釋:locked 允許改變 s[0] 。 但無論將 s[0] 變為 '(' 或者 ')' 都無法使 s 變為有效字串。
限制
n == s.length == locked.length
1 <= n <= 10^5
s[i]
要麼是'('
要麼是')'
。locked[i]
要麼是'0'
要麼是'1'
。
演算法
(貪心思維) \(O(n)\)
判斷一個合法的括號序列有兩個條件:
- 左括號數量等於右括號數量
- 任何一個字首中左括號數量小於等於右括號數量
具體實現:可以初始話變數x
,如果遇到左括號,x++
;如果遇到右括號x--
;如果中途x<0,則為非法括號序列,如果最終x=0,則說明為合法的括號序列。
該題,首先先將所有可以改變的位置都變為右括號,定義x
記錄當前多餘的左括號的情況,cnt
x<0
,則可以修改之前可變位置的某一個右括號為左括號,使得 x+=2,cnt-=1
。如果沒有可修改的位置,則表示無法變為有效字串。最終,如果 x=0
,則說明可以變為有效字串。
時間複雜度
- 遍歷陣列一次,故總時間複雜度為 \(O(n)\)。
空間複雜度
- 僅需要常數的額外空間。
C++ 程式碼
class Solution {
public:
bool canBeValid(string s, string locked) {
const int n = s.size();
int x = 0, cnt = 0;
for (int i = 0; i < n; i++) {
if (locked[i] == '0') {
s[i] = ')';
cnt++;
}
if (s[i] == '(') x++;
else x--;
if (x < 0) {
if (cnt == 0)
return false;
cnt--;
x += 2;
}
}
return x == 0;
}
};