小和问题

简介: 小和问题在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。例子:[1,3,4,2,5]1左边比1小的数,没有;3左边比3小的数,1;4左边比4小的数,1、3;2左边比2小的数,1;5左边比5小的数...

小和问题
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组
的小和。
例子:
[1,3,4,2,5]
1左边比1小的数,没有;
3左边比3小的数,1;
4左边比4小的数,1、3;
2左边比2小的数,1;
5左边比5小的数,1、3、4、2;
所以小和为1+1+3+1+1+3+4+2=16

1 最直接方法

依次遍历各元素左边
时间复杂度O(N)

2 归并方法

每次merge得出一个小和

package com.sss;

/**
 * @author Shusheng Shi
 */
public class SmallSum {

    public static int smallSum(int[] arr) {
        if (arr == null || arr.length < 2) {
            return 0;
        }
        return mergeSort(arr, 0, arr.length - 1);
    }

    /**
     *
     * @param arr
     * @param left
     * @param right
     * @return 在left - right范围内一共产生的小和
     */
    public static int mergeSort(int[] arr, int left, int right) {
        if (left == right) {
            return 0;
        }
        int mid = left + ((right - left) >> 1);
        //左侧部分产生的小和 + 右侧部分产生的小和 + 最终merge过程产生的小和 = 整体的小和
        return mergeSort(arr, left, mid) + mergeSort(arr, mid + 1, right) + merge(arr, left, mid, right);
    }

    public static int merge(int[] arr, int l, int m, int r) {
        int[] help = new int[r - l + 1];
        int i = 0;
        int p1 = l;
        int p2 = m + 1;
        int res =  0;
        while (p1 <= m && p2 <= r) {
            //p1<p2时 的小和数
            res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 <= m) {
            help[i++] = arr[p1++];
        }
        while (p2 <= r) {
            help[i++] = arr[p2++];
        }
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
        return res;
    }

    // for test
    public static int comparator(int[] arr) {
        if (arr == null || arr.length < 2) {
            return 0;
        }
        int res = 0;
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < i; j++) {
                res += arr[j] < arr[i] ? arr[j] : 0;
            }
        }
        return res;
    }

    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    // for test
    public static int[] copyArray(int[] arr) {
        if (arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    // for test
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    // for test
    public static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    // for test
    public static void main(String[] args) {
        int testTime = 500000;
        int maxSize = 100;
        int maxValue = 100;
        boolean succeed = true;
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            if (smallSum(arr1) != comparator(arr2)) {
                succeed = false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    }

}

目录
相关文章
|
8月前
|
存储 安全 数据挖掘
【工具】HxD Hex Editor 的安装、使用详细教程
【工具】HxD Hex Editor 的安装、使用详细教程
1349 0
|
8月前
|
JavaScript 前端开发
JavaScript DOM 操作:如何动态创建和插入元素?
使用JavaScript的`createElement`, `createTextNode`和`appendChild`方法可动态创建并插入元素。
60 2
|
8月前
|
XML 安全 测试技术
Jinja2:使用Python进行模板渲染的艺术
Jinja2:使用Python进行模板渲染的艺术
305 0
|
人工智能 云栖大会 开发者
2023云栖大会议程&体验攻略
明天,云栖小镇见
233 0
|
SQL 存储 关系型数据库
详解 Flink Catalog 在 ChunJun 中的实践之路
Catalog 提供元数据,以及访问存储在数据库或其他外部系统中的数据所需的函数和信息,能够极大简化用户现有系统开始使用 Flink 所需的步骤,并增强用户体验,本文将为大家带来 Flink Catalog 的介绍以及 Flink Catalog 在 ChunJun 中的实践之路详解。
403 0
详解 Flink Catalog 在 ChunJun 中的实践之路
|
机器学习/深度学习 编解码 自然语言处理
重磅!新增 13 种 Transformer 方法,火速收藏
如今,Transformer 这把火已经烧到了计算机视觉领域,可以说成为今年最大的热点。本着全心全意为社区服务的精神,OpenMMLab 当然不会对此无动于衷。 为了方便大家研究学习,我们基于 MMCV ,在OpenMMLab 6个方向的 repo 中复现了 13 种基于 Transformer 的方法,快来看看有没有你需要的吧。
834 0
重磅!新增 13 种 Transformer 方法,火速收藏
|
域名解析 Ubuntu 网络协议
移植BusyBox根文件系统到野火开发板
移植BusyBox根文件系统到野火开发板
204 0
|
机器学习/深度学习 JSON 算法框架/工具
【Python入门系列】第六篇:Python常用内置库总结
Python是一种功能强大的编程语言,拥有众多内置库,这些库提供了各种各样的功能和工具,方便开发人员进行各种任务。本文将介绍Python中所有常用的内置库,并提供相应的代码示例。
565 2
|
关系型数据库 MySQL 数据安全/隐私保护
Host is not allowed to connect to this MySQL server解决方法
Host is not allowed to connect to this MySQL server解决方法
629 0
|
算法
【算法竞赛进阶指南】車的放置(行列模型二分图最大匹配+匈牙利算法)
【算法竞赛进阶指南】車的放置(行列模型二分图最大匹配+匈牙利算法)
100 0

热门文章

最新文章