题目:
给定一个整数数组 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 个更小的元素.
/** * @param {number[]} nums * @return {number[]} */ var countSmaller = function (nums) { let len = nums.length, _result = Array(len).fill(0) for (let i = len - 1; i >= 0; i--) { _result[i] = get_num(i, nums, nums[i]) } function get_num(start, nums, n) { let num = 0 if (start === nums.length - 1) return num for (let i = start; i <= nums.length - 1; i++) { if (nums[i] < n) num++ } return num } return _result }
不是吧?这样一道困难的题就完了?没那么简单,优化下吧
思路
上面的循环会发现i越小循环的次数越多,而且对右边一个数的比较越多 最后一位数需要参与len-1次比较
实现
/** * @param {number[]} nums * @return {number[]} */ var countSmaller = function (nums) { let len = nums.length if (len == 0) return nums let _result = Array(len).fill(0), dp = []; for (let i = len - 1; i >= 0; i--) { // 计算位置 let index = findIndex(dp, nums[i]) // 插入数据 dp.splice(index, 0, nums[i]) // 记录索引 _result[i] = index } function findIndex(arr, target) { let start = 0, end = arr.length - 1; while (start < end) { let mid = parseInt((start + end) / 2,10) if (arr[mid] < target) { start = mid + 1; } else { end = mid; } } if (arr[start] < target) return start + 1; return start } return _result }
本文分享自微信公众号 - 前端小书童(gaowenju_web),作者:坑人的小书童
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2020-07-11
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句