• [LeetCode] 315. Count of Smaller Numbers After Self


    You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

    Example 1:

    Input: nums = [5,2,6,1]
    Output: [2,1,1,0]
    Explanation:
    To the right of 5 there are 2 smaller elements (2 and 1).
    To the right of 2 there is only 1 smaller element (1).
    To the right of 6 there is 1 smaller element (1).
    To the right of 1 there is 0 smaller element.

    Constraints:

    • 0 <= nums.length <= 10^5
    • -10^4 <= nums[i] <= 10^4

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

    题意是给一个数组,请你返回一个等长的list,表示当前位置的右侧小于nums[i]的元素个数。

    暴力解是O(n^2)的复杂度,肯定是不行的。我这里给出一个二分法思路。创建一个跟input数组等长的 arr 数组记录结果,同时再创建一个空的 list 做插入排序。数组从右往左扫描,对于每一个元素,我们把他插入到 list 一个合适的位置,使得 list 最后依然是升序排列的。这个插入的动作,比较高效的做法就是用二分。这个元素当时被插入list的index,同时也是这个元素的右侧有多少个元素小于他自己的个数。

    跑一个例子,nums = [5,2,6,1]。一开始插入input数组的最后一个元素1的时候,由于此时list为空,所以插入1的时候,他在 list 的index是0,而且在原数组中最后一个元素的右边没有比他更小的元素了;接着我们再试图把6放入list,此时他在list的index会是1(list = {1, 6}),说明在原数组中,6的右侧有一个元素比他小。

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public List<Integer> countSmaller(int[] nums) {
     3         // 返回结果
     4         List<Integer> res = new ArrayList<>();
     5         // 数组长度为0,直接返回
     6         if (nums.length == 0) {
     7             return res;
     8         }
     9         // 为了提高效率,新建一个数组型的返回结果
    10         int[] arr = new int[nums.length];
    11         // 新建一个list,用于排序
    12         List<Integer> list = new ArrayList<>();
    13         // 从数组最后一位开始向前循环
    14         for (int i = nums.length - 1; i >= 0; i--) {
    15             // 当前数字
    16             int num = nums[i];
    17             // 将当前数字插入到新建list中
    18             // 使用二分查找找到插入位置
    19             int left = 0;
    20             int right = list.size() - 1;
    21             while (left <= right) {
    22                 int mid = (left + right) / 2;
    23                 if (num <= list.get(mid)) {
    24                     right = mid - 1;
    25                 } else {
    26                     left = mid + 1;
    27                 }
    28             }
    29             // 将当前数字插入到相应位置,保证list升序排列
    30             list.add(left, num);
    31             // 当前位置前所有数字均小于当前数字,将个数加入返回结果
    32             arr[i] = left;
    33         }
    34         // 将list转化为数组
    35         for (int count : arr) {
    36             res.add(count);
    37         }
    38         return res;
    39     }
    40 }

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @return {number[]}
     4  */
     5 var countSmaller = function(nums) {
     6     let res = [];
     7     // corner case
     8     if (nums == null || nums.length == 0) {
     9         return nums;
    10     }
    11 
    12     // normal case
    13     let len = nums.length;
    14     let arr = new Array(len).fill(0);
    15     let list = [];
    16     for (let i = len - 1; i >= 0; i--) {
    17         let num = nums[i];
    18         let left = 0;
    19         let right = list.length - 1;
    20         while (left <= right) {
    21             let mid = Math.floor(left + (right - left) / 2);
    22             if (num <= list[mid]) {
    23                 right = mid - 1;
    24             } else {
    25                 left = mid + 1;
    26             }
    27         }
    28         list.splice(left, 0, num);
    29         arr[i] = left;
    30     }
    31     for (let count of arr) {
    32         res.push(count);
    33     }
    34     return res;
    35 };

    相关题目

    315. Count of Smaller Numbers After Self

    1365. How Many Numbers Are Smaller Than the Current Number

    LeetCode 题目总结

  • 相关阅读:
    这些HTML、CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML、CSS、盒子模型、内容布局)
    skywalking在 .net Framework客户端使用
    websoket的扫码登陆简单用法
    微信授权登陆nginx代理
    本地下载文件的方法(兼容下载图片和视频)
    Vue-给对象新增属性(使用Vue.$set())
    浏览器解析URL的过程
    promise es6,es7
    filter全局方法的写法
    监听滚动条
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13772216.html
Copyright © 2020-2023  润新知