1. 程式人生 > 其它 >LeetCode 2116. 判斷一個括號字串是否有效 思維

LeetCode 2116. 判斷一個括號字串是否有效 思維

LeetCode 2116. 判斷一個括號字串是否有效

題目描述

一個括號字串是隻由 '('')' 組成的 非空 字串。如果一個字串滿足下面 任意 一個條件,那麼它就是有效的:

  • 字串為 ()
  • 它可以表示為 ABAB 連線),其中 AB 都是有效括號字串。
  • 它可以表示為 (A),其中 A 是一個有效括號字串。

給你一個括號字串 s 和一個字串 locked,兩者長度都為nlocked 是一個二進位制字串,只包含 '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)\)

判斷一個合法的括號序列有兩個條件:

  1. 左括號數量等於右括號數量
  2. 任何一個字首中左括號數量小於等於右括號數量

具體實現:可以初始話變數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;
    }
};