2021 12-1 序列查询
- 题解1
- 题解2
- 区别
- 第一种算法:
- 第二种算法:
题解1
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 输入n表示商品数目,N表示总数int n = sc.nextInt();int N = sc.nextInt();int[] A = new int[n + 1]; // 存储价格的数组,注意要多一个位置用于存储0// 输入n个商品的价格for (int i = 1; i <= n; i++) {A[i] = sc.nextInt();}int sum = 0; // 存储 sum(A) 的值int curMax = 0; // 当前最大值的下标,初始化为0// 遍历 [0, N) 的范围for (int x = 0; x < N; x++) {// 找到小于等于x的最大值的下标while (curMax + 1 <= n && A[curMax + 1] <= x) {curMax++;}sum += curMax; // 将当前最大值的下标累加到sum中}System.out.println(sum); // 输出结果sc.close();}
}
题解2
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 输入n表示商品数目,N表示总数int n = sc.nextInt();int N = sc.nextInt();int[] arr = new int[n + 1]; // 存储价格的数组,注意要多一个位置用于存储0// 输入n个商品的价格for (int i = 1; i <= n; i++) {arr[i] = sc.nextInt();}int sum = 0; // 存储 sum(A) 的值int temp = 0; // 暂存当前最大值的下标// 遍历 [0, N) 的范围for (int i = 0; i < N; i++) {if (i < arr[n]) {// 如果i小于数组中的最大值,且等于arr[temp+1]时,temp加1if (i == arr[temp + 1]) {temp++;}sum += temp; // 将temp累加到sum中} else {// 如果i大于等于数组中的最大值,计算剩余的值并加到sum中,跳出循环sum += (N - arr[n]) * (temp + 1);break;}}System.out.println(sum); // 输出结果sc.close();}
}
区别
第一种算法:
使用了差分数组的思想,通过差分数组记录了每个时间段内的能出行的个数。
遍历每个出行计划,将每个计划对应的时间段进行标记,标记出行计划所需的时间段。
根据差分数组的性质,对于每个时间点,差分数组记录了该时间点前面的出行计划所覆盖的时间段个数,从而实现了查询时间点时的高效计算。
第二种算法:
在对每个时间点进行查询时,遍历了商品价格的数组,根据当前时间点和商品价格的关系来计算sum。
在遍历过程中,记录了当前最大值的下标temp,并根据temp来确定sum的值,即根据每个时间点对应的商品价格来确定sum的值。
总的来说,第一种算法更加直接且高效,通过差分数组记录时间段的出行计划个数,从而实现了O(1)时间复杂度内的查询。而第二种算法则需要对每个时间点都遍历整个商品价格数组来计算sum,效率较低。