算法-计算右侧小于当前元素的个数-分治&归并思想

题目

给你一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例 1:

复制代码
输入:nums = [5,2,6,1]
输出:[2,1,1,0] 
解释:5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

题解

利用归并排序的过程进行统计,这样有两个好处可以提升统计的效率:

1、归并的时候右边的数组元素一定是在左边组数组元素的右边

2、由于是有序数组可以进行快速的统计,提升统计的效率

java 复制代码
class Solution {
//用于记录原本数组对应的位置和数值
    private class Pair{
        int val, id;
        public Pair(int val,int id){
            this.val=val;
            this.id=id;
        }
    }
    private Pair[] temp;
    private int[] count;


    public List<Integer> countSmaller(int[] nums) {
        int n=nums.length;
        count=new int[n];
        temp=new Pair[n];
        Pair[] arr=new Pair[n];
        for(int i=0;i<n;i++){
            arr[i]=new Pair(nums[i],i);
        }
        sort(arr,0,n-1);
        List<Integer> res=new LinkedList<>();
        for(int c:count) res.add(c);
        return res;
        
    }
    private void sort(Pair[] arr,int left,int right){
        if(left==right) return;
        int mid=left+(right-left)/2;
        sort(arr,left,mid);
        sort(arr,mid+1,right);
        merge(arr,left,mid,right);
    
    }
    private void merge(Pair[] arr,int left,int mid,int right){
        for(int i=left;i<=right;i++){
            temp[i]=arr[i];
        }
        int l=left,m=mid+1;
        for(int i=left;i<=right;i++){
            //左边已经排好
            if(l==mid+1){
                arr[i]=temp[m];
                m++;
            }else if(m==right+1){//右边已经排好
                arr[i]=temp[l];
                l++;
                //更新count数组,右侧的所有元素都比当前元素小
                count[arr[i].id]+=m-mid-1;
                //左边比右边大
            }else if(temp[l].val>temp[m].val){//右侧元素比左侧元素小
                arr[i]=temp[m];
                m++;
            }else{
                //左边比右边小
                arr[i]=temp[l];
                l++;
                //右边的当前元素之前的所有元素都比左边数组的当前元素小
                count[arr[i].id]+=m-mid-1;
            }
        }
    }
}
相关推荐
计算机毕设定制辅导-无忧学长几秒前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法
Best_Liu~1 分钟前
SpringBoot全局日期格式化
java·spring boot·后端
黎相思11 分钟前
BTree
数据结构·b树·b+树
少年的范儿12 分钟前
IntelliJ IDEA 配置 JDK 21 与 Maven 教程(Windows):开发环境配置与验证
java·jdk·maven·intellij idea
RuoyiOffice13 分钟前
SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
java·数据库·spring boot·opengauss·信创
Dwzun31 分钟前
基于SpringBoot3+Vue3的油莎豆种植管理系统
java·前端·vue.js·spring boot·后端·python·计算机网络
学长毕设9 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw10 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
UIU11411 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
源码集结号11 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统