赞
踩
示例:
输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素
提示:
0 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
其实题目的要求就已经有所暗示,说的是每个元素右边比这个元素小的元素个数,就很像归并排序的内部实现过程,因为归并排序内部实现要相互比较,把左边和右边的两个区间的元素比较,实现是没问题,再考虑归并排序的时间复杂度,肯定不会超时,具体实现看代码。
AC代码
class Solution { public: struct Node { int id;//用来做位置标记 int val; int ans; }; void fun(int l,int r,vector<Node>& a) { if(l>=r)return; int mid=(l+r)/2; fun(l,mid,a); fun(mid+1,r,a); vector<Node>q; int s1=l,s2=mid+1,ans=0;//ans表示小的数目 while(s1<=mid&&s2<=r) { if(a[s1].val<=a[s2].val) { a[s1].ans+=ans;//这里累计右边比自己小的元素数目 q.push_back(a[s1]); s1++; } else { q.push_back(a[s2]); s2++; ans++; } } while(s1<=mid) { a[s1].ans+=ans; q.push_back(a[s1]); s1++; } while(s2<=r) { q.push_back(a[s2]); s2++; } for(int i=l,j=0;i<=r;i++,j++) a[i]=q[j]; } vector<Node>a; vector<int> countSmaller(vector<int>& nums) { if(nums.size()==0)return nums; vector<int>res; for(int i=0;i<nums.size();i++) { Node t; t.id=i,t.ans=0,t.val=nums[i]; a.push_back(t); res.push_back(0); } fun(0,nums.size()-1,a); for(int i=0;i<a.size();i++) res[a[i].id]=a[i].ans; return res; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。