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.

浙公网安备 33010602011771号