每日一题·力扣1963·使字符串平衡的最小交换次数

题目:

给你一个字符串 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
解释:这个字符串已经是平衡字符串。

详解:

题目分析:

  1. 给的是字符串
  2. 字符串恰好是'['和']’数量相等
  3. 只用返回交换次数

思路解析:

  • 给的字符串,就算直接遍历字符串,进行字符匹配时也需要用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;
    }
}
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值