• 小和问题(归并排序的例子)


    小和问题
    在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和。 求一个数组
    的小和。
    例子:
    [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

    如果直接用两层for循环扫一遍,时间复杂度O(n*n),这个题目可以利用归并排序把时间复杂度降到O(nlogn)

    上代码

    import java.io.BufferedInputStream;
    import java.util.Scanner;
    
    public class test {
        public static int[] help;
    
        public static int mergeSort(int[] a) {
            if (a == null || a.length < 2) {
                return 0;
            }
            help = new int[a.length];
            return sort(a, 0, a.length - 1);
        }
    
        public static int sort(int[] a, int lo, int hi) {
            if (lo >= hi) {
                return 0;
            }
            int mid = lo + ((hi - lo) >> 1);
            return sort(a, lo, mid) + sort(a, mid + 1, hi) + merge(a, lo, mid, hi); // 回到大区间的时候每部分都排好序了
        }
    
        public static int merge(int[] a, int lo, int mid, int hi) {
            int j = lo, k = mid + 1, res = 0;
            for (int i = lo; i <= hi; ++i) {
                help[i] = a[i];
            }
            for (int i = lo; i <= hi; ++i) {
                if (j > mid) {
                    a[i] = help[k++];
                } else if (k > hi) {
                    a[i] = help[j++];
                } else if (help[j] < help[k]) {
                    res += (hi - k + 1) * help[j]; // k~hi之间的所有数都比help[j]大, res就是对help[j]来说前面小于它的数字之和
                    a[i] = help[j++];
                } else {
                    a[i] = help[k++];
                }
            }
            return res;
        }
    
        public static void main(String[] args) {
            Scanner cin = new Scanner(new BufferedInputStream(System.in));
            int n = cin.nextInt(); // 要排序的数量
            int[] a = new int[n]; // 如果要排字符串用String[],排double用Double[],以此类推,就成了通用排序数组
            for (int i = 0; i < n; ++i) {
                a[i] = cin.nextInt();
            }
            cin.close();
            System.out.println(mergeSort(a)); // 在排好序的时候小数和已经求出来了
            /*if (n != 0) {
                System.out.print(a[0]);
            }
            for (int i = 1; i < n; ++i) {
                System.out.print(" " + a[i]);
            }*/
        }
    }



    ========================================Talk is cheap, show me the code=======================================

    CSDN博客地址:https://blog.csdn.net/qq_34115899
  • 相关阅读:
    cookie简介
    Javaweb
    apache-tomcat-7.0.92
    学javaweb 先学Servlet 应用理论很重要
    DataGuard切换(主库为Rac+备库为Rac)
    Oracle 迁移 序列
    oracle SQL 执行进度
    ORA-20011 ORA-29913 KUP-11024 GATHER_TABLE_STATS
    盘点 Oracle 11g 中新特性带来的10大性能影响
    查询近一个月的表空间使用情况
  • 原文地址:https://www.cnblogs.com/lcy0515/p/9179769.html
Copyright © 2020-2023  润新知