JAVA程序设计:计算右侧小于当前元素的个数(LeetCode:315)

给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

示例:

输入: [5,2,6,1]
输出: [2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.

思路:我们先看另一道题:

给你一个数组,对于每个位置i,求出所有在i之前的比位置i上的数大的数

这不就是求逆序数嘛,这道题不是大同小异嘛,我们想一下求逆序数比较快速的方法,树状数组? 归并排序?线段树?

其实都是可以的,我们采用比较常用的归并排序吧。

对于三个数组的解释:

temp:存储元素的初始索引

indexes:存储元素排序后的最终索引

counter:每个位置上的答案

class Solution {
	private int[] temp;
	private int[] counter;
	private int[] indexes;
    public List countSmaller(int[] nums) {
    	List res=new ArrayList<>();
    	int len=nums.length;
    	if(len==0) return res;
    	
    	temp=new int[len];
    	counter=new int[len];
    	indexes=new int[len];
    	
    	for(int i=0;inums[indexes[mid+1]])
    		mergeOfTwoSortedArrAndCountSmaller(nums,l,mid,r);
    }
    
    private void mergeOfTwoSortedArrAndCountSmaller(int[] nums,int l,int mid,int r)
    {
    	for(int i=l;i<=r;i++)
    		temp[i]=indexes[i];
    	int i=l,j=mid+1;
    	for(int k=l;k<=r;k++)
    	{
    		if(i>mid)
    		{
    			indexes[k]=temp[j];
    			j++;
    		}
    		else if(j>r)
    		{
    			indexes[k]=temp[i];
    			i++;
    			counter[indexes[k]]+=r-mid;
    		}
    		else if(nums[temp[i]]<=nums[temp[j]])
    		{
    			indexes[k]=temp[i];
    			i++;
    			counter[indexes[k]]+=(j-mid-1);
    		}
    		else
    		{
    			indexes[k]=temp[j];
    			j++;
    		}
    	}
    }
}

 

你可能感兴趣的:(JAVA程序设计:计算右侧小于当前元素的个数(LeetCode:315))