美文网首页
LeetCode 315. 计算右侧小于当前元素的个数

LeetCode 315. 计算右侧小于当前元素的个数

作者: 风卷晨沙 | 来源:发表于2019-08-16 15:56 被阅读0次

    1、题目

    计算右侧小于当前元素的个数 - 力扣(LeetCode) https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/submissions/

    2、题解

    这道题的题面很简单。就是计算在元素右侧比该元素小的个数。
    首先想到的自然是暴力法,两次循环遍历,直接比较,时间复杂度是O(n^2).超出时间限制。
    之后看了一下题解的思路,研究了一下归并排序,在归的部分就是把整个数组不断二分,在并的部分就是将二分的部分合一,并且通过在并的同时计算逆序数,从而得到该点的结果。使用归并算法,时间复杂度是O(nlgn).

    3、代码

    //归并排序的利用
        class Solution {
            private int[] indexs;//索引数组
            private int[] temp;//归并临时
            private int[] resultArray;//结果数组
    
            public List<Integer> countSmaller(int[] nums) {
                ArrayList<Integer> result = new ArrayList<>();
                int length = nums.length;
                if(length==0){
                    return result;
                }
                indexs=new int[length];
                temp=new int[length];
                resultArray=new int[length];
    
                for (int i = 0; i < length; i++) {
                    indexs[i]=i;
                }
                mergeSort(nums,0,length-1);
                for (int j = 0; j <length ; j++) {
                    result.add(resultArray[j]);
                }
    
                return result;
            }
    
            private void mergeSort(int[] nums, int Left, int Right) {
                if(Left==Right){
                    return;
                }
                int mid = Left+(Right-Left)/2;
                mergeSort(nums,Left,mid);
                mergeSort(nums,mid+1,Right);
                if(nums[indexs[mid]]>nums[indexs[mid+1]]){
                    merge(nums,Left,mid,Right);
                }
            }
    
            private void merge(int[] nums, int left, int mid, int right) {
                for (int i = left; i <=right ; i++) {
                    temp[i]=indexs[i];
                }
                int p1=left;
                int p2=mid+1;
                //归并大法
                for (int k = left; k <=right; k++) {
                    if(p1>mid){
                        //1、p1耗光了
                        indexs[k]=temp[p2];
                        p2++;
                    }else if(p2>right){
                        //2、p2耗光了
                        indexs[k]=temp[p1];
                        p1++;
                        resultArray[indexs[k]]+=(right-mid);
                    }else if(nums[temp[p1]]<=nums[temp[p2]]){
                        //3、前序小于后序
                        indexs[k]=temp[p1];
                        p1++;
                        resultArray[indexs[k]]+=(p2-mid-1);
                    }else {
                        //4、后序小于前序
                        indexs[k]=temp[p2];
                        p2++;
                    }
                }
            }
        }
    

    4、执行结果

    image.png

    相关文章

      网友评论

          本文标题:LeetCode 315. 计算右侧小于当前元素的个数

          本文链接:https://www.haomeiwen.com/subject/ophqsctx.html