[路飞][LeetCode]315_计算右侧小于当前元素的个数

「这是我参与2022首次更文挑战的第38天,活动详情查看:2022首次更文挑战

看一百遍美女,美女也不一定是你的。但你刷一百遍算法,知识就是你的了~~

谁能九层台,不用累土起!

题目地址

题目

给你一个整数数组 nums **,按要求返回一个新数组 counts **。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例 1:

输入: nums = [5,2,6,1]
输出: [2,1,1,0] 
解释: 
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素
复制代码

示例 2:

输入: nums = [-1]
输出: [0]
复制代码

示例 3:

输入: nums = [-1,-1]
输出: [0,0]
复制代码

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

暴力解

常规操作,先尝试暴力解

  • 我们定义一个数组用来存返回值
  • 遍历数组,从遍历到的项开始继续向右遍历
  • 对右侧的比当前项小的数的个数进行计数
  • 将计数的结果存入数组
var countSmaller = function(nums) {
    const arr = []
    for(let i = 0;i<nums.length;i++){
        let count = 0
        for(let j = i;j<nums.length;j++){
            if(nums[j]<nums[i]){
                count++
            }
        }
        arr.push(count)
    }
    return arr
};
复制代码

虽然解法简单粗暴,但是遗憾的是超时了

解题思路

  • 我们从末尾开始查找小于当前元素的数
  • 我们定义一个数组用于存放已经查找过的元素
  • 将查找过的元素按升序放入数组中
  • 使用二分查找,在用于存已找过的数组中找到比当前元素小的元素的个数

解题代码

var countSmaller = function(nums) {
    let temp = [] , res = Array(nums.length)
    for(let i = nums.length - 1; i >= 0; i--) {
        let l = 0 , r = temp.length
        while(l < r) {
            const mid =  Math.floor((r + l)/2)
            if(temp[mid] >= nums[i]) {
                r = mid
            } else {
                l = mid + 1
            }
        }
        res[i] = l
        temp.splice(l,0,nums[i])  
    }
    return res
};
复制代码

别把人生的希望寄托在别人身上,没人有这义务和能力.

如有任何问题或建议,欢迎评论区留言讨论!

Supongo que te gusta

Origin juejin.im/post/7068093164313116709
Recomendado
Clasificación