classPair{ int id; int val; Pair(int id,int val){ this.id=id; this.val=val; } }
Pair[] pairs; //索引数组,便于定位某一元素在初始数组中的index,用于更新结果 Pair[] temp; //辅助索引数组,存储merge前已经排序好的前后两部分,用于merge,使merge后pairs里就是最终结果 int[] counts; public List<Integer> countSmaller(int[] nums) { pairs=newPair[nums.length]; temp=newPair[nums.length]; for (inti=0; i < nums.length; i++) { pairs[i]=newPair(i,nums[i]); } counts=newint[pairs.length]; mergeSort(pairs,0,pairs.length-1); List<Integer> res=newArrayList<>(); for (int count : counts) { res.add(count); } return res; }
voidmergeSort(Pair[] pairs, int left, int right){ if(left>=right){ return; } int mid=left+(right-left)/2; mergeSort(pairs,left,mid); mergeSort(pairs,mid+1,right); merge(pairs,left,mid,right); }
voidmerge(Pair[] pairs, int left, int mid, int right){ for (inti= left; i <=right; i++) { temp[i]=pairs[i]; }
The problem is similiar to 315. Count of Smaller Numbers After Self, yoc can click here to check how to slolve it. The difference between two probles is that you need compute the prefix sums, cumsum[i] means nums[:i]’s prefix sums :
Random rand=newRandom(); publicintfindKthLargest(int[] nums, int k) { int n=nums.length; int low=0; int high=n-1; while(low<=high){ int j=partition(nums,low,high); if(j<n-k){ low=j+1; }elseif(j>n-k){ high=j-1; }else{ return nums[j]; } } return -1; }
intpartition(int[] nums, int start, int end){ int index=rand.nextInt(end-start+1)+start; swap(nums,start,index); int pivot=nums[start]; int i=start+1; int j=end; //[start,i) <=pivot //[i,j] unknown //(j,end] >pivot while(i<=j){ if(nums[j]>pivot){ j--; }else{ swap(nums,i++,j); } } swap(nums,start,j); return j; }
voidswap(int[] nums, int i, int j){ if(i==j){ return; } int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; }
Random rand=newRandom(); publicintfindKthLargest(int[] nums, int k) { int n=nums.length; quickSelect(nums,0,n-1,n-k); return nums[n-k]; }
voidquickSelect(int[] nums, int left, int right, int k){ if(left==right){ return; } int pivotIndex=left+rand.nextInt(right-left+1); int pivot=partition(nums,left,right,pivotIndex); if(pivot==k){ return; } if(k<pivot){ quickSelect(nums,left,pivot-1,k); }else{ quickSelect(nums,pivot+1,right,k); } }
intpartition(int[] nums, int left, int right, int pivot){ int val=nums[pivot]; swap(nums,right,pivot); int idx=left; for (inti= left; i <= right; i++) { if(nums[i]<val){ swap(nums,idx++,i); } } swap(nums,idx,right); return idx; }
voidswap(int[] nums, int a, int b){ if(a==b){ return; } nums[a]^=nums[b];//a^b nums[b]^=nums[a];//b^a^b=a nums[a]^=nums[b];//a^b^a=b }
publicintquickSelect(int[] a, int l, int r, int index) { intq= randomPartition(a, l, r); if (q == index) { return a[q]; } else { return q < index ? quickSelect(a, q + 1, r, index) : quickSelect(a, l, q - 1, index); } }
publicintrandomPartition(int[] a, int l, int r) { inti= random.nextInt(r - l + 1) + l; swap(a, i, r); return partition(a, l, r); }
publicintpartition(int[] a, int l, int r) { intx= a[r], i = l - 1; for (intj= l; j < r; ++j) { if (a[j] <= x) { swap(a, ++i, j); } } swap(a, i + 1, r); return i + 1; }
publicvoidswap(int[] a, int i, int j) { inttemp= a[i]; a[i] = a[j]; a[j] = temp; } }
347. Top K Frequent Elements
桶排序更好!
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
Map<Integer,Integer> map=newHashMap<>(); int[] unique; Random rand=newRandom(); publicint[] topKFrequent(int[] nums, int k) { for (int num : nums) { map.put(num,map.getOrDefault(num,0)+1); } int n=map.size(); unique=newint[n]; int idx=0; for (Integer num : map.keySet()) { unique[idx++]=num; } quickSelect(0,n-1,n-k); return Arrays.copyOfRange(unique,n-k,n); }
voidquickSelect(int left, int right, int k){ if(left>=right){ return; } //[k,k+1,..,n-1] int pivotIndex=left+rand.nextInt(right-left+1); int pivot=partition(left,right,pivotIndex); if(pivot==k){ return; } if(k<pivot){ quickSelect(left,pivot-1,k); }else{ quickSelect(pivot+1,right,k); } }
intpartition(int left, int right, int pivot){ int pivotFreq=map.get(unique[pivot]); swap(right,pivot); int idx=left; for (inti= left; i <= right; i++) { if(map.get(unique[i])<pivotFreq){ swap(idx++,i); } } swap(idx,right); return idx; }
voidswap(int a, int b){ if(a==b){ return; } int temp=unique[a]; unique[a]=unique[b]; unique[b]=temp; }