Welcome to Subscribe On Youtube
493. Reverse Pairs
Description
Given an integer array nums, return the number of reverse pairs in the array.
A reverse pair is a pair (i, j) where:
0 <= i < j < nums.lengthandnums[i] > 2 * nums[j].
Example 1:
Input: nums = [1,3,2,3,1] Output: 2 Explanation: The reverse pairs are: (1, 4) --> nums[1] = 3, nums[4] = 1, 3 > 2 * 1 (3, 4) --> nums[3] = 3, nums[4] = 1, 3 > 2 * 1
Example 2:
Input: nums = [2,4,3,5,1] Output: 3 Explanation: The reverse pairs are: (1, 4) --> nums[1] = 4, nums[4] = 1, 4 > 2 * 1 (2, 4) --> nums[2] = 3, nums[4] = 1, 3 > 2 * 1 (3, 4) --> nums[3] = 5, nums[4] = 1, 5 > 2 * 1
Constraints:
1 <= nums.length <= 5 * 104-231 <= nums[i] <= 231 - 1
Solutions
Merge Sort or Binary Indexed Tree or Segment Tree.
-
class Solution { public int reversePairs(int[] nums) { TreeSet<Long> ts = new TreeSet<>(); for (int num : nums) { ts.add((long) num); ts.add((long) num * 2); } Map<Long, Integer> m = new HashMap<>(); int idx = 0; for (long num : ts) { m.put(num, ++idx); } BinaryIndexedTree tree = new BinaryIndexedTree(m.size()); int ans = 0; for (int i = nums.length - 1; i >= 0; --i) { int x = m.get((long) nums[i]); ans += tree.query(x - 1); tree.update(m.get((long) nums[i] * 2), 1); } return ans; } } class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; c = new int[n + 1]; } public void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } public int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } public static int lowbit(int x) { return x & -x; } } -
class BinaryIndexedTree { public: int n; vector<int> c; BinaryIndexedTree(int _n) : n(_n) , c(_n + 1) {} void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } int lowbit(int x) { return x & -x; } }; class Solution { public: int reversePairs(vector<int>& nums) { set<long long> s; for (int num : nums) { s.insert(num); s.insert(num * 2ll); } unordered_map<long long, int> m; int idx = 0; for (long long num : s) m[num] = ++idx; BinaryIndexedTree* tree = new BinaryIndexedTree(m.size()); int ans = 0; for (int i = nums.size() - 1; i >= 0; --i) { ans += tree->query(m[nums[i]] - 1); tree->update(m[nums[i] * 2ll], 1); } return ans; } }; -
class BinaryIndexedTree: def __init__(self, n): self.n = n self.c = [0] * (n + 1) @staticmethod def lowbit(x): return x & -x def update(self, x, delta): while x <= self.n: self.c[x] += delta x += BinaryIndexedTree.lowbit(x) def query(self, x): s = 0 while x > 0: s += self.c[x] x -= BinaryIndexedTree.lowbit(x) return s class Solution: def reversePairs(self, nums: List[int]) -> int: s = set() for num in nums: s.add(num) s.add(num * 2) alls = sorted(s) m = {v: i for i, v in enumerate(alls, 1)} ans = 0 tree = BinaryIndexedTree(len(m)) for num in nums[::-1]: ans += tree.query(m[num] - 1) tree.update(m[num * 2], 1) return ans -
type BinaryIndexedTree struct { n int c []int } func newBinaryIndexedTree(n int) *BinaryIndexedTree { c := make([]int, n+1) return &BinaryIndexedTree{n, c} } func (this *BinaryIndexedTree) lowbit(x int) int { return x & -x } func (this *BinaryIndexedTree) update(x, delta int) { for x <= this.n { this.c[x] += delta x += this.lowbit(x) } } func (this *BinaryIndexedTree) query(x int) int { s := 0 for x > 0 { s += this.c[x] x -= this.lowbit(x) } return s } func reversePairs(nums []int) int { s := make(map[int]bool) for _, num := range nums { s[num] = true s[num*2] = true } var alls []int for num := range s { alls = append(alls, num) } sort.Ints(alls) m := make(map[int]int) for i, num := range alls { m[num] = i + 1 } tree := newBinaryIndexedTree(len(m)) ans := 0 for i := len(nums) - 1; i >= 0; i-- { ans += tree.query(m[nums[i]] - 1) tree.update(m[nums[i]*2], 1) } return ans } -
class Solution { public int reversePairs(int[] nums) { TreeSet<Long> ts = new TreeSet<>(); for (int num : nums) { ts.add((long) num); ts.add((long) num * 2); } Map<Long, Integer> m = new HashMap<>(); int idx = 0; for (long num : ts) { m.put(num, ++idx); } BinaryIndexedTree tree = new BinaryIndexedTree(m.size()); int ans = 0; for (int i = nums.length - 1; i >= 0; --i) { int x = m.get((long) nums[i]); ans += tree.query(x - 1); tree.update(m.get((long) nums[i] * 2), 1); } return ans; } } class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; c = new int[n + 1]; } public void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } public int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } public static int lowbit(int x) { return x & -x; } } -
class Solution { public int reversePairs(int[] nums) { TreeSet<Long> ts = new TreeSet<>(); for (int num : nums) { ts.add((long) num); ts.add((long) num * 2); } Map<Long, Integer> m = new HashMap<>(); int idx = 0; for (long num : ts) { m.put(num, ++idx); } SegmentTree tree = new SegmentTree(m.size()); int ans = 0; for (int i = nums.length - 1; i >= 0; --i) { int x = m.get((long) nums[i]); ans += tree.query(1, 1, x - 1); tree.modify(1, m.get((long) nums[i] * 2), 1); } return ans; } } class Node { int l; int r; int v; } class SegmentTree { private Node[] tr; public SegmentTree(int n) { tr = new Node[4 * n]; for (int i = 0; i < tr.length; ++i) { tr[i] = new Node(); } build(1, 1, n); } public void build(int u, int l, int r) { tr[u].l = l; tr[u].r = r; if (l == r) { return; } int mid = (l + r) >> 1; build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r); } public void modify(int u, int x, int v) { if (tr[u].l == x && tr[u].r == x) { tr[u].v += v; return; } int mid = (tr[u].l + tr[u].r) >> 1; if (x <= mid) { modify(u << 1, x, v); } else { modify(u << 1 | 1, x, v); } pushup(u); } public void pushup(int u) { tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v; } public int query(int u, int l, int r) { if (tr[u].l >= l && tr[u].r <= r) { return tr[u].v; } int mid = (tr[u].l + tr[u].r) >> 1; int v = 0; if (l <= mid) { v += query(u << 1, l, r); } if (r > mid) { v += query(u << 1 | 1, l, r); } return v; } } -
class BinaryIndexedTree { public: int n; vector<int> c; BinaryIndexedTree(int _n) : n(_n) , c(_n + 1) {} void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } int lowbit(int x) { return x & -x; } }; class Solution { public: int reversePairs(vector<int>& nums) { set<long long> s; for (int num : nums) { s.insert(num); s.insert(num * 2ll); } unordered_map<long long, int> m; int idx = 0; for (long long num : s) m[num] = ++idx; BinaryIndexedTree* tree = new BinaryIndexedTree(m.size()); int ans = 0; for (int i = nums.size() - 1; i >= 0; --i) { ans += tree->query(m[nums[i]] - 1); tree->update(m[nums[i] * 2ll], 1); } return ans; } }; -
class Node { public: int l; int r; int v; }; class SegmentTree { public: vector<Node*> tr; SegmentTree(int n) { tr.resize(4 * n); for (int i = 0; i < tr.size(); ++i) tr[i] = new Node(); build(1, 1, n); } void build(int u, int l, int r) { tr[u]->l = l; tr[u]->r = r; if (l == r) return; int mid = (l + r) >> 1; build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r); } void modify(int u, int x, int v) { if (tr[u]->l == x && tr[u]->r == x) { tr[u]->v += v; return; } int mid = (tr[u]->l + tr[u]->r) >> 1; if (x <= mid) modify(u << 1, x, v); else modify(u << 1 | 1, x, v); pushup(u); } void pushup(int u) { tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v; } int query(int u, int l, int r) { if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v; int mid = (tr[u]->l + tr[u]->r) >> 1; int v = 0; if (l <= mid) v = query(u << 1, l, r); if (r > mid) v += query(u << 1 | 1, l, r); return v; } }; class Solution { public: int reversePairs(vector<int>& nums) { set<long long> s; for (int num : nums) { s.insert(num); s.insert(num * 2ll); } unordered_map<long long, int> m; int idx = 0; for (long long num : s) m[num] = ++idx; SegmentTree* tree = new SegmentTree(m.size()); int ans = 0; for (int i = nums.size() - 1; i >= 0; --i) { ans += tree->query(1, 1, m[nums[i]] - 1); tree->modify(1, m[nums[i] * 2ll], 1); } return ans; } }; -
class BinaryIndexedTree: def __init__(self, n): self.n = n self.c = [0] * (n + 1) @staticmethod def lowbit(x): return x & -x def update(self, x, delta): while x <= self.n: self.c[x] += delta x += BinaryIndexedTree.lowbit(x) def query(self, x): s = 0 while x > 0: s += self.c[x] x -= BinaryIndexedTree.lowbit(x) return s class Solution: def reversePairs(self, nums: List[int]) -> int: s = set() for num in nums: s.add(num) s.add(num * 2) alls = sorted(s) m = {v: i for i, v in enumerate(alls, 1)} ans = 0 tree = BinaryIndexedTree(len(m)) for num in nums[::-1]: ans += tree.query(m[num] - 1) tree.update(m[num * 2], 1) return ans -
class Node: def __init__(self): self.l = 0 self.r = 0 self.v = 0 class SegmentTree: def __init__(self, n): self.tr = [Node() for _ in range(4 * n)] self.build(1, 1, n) def build(self, u, l, r): self.tr[u].l = l self.tr[u].r = r if l == r: return mid = (l + r) >> 1 self.build(u << 1, l, mid) self.build(u << 1 | 1, mid + 1, r) def modify(self, u, x, v): if self.tr[u].l == x and self.tr[u].r == x: self.tr[u].v += 1 return mid = (self.tr[u].l + self.tr[u].r) >> 1 if x <= mid: self.modify(u << 1, x, v) else: self.modify(u << 1 | 1, x, v) self.pushup(u) def pushup(self, u): self.tr[u].v = self.tr[u << 1].v + self.tr[u << 1 | 1].v def query(self, u, l, r): if self.tr[u].l >= l and self.tr[u].r <= r: return self.tr[u].v mid = (self.tr[u].l + self.tr[u].r) >> 1 v = 0 if l <= mid: v += self.query(u << 1, l, r) if r > mid: v += self.query(u << 1 | 1, l, r) return v class Solution: def reversePairs(self, nums: List[int]) -> int: s = set() for num in nums: s.add(num) s.add(num * 2) alls = sorted(s) m = {v: i for i, v in enumerate(alls, 1)} tree = SegmentTree(len(m)) ans = 0 for v in nums[::-1]: x = m[v] ans += tree.query(1, 1, x - 1) tree.modify(1, m[v * 2], 1) return ans -
type BinaryIndexedTree struct { n int c []int } func newBinaryIndexedTree(n int) *BinaryIndexedTree { c := make([]int, n+1) return &BinaryIndexedTree{n, c} } func (this *BinaryIndexedTree) lowbit(x int) int { return x & -x } func (this *BinaryIndexedTree) update(x, delta int) { for x <= this.n { this.c[x] += delta x += this.lowbit(x) } } func (this *BinaryIndexedTree) query(x int) int { s := 0 for x > 0 { s += this.c[x] x -= this.lowbit(x) } return s } func reversePairs(nums []int) int { s := make(map[int]bool) for _, num := range nums { s[num] = true s[num*2] = true } var alls []int for num := range s { alls = append(alls, num) } sort.Ints(alls) m := make(map[int]int) for i, num := range alls { m[num] = i + 1 } tree := newBinaryIndexedTree(len(m)) ans := 0 for i := len(nums) - 1; i >= 0; i-- { ans += tree.query(m[nums[i]] - 1) tree.update(m[nums[i]*2], 1) } return ans }