题目描述
给出一个二进制数组 data,你需要通过交换位置,将数组中 任何位置 上的 1 组合到一起,并返回所有可能中所需 最少的交换次数。
题解
- 首先举个栗子 假设数组为 [1 0 1 0 1],其中 1 数字的总数为3,那么我们只需要枚举长度为3的所有子序列,并找到其中 0 的个数最少的子序列,例如:子序列 [1,0,1] 其中0的个数,即为要交换的最少次数,时间复杂度O(n*c)。
- 上述方法当数据量过大时,时间复杂度过高,接下来我们采用滑动窗口的方法来解决这道题。
- 我们依然统计数组中 1 的总数量,并记作maxOneCount ,并维护一个长度为 maxOneCount的滑动窗口,我们将 序号1中枚举的方案转换一下,求子序列中 0的最少个数,即为求子序列中1的最大个数,转换到滑动窗口 即为求 滑动窗口中 1 的最大个数,然后用统计到的数组中1的总数减去滑动窗口中1的最大数量,即为题解。
详细代码
public class Solution
{
public int MinSwaps(int[] data)
{
int maxOneCount = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 1) maxOneCount++;
}
int curWindowOneCount = 0;
for (int i = 0; i < maxOneCount; i++)
{
if (data[i] == 1) curWindowOneCount++;
}
int maxWindowOnCount = curWindowOneCount;
for (int i = maxOneCount; i < data.Length; i++)
{
// 滑动窗口移动时,将左侧的数字移出窗口,右侧的数字进入窗口
// curWindowOneCount -= data[i - maxOneCount];
// curWindowOneCount += data[i];
curWindowOneCount += data[i] - data[i - maxOneCount];
maxWindowOnCount = Math.Max(maxWindowOnCount, curWindowOneCount);
}
return maxOneCount - maxWindowOnCount;
}
}