华为机试题:求子区间面积和

题目内容

小A发明了一个游戏,有一串连续的数字用数组arr表示,arr[0...N-1],0 < N =< 100000,定义任意子区间 arr[i...j],0 =< i =< j =< N-1,区间的面积为该区间的最大值减去区间最小值,然后乘以区间的长度(j - i + 1),这个游戏的获胜条件为需要计算出所有子区间面积和,由于面积会很大,结果返回面积和对 1000000007 取模后的值(ares_num % 1000000007)。

输入描述:
输入第一行只有一个参数N,为数组长度,0 < N =< 100000
第二行给出数组的各数字元素,数组元素 arr[i] 满足 0 < arr[i] =< 100000

输出描述:
输出所有子区间面积之和 mod 1000000007

测试用例

用例1:
输入

3
1 4 2000

输出

9995

说明
子区间有三个:
1 4 面积 (4 - 1) * 2 = 6
4 2000 面积 (2000 - 4) * 2 = 3992
1 4 2000 面积 (2000 - 1) * 3 = 5997

9995 % 1000000007 = 9995

时间复杂度O((n^2))的解法:

import java.util.Arrays;
import java.util.Scanner;


public class Main {


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = Integer.parseInt(scanner.nextLine());
        String line = scanner.nextLine();
        int[] numbers = Arrays.stream(line.split(" ")).mapToInt(Integer::parseInt).toArray();
        areaSum(size, numbers);
    }

    public static void areaSum(int n, int[] arr) {
        int sum = 0;
        for (int i = 0; i < n - 1; i++) {
            int max = arr[i]; // 初始化 arr[i...j] 的最大值为 arr[i]
            int min = arr[i]; // 初始化 arr[i...j] 的最小值为 arr[i]
            int area_sum;
            for (int j = i + 1; j < n; j++) {
                max = Math.max(max, arr[j]); // 更新 arr[i...j] 的最大值
                min = Math.min(min, arr[j]); // 更新 arr[i...j] 的最小值
                area_sum = (max - min) * (j - i + 1) % 1000000007;
                sum = (sum + area_sum) % 1000000007;
            }
        }
        System.out.println(sum);
    }

}

参考同余定理:(a + b) % n = ((a % n ) + (b % n)) % n

自编用例

输入

3
1 100000 2

输出

699991

面积和等于
(100000-1)*2 + (100000 - 1) * 3 + (100000 - 2) * 2 = 699991

原文地址:https://www.cnblogs.com/kendoziyu/p/15355854.html