美文网首页
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