原始题目链接可以参考如下链接 某厂机试算法刷题一览_@_南先森的博客-CSDN博客
在阅读代码时,建议拷贝到idea或者eclipse里面看,为了便于理解代码,注释比较多,
在阅读代码时,可以先删掉注释
这个题目可以用固定滑动窗口来解。先确定滑动窗口大小,滑动窗口的大小取决于有多少个数小于k,假定总共有m个数小于k。这个数值即为滑动窗口的长度。然后让滑动窗口从数组起始端向右滑动,每滑动一位,就计算出当前窗口内有多少个数小于k,将这些统计数字做比较,找出最大的,假定窗口内最多有n个数小于k。那么m与n的差值就是需要交换的次数,这个不难理解。代码也不复杂,如下
public class Demo106 {
public static void main(String[] args) {
int[] n = {1, 3, 1, 4, 0};
int k = 2;
int r = mergeMinTimes(n, k);
System.out.println(r);
}
public static int mergeMinTimes(int[] n, int k) {
/*
* 遍历一次数组,找出数组里面有多少个数字小于k
* 据此确定滑动窗口大小
*/
int target = 0;
for (int i = 0; i < n.length; i++) {
if (n[i] < k) {
target++;
}
}
// 滑动窗口左单点
int left = 0;
// 滑动窗口右单点
int right = target - 1;
// 记录当前窗口范围内有多少个数字小于k
int current = 0;
// 再遍历一次,确定初始窗口内有多少个数小于k
for (int i = 0; i <= right; i++) {
if (n[i] < k) {
current++;
}
}
// max用来记录窗口内最多有多少个数小于k
int max = current;
// 窗口不停的向右滑动
while (right < n.length - 1) {
// 左边滑出
if (n[left++] < k) {
current--;
}
// 右边滑入
if (n[++right] < k) {
current++;
}
if (current > max) {
max = current;
}
}
return target - max;
}
}