315. 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.
class Solution {
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> list = new ArrayList();
        int[] n = new int[nums.length];
        if(nums.length == 0) return list;
        for(int i = 0; i < nums.length; i++){
            for(int j = i + 1; j < nums.length; j++){
                if(nums[j] < nums[i]) n[i]++;
            }
            list.add(n[i]);
        }
        return list;
    }
}

尼玛,TLE了,咋不早说不能O(n²)

class Solution {
public List<Integer> countSmaller(int[] nums) {
        if(nums == null || nums.length == 0) {
            return new ArrayList();
        }
        int[][] arr = new int[nums.length][2];
        for(int i = 0; i < arr.length; ++i) {
            arr[i] = new int[]{nums[i], i};
        }
        
        int[] count = new int[nums.length];
        ms(arr, count);
        
        List<Integer> ret = new ArrayList();
        for(int i = 0; i < count.length; ++i) {
            ret.add(count[i]);
        }
        return ret;
    }
    
    private void ms(int[][] arr, int[] count) {
        int[][] temp = new int[arr.length][2];
        Arrays.fill(temp, new int[2]);
        ms(arr, temp, 0, arr.length - 1, count);
    }
    
    private void ms(int[][] arr, int[][] temp, int left, int right, int[] count) {
        if(left == right) {
            return;
        }
        
        int mid = left + (right - left) / 2;
        ms(arr, temp, left, mid, count);
        ms(arr, temp, mid + 1, right, count);
        merge(arr, temp, left, mid + 1, right, count);
    }
    
    private void merge(int[][] arr, int[][] temp, int left, int mid, int right, int[] count) {
        int leftEnd = mid, tempPtr = left, tempSection = right - left + 1;
        
        int inverse = 0;
        while(left < leftEnd && mid <= right) {
            // changed from: if(arr[left] <= arr[mid]) {
            if(arr[left][0] <= arr[mid][0]) {
                temp[tempPtr] = arr[left++];
                // added: count[temp[tempPtr][1]] += inverse;
                count[temp[tempPtr][1]] += inverse;
            }else {
                temp[tempPtr] = arr[mid++];
                // added: inverse++;
                inverse++;
            }
            tempPtr++;
        }
        
        while(left < leftEnd) {
            // added: count[arr[left][1]] += inverse;
            count[arr[left][1]] += inverse;
            temp[tempPtr++] = arr[left++];
        }
        
        while(mid <= right) {
            temp[tempPtr++] = arr[mid++];
        }
        
        for(int i = 0; i < tempSection; ++i, --right) {
            arr[right] = temp[right];
        }
    }
}

mergesort

class Solution {
    int[] temp;
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> res = new ArrayList<>();
        int n = nums.length;
        temp = new int[n];
        int[] indexes = new int[n];
        for (int i = 0; i < n; i++) {
            indexes[i] = i;
            res.add(0);
        }
        mergeSort(0, n - 1, indexes, nums, res);
        return res;
    }
    void mergeSort(int start, int end, int[] indexes, int[] nums, List<Integer> res) {
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        mergeSort(start, mid, indexes, nums, res);
        mergeSort(mid + 1, end, indexes, nums, res);
        merge(start, end, indexes, nums, res);
    }
    void merge(int start, int end, int[] indexes, int[] nums, List<Integer> res) {
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        int j = mid + 1;
        int i = start;
        while (i <= mid) {
            while (j <= end && nums[indexes[i]] > nums[indexes[j]]) {
                j++;
            }
            res.set(indexes[i], res.get(indexes[i]) + j - mid - 1);
            i++;
        }
        i = start;
        j = mid + 1;
        int k = start;
        while (i <= mid && j <= end) {
            int a = nums[indexes[i]];
            int b = nums[indexes[j]];
            if (a < b) {
                temp[k++] = indexes[i];
                i++;
            } else {
                temp[k++] = indexes[j];
                j++;
            }
        }
        while (i <= mid) {
            temp[k++] = indexes[i++];
        }
        while (j <= end) {
            temp[k++] = indexes[j++];
        }
        for (k = start; k <= end; k++) {
            indexes[k] = temp[k];
        }
    }
}

 

class TreeNode{
        int smallCount;
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int count, int val){
            this.smallCount = count;
            this.val = val;
        }
    }
    
    public List<Integer> countSmaller(int[] nums) {
        TreeNode root = null;
        Integer[] ret = new Integer[nums.length];
        if(nums == null || nums.length == 0) return Arrays.asList(ret);
        for(int i=nums.length-1; i>=0; i--){
            root = insert(root, nums[i], ret, i, 0);
        }
        return Arrays.asList(ret);
    }
    
    public TreeNode insert(TreeNode root, int val, Integer[] ans, int index, int preSum){
        if(root == null){
            root = new TreeNode(0, val);
            ans[index] = preSum;
        }
        else if(root.val>val){
            root.smallCount++;
            root.left = insert(root.left, val, ans, index, preSum);
        }
        else{
            root.right = insert(root.right, val, ans, index, root.smallCount + preSum + (root.val<val?1:0));//only adding 1 on preSum if root.val is only smaller than val
        }
        return root;
    }

bst, though TLE

posted @ 2019-11-01 01:34  Schwifty  阅读(125)  评论(0编辑  收藏  举报