滑动窗口

计算最接近的数

2025-11-19  本文已影响0人  何以解君愁

 给定一个数组X和正整数K,请找出使表达式:
  X[i] - X[i+1] - … - X[i+K-1]
 结果最接近于数组中位数的下标 i ,如果有多个 i 满足条件,请返回最大的 i。
 其中,数组中位数:长度为N的数组,按照元素的值大小升序排列后,下标为N/2元素的值

import java.util.*;

public class Main {
    // 主函数,不要做任何改动
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 输入数组
        String[] input = scanner.nextLine().split(" ");
        int[] nums = Arrays.stream(input).mapToInt(Integer::parseInt).toArray();

        // 输入窗口大小K
        int K = scanner.nextInt();

        // 输出结果
        System.out.println(solve(nums, K));
    }

    // 注意,本题为核心代码模式
    // 请在这个函数中填充你的代码
    public static int solve(int[] nums, int K) {
        // 计算输入数组nums的长度
        int n = nums.length;

        // 计算该数组的中位数
        int[] numsSorted = Arrays.copyOf(nums, n);
        Arrays.sort(numsSorted);
        int mid = numsSorted[n / 2];

        // 构建前缀和数组
        int[] preSum = new int[n + 1];
        preSum[0] = 0;
        // 0   50    100
        for (int i = 1; i < n + 1; i++) {
            preSum[i] = preSum[i - 1] + nums[i - 1];
        }

        // 初始化最接近的数为一个极大的数
        int closest = Integer.MAX_VALUE;
        // 初始化答案变量
        int res = -1;

        // 遍历所有的子数组起始位置i
        for (int i = 0; i <= n - K; i++) {
            // 根据前缀和计算子数组的和
            int sum = - preSum[i + K] + preSum[i + 1] + nums[i];

            // 更新答案
            if (Math.abs(sum - mid) <= Math.abs(closest - mid)) {
                closest = sum;
                res = i;
            }
        }

        return res;
    }
}
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] s = sc.nextLine().trim().split("[ ]");
        int[] x = new int[s.length];
        for(int i = 0;i < s.length;i++){
            x[i] = Integer.parseInt(s[i]);
        }
        int k = sc.nextInt();
        int[] numsSorted = Arrays.copyOf(x, s.length); 
        //排序
        Arrays.sort(numsSorted);
        //中位数
        int mid = numsSorted[x.length / 2];
        int[] sums =  new int[s.length + 1];
        sums[0] = 0;
        int sum = 0;
        //统计前缀和
        for(int i = 1;i < s.length + 1;i++){
            sum += x[i - 1];
            sums[i] = sum;
        }
        
        int like = Integer.MAX_VALUE;
        int min = Integer.MAX_VALUE;
        for(int i = 0;i <= x.length - k;i++){
            int l = x[i] - (sums[i + k] - sums[i+1]);
            int a = Math.abs(l - mid);
            if(a <= min){
                min = a;
                like = i;
            }
        }
        System.out.print(like);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读