LEETCODE 315. 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 个更小的元素.

如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=315

解题思路分析:

如果本题使用暴力解,感觉会超时,因此并没有尝试。看了题目的提示后才发现比较高效的方法是使用二分查找。我们从数组末尾开始向前循环遍历每个数字,循环时,将当前数字插入到一个新的List中,插入时使用二分查找,找到第一个大于等于当前数字的下标,并将其插入到那个下标处,此时数组能够保证升序排列,因此当前下标前的数字个数即是比当前数字小的所有数字个数。

实现代码:

public List<Integer> countSmaller(int[] nums) {
    // 返回结果
    List<Integer> res=new ArrayList<>();
    // 数组长度为0,直接返回
    if(nums.length==0) return res;
    // 为了提高效率,新建一个数组型的返回结果
    int[] arr=new int[nums.length];
    // 新建一个list,用于排序
    List<Integer> list=new ArrayList<>();
    // 从数组最后一位开始向前循环
    for(int i=nums.length-1;i>=0;i--){
        // 当前数字
        int num = nums[i];
        // 将当前数字插入到新建list中
        // 使用二分查找找到插入位置
        int left=0,right=list.size()-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(num<=list.get(mid)) right=mid-1;
            else left=mid+1;
        }
        // 将当前数字插入到相应位置,保证list升序排列
        list.add(left, num);
        // 当前位置前所有数字均小于当前数字,将个数加入返回结果
        arr[i]=left;
    }
    // 将list转化为数组
    for(int count : arr) res.add(count);
    return res;
}

本题解法执行时间为16ms。

Runtime: 16 ms, faster than 39.97% of Java online submissions for Count of Smaller Numbers After Self.

Memory Usage: 38.3 MB, less than 100.00% of Java online submissions for Count of Smaller Numbers After Self.

本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/leetcode-315-count-of-smaller-numbers-after-self-解题思路分析/
此条目发表在leetcode分类目录,贴了, , , 标签。将固定链接加入收藏夹。

发表评论

您的电子邮箱地址不会被公开。