You are given a 0-indexed string s
of even length n
. The string consists of exactly n / 2
opening brackets '['
and n / 2
closing brackets ']'
.
A string is called balanced if and only if:
- It is the empty string, or
- It can be written as
AB
, where bothA
andB
are balanced strings, or - It can be written as
[C]
, whereC
is a balanced string.
You may swap the brackets at any two indices any number of times.
Return the minimum number of swaps to make s
balanced.
Example 1:
Input: s = "][][" Output: 1 Explanation: You can make the string balanced by swapping index 0 with index 3. The resulting string is "[[]]".
Example 2:
Input: s = "]]][[[" Output: 2 Explanation: You can do the following to make the string balanced: - Swap index 0 with index 4. s = "[]][][". - Swap index 1 with index 5. s = "[[][]]". The resulting string is "[[][]]".
Example 3:
Input: s = "[]" Output: 0 Explanation: The string is already balanced.
Constraints:
n == s.length
2 <= n <= 106
n
is even.s[i]
is either'['
or']'
.- The number of opening brackets
'['
equalsn / 2
, and the number of closing brackets']'
equalsn / 2
.
使字符串平衡的最小交换次数。
给你一个字符串 s ,下标从 0 开始 ,且长度为偶数 n 。字符串 恰好 由 n / 2 个开括号 '[' 和 n / 2 个闭括号 ']' 组成。
只有能满足下述所有条件的字符串才能称为 平衡字符串 :
字符串是一个空字符串,或者
字符串可以记作 AB ,其中 A 和 B 都是 平衡字符串 ,或者
字符串可以写成 [C] ,其中 C 是一个 平衡字符串 。
你可以交换 任意 两个下标所对应的括号 任意 次数。返回使 s 变成 平衡字符串 所需要的 最小 交换次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-number-of-swaps-to-make-the-string-balanced
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题我给出两种思路。
第一种思路涉及到stack + 贪心。这里我需要一个stack,stack里面放的永远是左括号。当我遇到左括号的时候我都无条件放入stack;当我遇到右括号的时候,如果此时栈不为空同时栈顶元素是左括号,那么我就stack.pop(),意思是我就把这一对括号配对了。但是如果栈为空同时当前是一个右括号的话,我就知道我一定要 swap 这个右括号了,否则结果就错了。所以我会把当前这个单独的右括号变为左括号再入栈。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int minSwaps(String s) { 3 Stack<Character> stack = new Stack<>(); 4 int swap = 0; 5 for (char c : s.toCharArray()) { 6 if (c == '[') { 7 stack.push(c); 8 } else { 9 if (!stack.isEmpty() && stack.peek() == '[') { 10 stack.pop(); 11 } else if (stack.isEmpty()) { 12 swap++; 13 stack.push('['); 14 } 15 } 16 } 17 return swap; 18 } 19 }
第二种思路类似第一种,但是找的东西的定义略有区别。首先我创建一个变量 size 记录需要swap的括号个数。我们还是照着配对的原则,如果当前我遇到一个左括号,我就 size++,意思是我需要找一个配对;如果我遇到一个右括号,同时当前 size 大于0的话(意思是前面有单独的左括号可供配对),我就 size--,这样就能配对了。最后返回的是需要配对的半括号 / 2。
时间O(n)
空间O(1)
Java实现
1 class Solution { 2 public int minSwaps(String s) { 3 int size = 0; 4 for (char c : s.toCharArray()) { 5 if (c == '[') { 6 size++; 7 } else { 8 if (size > 0) { 9 size--; 10 } 11 } 12 } 13 return (size + 1) / 2; 14 } 15 }