leetcode
leetcode 2701 ~ 2750
使字符串平衡的最小交换次数

使字符串平衡的最小交换次数

难度:

标签:

题目描述

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 both A and B are balanced strings, or
  • It can be written as [C], where C 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 '[' equals n / 2, and the number of closing brackets ']' equals n / 2.

代码结果

运行时间: 152 ms, 内存: 22.0 MB


解释

方法:

此题解采用贪心算法的思路来解决问题。首先初始化一个计数器 cnt 来记录遇到的未匹配的 ']' 的数量。遍历字符串,每次遇到 ']' 且 cnt 大于 0 时,说明前面有一个 '[' 可以与之匹配,因此将 cnt 减一。如果遇到 '[' 或者 cnt 为 0 时遇到 ']',则 cnt 加一。最后,cnt 表示的是无法匹配的 '[' 的数量(每个这样的 '[' 都需要一个对应的 ']' 来匹配以平衡字符串)。因此,需要的最小交换次数为 cnt 的一半,因为每一次交换可以解决两个未匹配的括号。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
算法中提到的'未匹配的 ] 的数量'是如何定义的?为什么遇到'['时仍然将计数器cnt增加?
在算法中,'未匹配的 ] 的数量'是指在遍历字符串时,遇到的']'字符,但在它之前没有足够的'['字符可以与之配对的次数。这是一个负载计数,用于追踪需要额外'['来平衡的']'的数量。当遇到'['时,我们暂时认为它是多余的,因为此时尚未遇到可以与之匹配的']',所以将cnt增加。这种做法是为了后续遇到']'时,能够用这些'['进行匹配。实际上,cnt在这里计数的是未匹配的括号数量,正负号表示未匹配的类型(正表示'[',负表示']')。
🦆
在题解中提到每次遇到']'且cnt大于0时,将cnt减一。请问这种做法是否意味着前面必有一个未匹配的'['可以与之配对?
是的,当cnt大于0且遇到']'时,cnt减一的操作确实意味着前面有一个未匹配的'['可以与之配对。cnt大于0表示在这个位置之前,有未匹配的'['存在(即'['的数量多于']'的数量)。因此,遇到']'可以与之前一个'['配对,从而减少未匹配的'['的数量,也就是cnt减一。
🦆
题解中最终返回的是cnt的一半,能否详细解释为什么每两个未匹配的括号通过一次交换就可以被匹配?
最终返回cnt的一半是因为每次交换可以解决两个未匹配的括号。具体来说,如果有两个未匹配的括号(例如两个'['),那么通过将其中一个'['与后面某个']'交换位置,可以让两个'['都找到各自的匹配']'。这意味着每进行一次交换,就有两个未匹配的括号被匹配掉。因此,未匹配括号的总数(即cnt)除以2就是需要的最小交换次数。

相关问题