计算二进制序列重排为交替形式所需的最少交换次数
最少交换次数计算方案
嘿,这个问题其实可以拆解成两种目标序列的情况来分析,核心思路是统计「错位的0和1」的数量——因为每次交换能同时修正两个错位,所以最终的交换次数就是这类错位对的数量。
先明确几个基础变量:
- 设序列总长度为
n - 数出序列里1的数量
k,0的数量就是m = n - k
第一步:确定合法的目标序列形式
我们的目标序列只能是以下两种之一,取决于1和0的数量:
- 如果 k > m:目标是
1010...1——前2m位是交替的10组合,末尾剩下k - m个1(因为1更多) - 如果 m > k:目标是
0101...0——前2k位是交替的01组合,末尾剩下m - k个0(因为0更多) - 如果 k = m:两种形式都合法,我们需要分别计算两种情况的交换次数,取更小的那个
第二步:计算单种目标模式的交换次数
对于任意一种目标模式,我们只需要遍历原序列,统计两类错位的数量:
针对「1开头的交替模式」:
- 偶数索引位(从0开始数)应该是1,统计这里出现0的数量,记为
wrong_even_0 - 奇数索引位应该是0,统计这里出现1的数量,记为
wrong_odd_1 - 这两个数一定相等(因为每个偶数位的0,必然对应一个奇数位的1错位),所以这种模式的交换次数就是
wrong_even_0(或者wrong_odd_1,两者数值一样)
针对「0开头的交替模式」:
- 偶数索引位应该是0,统计这里出现1的数量,记为
wrong_even_1 - 奇数索引位应该是1,统计这里出现0的数量,记为
wrong_odd_0 - 同理,交换次数就是
wrong_even_1(等于wrong_odd_0)
举个实际例子验证
比如你给的序列10100100:
- 总长度n=8,数出1的数量k=3,0的数量m=5(m>k),所以只能用0开头的目标模式
01010100 - 只需要看前6位(因为2k=6,后面两位固定是0):
- 索引0(偶):1≠0 →
wrong_even_1加1 - 索引1(奇):0≠1 →
wrong_odd_0加1 - 索引2(偶):1≠0 →
wrong_even_1加1 - 索引3(奇):0≠1 →
wrong_odd_0加1 - 索引4、5都是正确的
- 索引0(偶):1≠0 →
- 最终
wrong_even_1=2,交换次数就是2次——实际操作中交换索引0和4的1、0,再交换索引2和3的1、0,就能得到目标序列,确实只需要2次交换
最后总结流程
- 统计序列中1的数量
k,计算0的数量m = n -k - 根据k和m的大小选择要计算的目标模式:
- k > m → 计算1开头模式的交换次数
- m > k → 计算0开头模式的交换次数
- k = m → 计算两种模式的次数,取最小值
- 得到的结果就是最少交换次数
内容的提问来源于stack exchange,提问作者piternet
相关产品推荐
相关产品推荐

