网易2020校招笔试- 系统开发/研发工程师(提前批) [编程题]序列维护

问题描述

小易在维护数据的时候遇到一个需求,具体来说小易有一系列数据,这些数据了构成一个长度为n的数字序列,接下来小易会在这个序列上进行q次操作。
每次操作有一个查询的数字x,小易需要将序列数据中所有大于等于x的数字都减一,并输出在本次操作中有多少个数字被减一了。
小易犯了难,希望你能帮帮他。

输入描述

第一行n,q,表示数字个数和操作个数。
接下来一行n个数表示初始的数字。
接下来q行,每行一个数,表示指定的数字x。
1 <= n, q <= 200000, 1 <= (a_{i}), x <= n

输出描述

对于每个询问,输出一个数字表示答案

输入例子1

4 3
1 2 3 4
4
3
1

输出例子1

1
2
4

输入例子2

3 2
1 2 3
3
3

输出例子2

1
0

解题思路

  • 暴力解法
    暴力解法很容易想到,直接按题目说的来做就可以了
  • 优化
    这个数据量,显然需要用O(nlogn)或者O(n)算法,则会想到排序。如果从大到小排,那么每次查询一个数字x,使得大于等于x的数字都会-1,那么数列还是有序的。也就是数列始终都是有序的,这样就可以进行剪枝了,遍历到小于x的直接break跳出循环即可。

代码

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int q = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        Arrays.sort(arr);
        for (int i = 0; i < q; i++) {
            int num = sc.nextInt();
            System.out.println(column(arr, num));
        }
    }
    
    private static int column(int[] arr, int num) {
        int count = 0;
        for (int i = arr.length - 1; i >= 0; i--) {
            if (arr[i] >= num) {
                arr[i]--;
                count++;
            } else {
                break;
            }
        }
        return count;
    }
}
原文地址:https://www.cnblogs.com/taiyii/p/13453137.html