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:
Given nums = [5, 2, 6, 1] 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.
Return the array [2, 1, 1, 0]
.
https://leetcode.com/problems/count-of-smaller-numbers-after-self/
在数组中统计当前数之后比他小的数的个数,复杂度要小于O(n^2)。
首先注意到应该从右往左遍历,记录下访问过的数,这样就转化成了子问题:
怎么从一个数据结构中快速找出所有比他小的数,并且这个数据结构要支持O(logn)的插入操作。
那么就想到用二叉搜索树,所有左子树的数据都比当前节点小,这边用数组实现BST。
二分查找插入的位置,这个位置恰好也代表了左边有几个比他小的数。
1 /** 2 * @param {number[]} nums 3 * @return {number[]} 4 */ 5 var countSmaller = function(nums) { 6 var i, bst = [], result = [], index; 7 for(i = nums.length - 1; i >= 0; i--){ 8 index = getBSTIndex(bst, nums[i]); 9 result.unshift(index); 10 bst.splice(index, 0, nums[i]); 11 } 12 return result; 13 14 function getBSTIndex(bst, num){ 15 if(bst.length === 0) return 0; 16 var start = 0, end = bst.length , middle; 17 if(bst[start] >= num) return 0; 18 if(bst[end] <= num) return bst.length; 19 while(start < end){ 20 middle = (start + end) >> 1; 21 if(bst[middle] >= num) 22 end = middle; 23 else 24 start = middle + 1; 25 } 26 return start; 27 } 28 };