认识O(NlogN)的排序(二)

简介: 认识O(NlogN)的排序(二)

小和问题

小和问题:在一个数组中,每个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。

例子:数组[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。

解法思路:采用递归的方式分为左右两个数组,则左边的数组产生的小和+右边的数组产生的小和+左右数组合并产生的小和就为最终的结果。


public class SmallSum {
    public static void main(String[] args) {
        int[] arr={3,6,8,4,5};
        int ss=smallSum(arr);
        System.out.println(ss);
    }
    public static int smallSum(int[] arr){
        if(arr==null || arr.length<2){
            return 0;
        }
        return mergeSort(arr,0,arr.length-1);
    }
    public static int mergeSort(int[] arr,int l,int r){
        if(l==r){
            return 0;
        }
        int mid=l+((r-l)>>1);
        return mergeSort(arr,l,mid)+
                mergeSort(arr,mid+1,r)+
                merge(arr,l,mid,r);
    }
    public static int merge(int[] arr,int l,int m,int r){
        //辅助空间
        int[] help=new int[r-l+1];
        int i=0,p1=l,p2=m+1;
        int res=0;
        //都不越界
        while (p1<=m && p2<=r){
            //边界值判断,如果左右两侧值相等的话,应该是右侧指针右移
            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 (int j=0;j<help.length;j++){
            arr[l+j]=help[j];
        }
        return res;
    }
}


逆序对问题

剑指Offer 51

题目描述:


1687268784179.png


题解:


public class nxd {
    public static void main(String[] args) {
        int[] arr={7,5,6,4};
        int ss=smallSum(arr);
        System.out.println(ss);
    }
    public static int smallSum(int[] arr){
        if(arr==null || arr.length<2){
            return 0;
        }
        return mergeSort(arr,0,arr.length-1);
    }
    public static int mergeSort(int[] arr,int l,int r){
        if(l==r){
            return 0;
        }
        int mid=l+((r-l)>>1);
        return mergeSort(arr,l,mid)+
                mergeSort(arr,mid+1,r)+
                merge(arr,l,mid,r);
    }
    public static int merge(int[] arr,int l,int m,int r){
        //辅助空间
        int[] help=new int[r-l+1];
        int i=0,p1=l,p2=m+1;
        int res=0;
        //都不越界
        while (p1<=m && p2<=r){
            //边界值判断,如果左右两侧值相等的话,应该是右侧指针右移
            res+=arr[p1]>arr[p2]?(m-p1+1):0;
            help[i++]=arr[p1]>arr[p2]?arr[p2++]:arr[p1++];
        }
        //有一侧越界
        while (p1<=m){
            help[i++]=arr[p1++];
        }
        while (p2<=r){
            help[i++]=arr[p2++];
        }
        for (int j=0;j<help.length;j++){
            arr[l+j]=help[j];
        }
        return res;
    }
}


相关文章
|
存储 算法 搜索推荐
排序篇(四)----归并排序
排序篇(四)----归并排序
60 0
|
11月前
|
算法 搜索推荐 大数据
【算法】排序——归并排序和计数排序
上两篇文章讲解了插入排序、选择排序以及交换排序,每种类型的排序大类下都有一到两种排序,今天给大家带来的是归并排序,和前面几种排序一样都属于比较排序中的一种,是通过比较数组中的元素来实现排序的,还给大家带来一种非比较排序计数排序,让我们开始今天的排序之吧!!!
|
6月前
|
算法 搜索推荐
排序——归并排序
排序——归并排序
43 0
|
11月前
|
算法
【算法】排序——选择排序和交换排序(快速排序)
上篇文章讲述了插入排序及插入排序的优化希尔排序,今天我们继续给大家带来排序中的选择排序和交换排序,选择排序包括直接选择排序、 其中还包括堆排序,因为之前讲过堆排序,这篇文章就不多讲解,点击直达堆排序。交换排序包括冒泡排序、快速排序。让我们开始今天的选择排序之旅吧!!!
认识O(NlogN)的排序(一)
认识O(NlogN)的排序(一)
56 0
|
存储 算法 搜索推荐
排序(4)——归并排序
今天给大家带来比较排序的最后一种,归并排序,这个排序,需要我们对递归,循环控制要有着较强的理解,我相信大家通过前面和小编的一起学习,这里肯定也是得心应手。
95 0
|
算法 API 索引
算法排序6——快速排序(分治思想)
对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理
128 0
算法排序6——快速排序(分治思想)
|
算法 搜索推荐
排序——归并排序和计数排序
介绍归并排序和计数排序
109 0
排序——归并排序和计数排序
|
存储 算法 搜索推荐
C++实现排序 - 02 归并排序、快速排序和堆排序
今天我们继续来整理平均时间复杂度为 O(nlogn) 的三个排序算法,即归并排序、堆排序和快速排序。
270 0
C++实现排序 - 02 归并排序、快速排序和堆排序
|
算法
排序——快速排序
排序——快速排序
118 0
排序——快速排序