题目:
给你一个字符串 s
,下标从 0 开始 ,且长度为偶数 n
。字符串 恰好 由 n / 2
个开括号 '['
和 n / 2
个闭括号 ']'
组成。
只有能满足下述所有条件的字符串才能称为 平衡字符串 :
- 字符串是一个空字符串,或者
- 字符串可以记作
AB
,其中A
和B
都是 平衡字符串 ,或者 - 字符串可以写成
[C]
,其中C
是一个 平衡字符串 。
你可以交换 任意 两个下标所对应的括号 任意 次数。
返回使 s
变成 平衡字符串 所需要的 最小 交换次数。
示例 1:
输入:s = "][][" 输出:1 解释:交换下标 0 和下标 3 对应的括号,可以使字符串变成平衡字符串。 最终字符串变成 "[[]]" 。
示例 2:
输入:s = "]]][[[" 输出:2 解释:执行下述操作可以使字符串变成平衡字符串: - 交换下标 0 和下标 4 对应的括号,s = "[]][][" 。 - 交换下标 1 和下标 5 对应的括号,s = "[[][]]" 。 最终字符串变成 "[[][]]" 。
示例 3:
输入:s = "[]" 输出:0 解释:这个字符串已经是平衡字符串。
详解:
题目分析:
- 给的是字符串
- 字符串恰好是'['和']’数量相等
- 只用返回交换次数
思路解析:
- 给的字符串,就算直接遍历字符串,进行字符匹配时也需要用str.charAt(i)来进行匹配,所以我选择直接把字符串转化为字符数组
- 由一三条可以得出可以只进行遍历,不用进行实际交换
- 因为一个'['和']’是对应的,所以我们可以把'['记作1,']’记作-1,0代表就是匹配上了
- 只有当遍历到']’,且前面的累加和为‘-1’时需要交换
- 交换的时候是从后面向前找'[',因为当前的']’出现的过于早,后面的'['出现过于靠后,所以,一交换可以达到平衡的作用
代码:
改进前:
class Solution {
public int minSwaps(String s) {
char[] arr= s.toCharArray();
int cnt= 0;//交换次数
int num=0;//求前面累加和
int behind=arr.length-1;//从后面开始找]
for (int j = 0;j<arr.length-1;j++) {
if(arr[j]=='['){num++;}
else if(arr[j]==']'){
num--;
if(num<0){
for(int i=behind;i>j;i--){
if(arr[i]=='['){
arr[i]=']';
arr[j]='[';
cnt++;
break;
}
}
num+=2;//因为](-1)替换成[(1),差值为2
}
}
}
return cnt;
}
}
改进后:
(把实际交换的去掉,同时优化代码)
class Solution {
public int minSwaps(String s) {
char[] arr= s.toCharArray();
int cnt= 0;
int num=0;
int behind=arr.length-1;
for (int j = 0;j<behind;j++) {
if(arr[j]=='['){num++;continue;}
else if(arr[j]==']'){
num--;
if(num<0){
for(;behind>j;behind--){
if(arr[behind]=='['){
cnt++;
break;
}
}
num+=2;
}
}
}
return cnt;
}
}