题目来源:https://leetcode-cn.com/problems/minimum-swaps-to-group-all-1s-together-ii/
大致题意:
给一个由 0 和 1 组成的环形数组(也就是首尾可以视为是相邻的),求出最少交换多少次元素后,可以让所有的 1 全部相邻
思路
题目要求最少的交换把所有的 1 放到一块,那就可以先算出 1 的个数 c,然后看在大小为 c 的窗口大小内,最多有多少个 1,选出最多的那个窗口,然后把这个窗口外的 1 全部交换进来即可
滑动窗口
- 统计 1 的个数 size
- 因为是首尾相连,所以直接将原数组扩容一倍加在尾部,做出首尾相连的效果
- 使用 size 大小的滑动窗口在扩容后的数组上滑动,统计最多的 1 的个数
代码:
public int minSwaps(int[] nums) {
int size = 0;
int n = nums.length;
int[] arr = new int[n * 2];
// 统计 1 的个数,并给扩容数组初始化
for (int i = 0; i < n; i++) {
size += nums[i];
arr[i] = nums[i];
}
for (int i = n; i < n * 2; i++) {
arr[i] = nums[i - n];
}
int count = 0;
int ans = size;
// 窗口为 0,直接返回
if (size == 0) {
return 0;
}
// 滑动窗口
for (int i = 0; i < 2 * n; i++) {
count += arr[i];
if (i < size - 1) {
continue;
}
ans = Math.min(ans, size - count);
count -= arr[i - size + 1];
}
return ans;
}