LeetCode315 Count of Smaller Numbers After Self

  1. Count of Smaller Numbers After Self
    You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

用归并排序解决:(也可以用BST,还没试,以后再说)

	int[] counts; //设置全局变量,在merge的时候改变其值
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> res = new ArrayList<Integer>();
        int[] index = new int[nums.length]; //根据元素大小排序其索引,而非直接排序元素,因为counts[]在merge的时候要根据数组原索引增加值。
        for(int i = 0; i < nums.length; i++){
            index[i] = i;
        }
        counts = new int[nums.length];
        mergeSort(nums,index,0,nums.length-1);
        for(int i = 0; i < counts.length; i++){
            res.add(counts[i]);
        }
        return res;
    }
    public void mergeSort(int[] nums, int[] index, int start, int end){
        if(start >= end)  return;
        int mid = start + (end - start) / 2;
        mergeSort(nums,index,start,mid);
        mergeSort(nums,index,mid+1,end);
        merge(nums,index,start,mid,end);
    }
    public void merge(int[] nums, int[] index, int start, int mid, int end){
        int[] newIndex = new int[end - start + 1];  //这里要注意,我一开设置成new int[nums.length]
       												 //然后在最下面for循环重新赋值
       												 //就是for(int i = start; i <= end; i++){
         											 //      index[i] = newIndex[i];
          											  //	}   这样时间复杂度加了很多,不好。
        int rightCount = 0;
        int leftIdx = start;
        int rightIdx = mid + 1;
        int sort_index = 0;
        while(leftIdx <= mid && rightIdx <= end){
            if(nums[index[leftIdx]] <= nums[index[rightIdx]]){
                counts[index[leftIdx]] += rightCount;
                newIndex[sort_index++] = index[leftIdx++];
            }else{
                rightCount++;
                newIndex[sort_index++] = index[rightIdx++];
            }
        }
        while(leftIdx <= mid){
            counts[index[leftIdx]] += rightCount;
            newIndex[sort_index++] = index[leftIdx++];
        }
        while(rightIdx <= end){
            newIndex[sort_index++] = index[rightIdx++];
        }
        for(int i = start; i <= end; i++){
            index[i] = newIndex[i-start];
        }
    }

猜你喜欢

转载自blog.csdn.net/fruit513/article/details/84849743