Count of Smaller Numbers After Self(Hard)

Leetcode Source

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].

Examples

Given nums = [5, 2, 6, 1]

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.

Return the array [2, 1, 1, 0].

树状数组:复杂度将为O(NlgN)

private int lowbit(int x) {
    return x&(-x);
}

private void update(int[] bit, int i, int val) {
    for (; i < bit.length; i += lowbit(i))
        bit[i] += val;
}

private int read(int[] bit, int i) {
    int ans = 0;
    for (; i > 0; i -= lowbit(i))
        ans += bit[i];
    return ans;
}

public List<Integer> countSmaller(int[] nums) {
    int[] tmp = nums.clone();
    Arrays.sort(tmp);
    for (int i = 0; i < nums.length; i++)
        nums[i] = Arrays.binarySearch(tmp, nums[i]);

    int[] bit = new int[nums.length+1];
    Integer[] ans = new Integer[nums.length];
    for (int i = nums.length - 1; i >= 0; i--) {
        ans[i] = read(bit, nums[i]);
        update(bit, nums[i] + 1, 1);
    }
    return Arrays.asList(ans);
}
public List<Integer> countSmaller(int[] nums) {
        List<Integer> result = new ArrayList<Integer>();
        if (nums == null || nums.length == 0) return result;

        List<Integer> sorted = new ArrayList<>();
        for (int i = nums.length - 1; i >= 0; i--) {
            int index = find(sorted, nums[i]);
            result.add(index);
            sorted.add(index,nums[i]);
        }
        Collections.reverse(result);//!!don't forget to reverse
        return result;
    }

    public int find(List<Integer> sorted, int val) {
        //if (sorted.size() == 0) return 0; no need
        int lo = 0, hi = sorted.size() - 1;
        while (lo <= hi) {
            int mid = (lo + hi) / 2;
            if (sorted.get(mid) == val) {
                while (mid - 1 >= 0 && sorted.get(mid - 1) == val) {
                    mid--;
                }
                return mid;
            } else if (sorted.get(mid) < val) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }
        return lo;
    }

Reference

1 http://yuancrackcode.com

2 Count of Range Sum

results matching ""

    No results matching ""