力扣315 計算右側小於當前元素的個數
阿新 • • 發佈:2020-07-22
題意
給定一個整數陣列 nums,按要求返回一個新陣列 counts。陣列 counts 有該性質: counts[i] 的值是 nums[i] 右側小於 nums[i] 的元素的數量。
題解
可以將陣列nums中的陣列先離散化、去重。用樹狀陣列維護這些數字出現的次數,區間[0,l]就代表了比l小的數字出現了多少次。
我們從後往前遍歷原陣列,每次進行單點更新和區間查詢操作。
class Solution { public: int c[10010],t; map<int,int>mp; vector<int>v; int lowbit(int x) { return x&(-x); } void update(int i,int k) { while(i<=t) { c[i]+=k; i+=lowbit(i); } } int sum(int l) { int sum=0; while(l>=1) { sum+=c[l]; l-=lowbit(l); } return sum; } vector<int> countSmaller(vector<int>& nums) { int n=nums.size(); if(n==0) return v; v.resize(n); for(int i=0;i<n;i++) v[i]=nums[i]; sort(v.begin(),v.end()); t=0; mp[v[0]]=++t; for(int i=1;i<n;i++) { if(v[i]==v[i-1]) continue; else mp[v[i]]=++t; } for(int i=n-1;i>=0;i--) { update(mp[nums[i]],1); v[i]=sum(mp[nums[i]]-1); } return v; } };
類似這種思想還可以用到樹狀陣列求逆序數上。將原陣列離散化後,從前往後依此加入到樹狀陣列中(單點更新),每次區間查詢可以找到比當前數字小的數字總數p,用當前遍歷的i-p即可找到比其大的數。