赞
踩
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self
输入: [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; let res = new Array(len).fill(0); for(let i = len -1; i>=0;--i){ for(let j = i+1; j<len;++j){ if(nums[i]>nums[j]){ res[i]++; } } } return res; };
从最后一个元素开始遍历,比较他和后面元素的大小,并记录,但这个会超时,不能ac
因为每个元素的遍历都要,和之后的所有元素进行比较,那如果对后面的元素进行排序,当遇到比该元素小的值时,停止比较,记录一下之后元素的个数。代码如下
/** * @param {number[]} nums * @return {number[]} */ function ListNode(value){ this.val = value; this.next = null this.length = 1; } var countSmaller = function(nums) { let len = nums.length; let head = new ListNode(-1); let res = new Array(len).fill(0); for(let i = len -1; i>=0;--i){ let pre = head; while(pre.next && pre.next.val>=nums[i]){ pre.next.length++; pre = pre.next; } let node = new ListNode(nums[i]); node.length = pre.next?pre.next.length+1:0; node.next = pre.next; pre.next = node; res[i] = node.length; } return res; };
这个结果是可以ac的,但时间效率不高,本质还是O(n^2)。
其实这道题和另一道求逆序对个数的题很像,但那道题是求逆序对的总数,而这道题是求每个位置开始的逆序对,一开始也是想用归并做的,但考虑到归并的时候会是数组的索引会变,如果要新增了一个索引数组作为映射,貌似也很麻烦,所以就没往归并的方向做下去了。 但看题解的时候,发现可以归并一个索引数组,代码如下:
/** * @param {number[]} nums * @return {number[]} */ var countSmaller = function(nums) { let len = nums.length; let arr_index = new Array(len); nums.forEach((_,key)=>{ arr_index[key] = key; }) let ans = new Array(len).fill(0); const merge = (left, right)=>{ let llen = left.length; let rlen = right.length; let len = llen+rlen; let res = new Array(len); for(let i = 0, j= 0, k= 0 ; k <len;++k){ if(i == llen){ res[k] = right[j++] }else if(j == rlen){ res[k] = left[i++]; }else if(nums[left[i]]>nums[right[j]]){ ans[left[i]]+=(rlen-j); res[k] = left[i++]; }else{ res[k] = right[j++]; } } return res; } const mergeSort = (arr)=>{ if(arr.length<2){ return arr; } let len = arr.length; let mid = len>>1; let left = arr.slice(0,mid); let right = arr.slice(mid); return merge(mergeSort(left), mergeSort(right)); } mergeSort(arr_index); return ans; };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。