1. 程式人生 > >LeetCode315 Count of Smaller Numbers After Self

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];
        }
    }