//解法一:分治 用额外的index数组记录下标 根据index归并排序并计算答案 有点慢我日classSolution{int[] res;int[] tmp;int[] index;public List<Integer>countSmaller(int[] nums){int n = nums.length;
res =newint[n];
tmp =newint[n];
index =newint[n];for(int i =0; i < n; i++)
index[i]= i;merge(nums,0, n -1);
List<Integer> list =newArrayList<Integer>();for(int num : res){
list.add(num);}return list;}publicvoidmerge(int[] a,int l,int r){if(l == r)return;int mid = l + r >>1;merge(a, l, mid);merge(a, mid +1, r);if(a[index[mid]]<= a[index[mid +1]])return;//合并for(int i = l; i <= r; i++)
tmp[i]= index[i];int i = l;int j = mid +1;for(int k = l; k <= r; k++){if(i > mid){
index[k]= tmp[j++];}elseif(j > r){
index[k]= tmp[i++];
res[index[k]]+=(r - mid);}else{if(a[tmp[i]]<= a[tmp[j]]){
index[k]= tmp[i++];
res[index[k]]+= j - mid -1;}else{
index[k]= tmp[j++];}}}}}
//解法二:树状数组 慢。。。。classSolution{public List<Integer>countSmaller(int[] nums){
LinkedList<Integer> res =newLinkedList<>();int len = nums.length;if(len ==0)return res;//将nums中的元素排序,记录每个元素对应的索引
TreeSet<Integer> set =newTreeSet();for(int i =0; i < len; i++){
set.add(nums[i]);}
Map<Integer, Integer> map =newHashMap<>();int index =1;for(Integer n : set){
map.put(n, index);
index++;}//利用索引更新并统计
FenwickTree fenwickTree =newFenwickTree(len +1);for(int i = len -1; i >=0; i--){
index = map.get(nums[i]);//在索引位置添加计数1
fenwickTree.update(index,1);//统计比索引对应元素小的个数
res.addFirst(fenwickTree.query(index -1));}return res;}//线段树,O(logn)实现单点更新和前缀和计算privateclassFenwickTree{privateint[] tree;privateint len;publicFenwickTree(int n){this.len = n;
tree =newint[n +1];}//更新本节点和父节点publicvoidupdate(int i,int delta){while(i <=this.len){
tree[i]+= delta;
i +=lowbit(i);}}//求和,找到对应树的节点publicintquery(int i){int sum =0;while(i >0){
sum += tree[i];
i -=lowbit(i);}return sum;}//计算第一个非0的位置,2的幂publicintlowbit(int x){return x &(-x);}}}