Skip to content

Commit 23395a1

Browse files
Reverse Pairs
1 parent 9d8ce18 commit 23395a1

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ My accepted leetcode solutions to some of the common interview problems.
128128
#### [Divide and Conquer](problems/src/divide_and_conquer)
129129

130130
- [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium)
131+
- [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard)
131132
- [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium)
132133

133134
#### [Dynamic Programming](problems/src/dynamic_programming)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package divide_and_conquer;
2+
import java.util.*;
3+
/**
4+
* Created by gouthamvidyapradhan on 30/06/2018.
5+
* Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].
6+
7+
You need to return the number of important reverse pairs in the given array.
8+
9+
Example1:
10+
11+
Input: [1,3,2,3,1]
12+
Output: 2
13+
Example2:
14+
15+
Input: [2,4,3,5,1]
16+
Output: 3
17+
Note:
18+
The length of the given array will not exceed 50,000.
19+
All the numbers in the input array are in the range of 32-bit integer.
20+
21+
Solution: O(n log n):
22+
Example: 1,3,2,3,1
23+
1. Sort the array in non-increasing order (if there is a collision, sort by lower index).
24+
So the sorted array will be (3, 3, 2, 1, 1) having indexes (1, 3, 2, 0, 4)
25+
2. Maintain a prefix sum of index (starting from 1) for the sorted array. So, prefix sum for the above sorted array is
26+
(1, 2, 3, 4, 5)
27+
Now, the basic idea is to iterate from index n - 1 to 0 in the original array and for each element calculate the
28+
element p (num[i] x 2) and find the upper bound of the element p in sorted array which is 3 at index 1 in this case
29+
and add prefix sum of the index 1 to the result. So the result now becomes 2.
30+
31+
To maintain a prefix sum and update it efficiently we have to use a BIT or Fenwick tree.
32+
33+
34+
*/
35+
public class ReversePairs {
36+
37+
class Pair{
38+
int i, n;
39+
Pair(int i, int n){
40+
this.i = i;
41+
this.n = n;
42+
}
43+
int getN(){
44+
return n;
45+
}
46+
int getI(){
47+
return i;
48+
}
49+
}
50+
51+
/**
52+
* Main method
53+
* @param args
54+
* @throws Exception
55+
*/
56+
public static void main(String[] args) throws Exception{
57+
int[] A = {2,4,3,5,1};
58+
System.out.println(new ReversePairs().reversePairs(A));
59+
}
60+
61+
public int reversePairs(int[] nums) {
62+
List<Pair> list = new ArrayList<>();
63+
Ftree ft = new Ftree(nums.length);
64+
for(int i = 0; i < nums.length; i ++){
65+
list.add(new Pair(i, nums[i]));
66+
ft.update(i, 1);
67+
}
68+
Collections.sort(list, (Comparator.comparing(Pair::getN).reversed().thenComparing(Pair::getI)));
69+
int[] indexMap = new int[nums.length];
70+
for(int i = 0, l = list.size(); i < l; i ++){
71+
indexMap[list.get(i).getI()] = i;
72+
}
73+
int ans = 0;
74+
for(int i = nums.length - 1; i >= 0; i --){
75+
ft.update(indexMap[i], -1);
76+
int index = binarySearch(list, (long)nums[i] * 2);
77+
if(index > -1){
78+
ans += ft.getRangeSum(index);
79+
}
80+
}
81+
return ans;
82+
}
83+
84+
private int binarySearch(List<Pair> list, long n){
85+
int l = 0, h = list.size() - 1;
86+
int ans = -1;
87+
while(l <= h){
88+
int m = l + (h - l) / 2;
89+
if(list.get(m).n > n){
90+
ans = m;
91+
l = m + 1;
92+
} else{
93+
h = m - 1;
94+
}
95+
}
96+
return ans;
97+
}
98+
99+
private class Ftree {
100+
private int[] a;
101+
102+
Ftree(int n) {
103+
a = new int[n + 1];
104+
}
105+
106+
void update(int p, int v) {
107+
for (int i = p + 1; i < a.length; i += (i & (-i))) {
108+
a[i] += v;
109+
}
110+
}
111+
112+
int getRangeSum(int p) {
113+
int sum = 0;
114+
for (int i = p + 1; i > 0; i -= (i & (-i))) {
115+
sum += a[i];
116+
}
117+
return sum;
118+
}
119+
120+
}
121+
}

0 commit comments

Comments
 (0)