每日一题 -- leetCode1864

830 阅读3分钟

image.png 「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

前言

每日一题,轻松解题

每日一题为刷题系列 每日刷一题LeetCode题,并且对题目进行分析,分享思路。

正文

:构成交替字符串需要的最小交换次数

难度:中等

题目要求:

给你一个二进制字符串 s ,现需要将其转化为一个 交替字符串 。请你计算并返回转化所需的 最小 字符交换次数,如果无法完成转化,返回 -1 。

交替字符串 是指:相邻字符之间不存在相等情况的字符串。例如,字符串 "010" 和 "1010" 属于交替字符串,但 "0100" 不是。

任意两个字符都可以进行交换,不必相邻 。

分析题目:

一个二进制字符串,只包含数字0和1,给一串随机字符串,要使字符串没有相同的两个数字相邻就属于交替字符串,要获取最小次数的结果,如果本身就是交替字符串就为0

举个例子

输入: s = "111000"
输出: 1
解释: 交换位置 14"111000" -> "101010" ,字符串变为交替字符串。

:解题

方法一

理清思路:

分析:
符合要求的交替字符串的形式只有两种:
1.形如 \texttt{"1010..."}"1010..." 的字符串,奇数位为 \texttt{0'}‘0’,偶数位为 \texttt{1'}‘1’;
2.形如 \texttt{"0101..."}"0101..." 的字符串,奇数位为 \texttt{1'}‘1’,偶数位为 \texttt{0'}‘0’。

二进制源字符串 s_1s 1和目标字符串 s_2s 2可以通过交换操作互相转化,当且仅当两个字符串中 \texttt{'0'}‘0’ 和 \texttt{'1'}‘1’ 的个数均相等。

假设 s_1s 1和 s_2s 2可以通过交换操作互相转化,且它们有 kk 个位置不同,那么最小的交换次数为 k/2k/2。

思路与算法
我们枚举两种交替字符串的形式,并根据 提示 22 判断 \texttt{'0'}‘0’ 和 \texttt{'1'}‘1’ 的个数是否相等。如果相等,我们可以计算出 ss 与上述目标字符串不同的位数 \texttt{diff}_1diff 1和 \texttt{diff}_2diff 2 。此时根据 提示 33,对应的最少交换次数即为 \texttt{diff}_1 / 2diff 1 /2 和 \texttt{diff}_2 / 2diff 2/2。最终,我们取两种情况的较小值作为答案返回;若两种情况均不满足,则返回 -1−1。

编辑代码:

class Solution {
public:
    int minSwaps(string s) {
        int n = s.size();
        int n0 = count(s.begin(), s.end(), '0');
        int n1 = count(s.begin(), s.end(), '1');
        int res = INT_MAX;
        // "1010..."
        if (n1 == (n + 1) / 2 && n0 == n / 2){   // 不同字符个数相等
            int diff1 = 0;
            for (int i = 0; i < n; ++i){
                if (s[i] - '0' == i % 2){   // 对应位数不同
                    ++diff1;
                }
            }
            res = min(res, diff1 / 2);
        }
        // "0101..."
        if (n0 == (n + 1) / 2 && n1 == n / 2){   // 不同字符个数相等
            int diff2 = 0;
            for (int i = 0; i < n; ++i){
                if (s[i] - '0' != i % 2){   // 对应位数不同
                    ++diff2;
                }
            }
            res = min(res, diff2 / 2);
        }
        if (res == INT_MAX){
            return -1;   // 不存在
        }
        else {
            return res;
        }
    }
};

总结

无论做什么分析最重要,其中我们分析了题目,分析了解题思路,其实在分析完解题思路后,代码其实就是很简单的事情了,养成习惯,无论做什么之前,都要进行分析,这样有助于你更快更好的完成这件事。