LeetCode 493 Reverse Pairs

very easy yo understand the problem: Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j]. You need to return the number of important reverse pairs in the given array.

if I’m not told to solve this problem in segment tree, i will use brute force way.

class Solution {
    public int reversePairs(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int res = 0;
        //the order is important so we can't presort
        for (int i = 0; i< nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] > (long)2 * nums[j]) {
                    res++;
                }
            }
        }
        return res;
    }
}

and this brute force is TLE for sure.

now. i’ve told this problem can solve by segment tree, but I still don’t know how.

but here it is:

class Solution {
    public int reversePairs(int[] nums) {
        int res=0;
        int n=nums.length;
        Seg tree = new Seg(Integer.MIN_VALUE, Integer.MAX_VALUE);
        for (int j = 1; j < n; j++) { //for every one in nums
            tree.add(nums[j-1]); //we add it in the tree
            res += tree.count(nums[j]*2L+1L); //and we calculate the number of nodes in current tree, who is larger than or equals to nums[j]*2 + 1. the reason why we can construct the tree while count the number? because think about this: for any fixed j, when need to find every i, from 0~j-1, the number of nums[i] > nums[j] * 2. and in this case, when we traverse to j, the segement tree which contains infromation from 0~j-1 is constructed, and we only need to find exerything from that. it is exactly what the problem what
        }
        return res;
    }
    
    class Seg {
        private long min, max; //range of current segment tree node
        private int count; //count the number of nodes in segment tree
        private Seg L, R; //two children
        
        public Seg(long min, long max) { //constructor
            this.min = min;
            this.max = max;
            count = 0;
            L = R = null;
        }
        
        public void add(long n) { //add number n to its right position, build the segment tree
            count++;
            if (min==max)return;
            long mid = (max-min)/2+min; //use binaery search to find the right spot
            if (n <= mid) {
                // left
                if (L==null) L = new Seg(min, mid); //
                L.add(n); //add the n into left subtree. until it eached the bottom and placed into the right position
            } else {
                // right
                if (R==null) R = new Seg(mid+1,max);
                R.add(n);
            }
        }
        
        public int count(long n) { //count the number of node which is larger or equals than n, and this count function is actually the query function of segment tree
            if (min>=n) return count; 
            if (max<n) return 0;
            return
                (L==null?0:L.count(n))+
                (R==null?0:R.count(n)); //use recysuib to count
        }
    }
}

and this problem can also solve in divide and conquer:
but it is hard to understand. we will figure this out later.

posted @ 2020-05-06 06:10  EvanMeetTheWorld  阅读(16)  评论(0)    收藏  举报