LeetCode 1864. 构成交替字符串需要的最小交换次数

LeetCode 1864. 构成交替字符串需要的最小交换次数

题意

给一个二进制字符串s,请将其转化为一个交替字符串,返回转化所需的最小字符交换次数, 如果无法完成转化,返回-1。交替字符串的定义:相邻字符之间不存在相等情况的字符串。例如:“010”和“1010”是交替字符串,但“0100”不是。任意两个字符都可以进行交换,不必相邻 。

分析

1.对于二进制字符串,里面的组成元素只有‘0’和’1’,因此对于固定长度的二进制字符串只有
两种交替字符串状态:“010101…”和“101010…”
2.那么给定的二进制字符串也只能变成上面的两种交替字符串状态了,使用给定的二进制字符串分别
与上面的两种状态进行匹配,匹配出现的情况一共有4种:
给定字符串s:0 1 0 1
交替字符串a:0 1 1 0
第一种情况是两者都是0,则说明s在某个索引上的字符是和a相同的,不需要做任何操作。
第二种情况是两者都是1,则说明s在某个索引上的字符是和a相同的,不需要做任何操作。
第三种情况是s在某个索引上的字符是’1’,而a在对应的索引上的字符是’0’,两个字符不相同,因此s需要与它自身其他字符值为’0’的元素进行交换操作。
第四种情况是s在某个索引上的字符是’0’,而a在对应的索引上的字符是’1’,两个字符不相同,因此s需要与它自身其他字符值为’1’的元素进行交换操作。
因此,可以把第三种情况中的’1’与第四种情况中的’0’进行交换操作,这样第三种情况中的’1’就变成了’0’,而第四种情况的’0’就变成了’1’。也就是说,如果s的第三种情况的出现次数等于第四种情况的出现次数,那么s就可以通过交换字符操作变成交替字符串, 且是最小字符交换次数。

代码

c++

class Solution {
public:
    //字符串a为交替字符串,字符串b为给定字符串
    int solve(string a, string b) {
        //x用于统计交替字符串某个索引为'0',而给定字符串对应索引为'1'的情况
        //y用于统计交替字符串某个索引为'1',而给定字符串对应索引为'0'的情况
        int x = 0, y = 0;
        for (int i = 0; i < a.size(); i++) {
            if (a[i] != b[i]) {
                if (a[i] == '0') x++;
                else y++;
            }
        }
        //如果x不等于y,则说明给定字符串无法变成交替字符串
        if (x != y) return INT_MAX;
        return x;
    }

    int minSwaps(string s) {
        int n = s.size();//取得给定字符串s的长度
        string a(n, '0'), b(n, '0');//初始化两个字符串
        for (int i = 0; i < n; i += 2) a[i] = '1';//"1010..."
        for (int i = 1; i < n; i += 2) b[i] = '1';//"0101..."
    
        int ans = min(solve(s, a), solve(s, b));
        if (ans == INT_MAX) return -1;
        return ans;
    }
};

Java

class Solution {
    int solve(char[] a, char[] b) {
        int x = 0, y = 0;
        for (int i = 0; i < a.length; i++) {
            if (a[i] != b[i]) {
                if (a[i] == '0') x++;
                else y++;
            }
        }
        return x == y ? x : Integer.MAX_VALUE;
    }

    public int minSwaps(String s) {
        int n = s.length();
        char[] a = new char[n];
        char[] b = new char[n];
        for (int i = 0; i < n; i++) a[i] = '0';
        for (int i = 0; i < n; i++) b[i] = '0';
        for (int i = 0; i < n; i += 2) a[i] = '1';
        for (int i = 1; i < n; i += 2) b[i] = '1';
        int ans = Math.min(solve(s.toCharArray(), a), solve(s.toCharArray(), b));
        return ans == Integer.MAX_VALUE ? -1 : ans;    
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值