给定一个整数数组 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
}
博客: 小书童博客
公号: 坑人的小书童