Skip to content

Latest commit

 

History

History

1963.Minimum Number of Swaps to Make the String Balanced

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给你一个字符串 s下标从 0 开始 ,且长度为偶数 n 。字符串 恰好n / 2 个开括号 '['n / 2 个闭括号 ']' 组成。

只有能满足下述所有条件的字符串才能称为 平衡字符串

  • 字符串是一个空字符串,或者
  • 字符串可以记作 AB ,其中 AB 都是 平衡字符串 ,或者
  • 字符串可以写成 [C] ,其中 C 是一个 平衡字符串

你可以交换 任意 两个下标所对应的括号 任意 次数。

返回使 s 变成 平衡字符串 所需要的 最小 交换次数。

 

示例 1:

输入:s = "][]["
输出:1
解释:交换下标 0 和下标 3 对应的括号,可以使字符串变成平衡字符串。
最终字符串变成 "[[]]" 。

示例 2:

输入:s = "]]][[["
输出:2
解释:执行下述操作可以使字符串变成平衡字符串:
- 交换下标 0 和下标 4 对应的括号,s = "[]][][" 。
- 交换下标 1 和下标 5 对应的括号,s = "[[][]]" 。
最终字符串变成 "[[][]]" 。

示例 3:

输入:s = "[]"
输出:0
解释:这个字符串已经是平衡字符串。

 

提示:

  • n == s.length
  • 2 <= n <= 106
  • n 为偶数
  • s[i]'['']'
  • 开括号 '[' 的数目为 n / 2 ,闭括号 ']' 的数目也是 n / 2

解法

方法一:贪心

我们用一个变量 $x$ 记录当前未匹配的左括号的数量,遍历字符串 $s$,对于每个字符 $c$

  • 如果 $c$ 是左括号,那么 $x$ 加一;
  • 如果 $c$ 是右括号,那么我们需要判断 $x$ 是否大于零,如果大于零,那么将当前右括号与左侧最近的一个未匹配的左括号匹配,即 $x$ 减一。

遍历结束后,得到的一定是形如 "]]]...[[[..."的字符串,我们再贪心地每次将两端的括号交换,这样一次可以消去 $2$ 个不匹配的左括号。因此,一共需要交换的次数为 $\left\lfloor \frac{x + 1}{2} \right\rfloor$

时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$

class Solution:
    def minSwaps(self, s: str) -> int:
        x = 0
        for c in s:
            if c == "[":
                x += 1
            elif x:
                x -= 1
        return (x + 1) >> 1
class Solution {
    public int minSwaps(String s) {
        int x = 0;
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            if (c == '[') {
                ++x;
            } else if (x > 0) {
                --x;
            }
        }
        return (x + 1) / 2;
    }
}
class Solution {
public:
    int minSwaps(string s) {
        int x = 0;
        for (char& c : s) {
            if (c == '[') {
                ++x;
            } else if (x) {
                --x;
            }
        }
        return (x + 1) / 2;
    }
};
func minSwaps(s string) int {
	x := 0
	for _, c := range s {
		if c == '[' {
			x++
		} else if x > 0 {
			x--
		}
	}
	return (x + 1) / 2
}
function minSwaps(s: string): number {
    let x = 0;
    for (const c of s) {
        if (c === '[') {
            ++x;
        } else if (x) {
            --x;
        }
    }
    return (x + 1) >> 1;
}