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

题目

(https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/)
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例:

输入: [5,2,6,1]
输出: [2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.
在真实的面试中遇到过这道题?

分析

二话不说使用暴力解题(双重遍历)。超时。
嗯,要对代码进行优化
这道题从后往前遍历会比较清楚明了。优化点主要在sorted这个数列。这个sorted实现了对遍历到当前i之后的数据进行排序插入、然后就可以使用二分法进行获取当前大于或者等于nums[i]的第一个位置。这个位置就是当前值的逆序数

代码

 class Solution {
        public List countSmaller(int[] nums) {
            Integer[] res = new Integer[nums.length];
            //sort其实是关键。sort的目的是 对i后面的元素进行从小到大的排序。
            // 每次插入新的数值,前面有几个数就是这个数值现在的逆序数
            List sorted = new ArrayList<>(nums.length);
            int length = nums.length;
            // 从后往前计算
            for (int i = length - 1; i >= 0; i--) {
                int idx = binarySearch(sorted, nums[i]);
                res[i] = idx;
                //实现对sorted的排序。
                sorted.add(idx, nums[i]);
            }

            return Arrays.asList(res);
        }
        // 使用二分法。找大于或等于key的第一个位置
        private int binarySearch(List list, int key) {
            int l = 0;
            int r = list.size();
            while(l

结果

315. 计算右侧小于当前元素的个数_第1张图片
image.png

你可能感兴趣的:(315. 计算右侧小于当前元素的个数)