华为OD机试106-根据某条件聚类最少交换次数

原始题目链接可以参考如下链接 某厂机试算法刷题一览_@_南先森的博客-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;
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值