|
1 | | -import java.util.LinkedList; |
| 1 | +import java.util.ArrayList; |
| 2 | +import java.util.Arrays; |
| 3 | +import java.util.Collections; |
| 4 | +import java.util.HashSet; |
2 | 5 | import java.util.List; |
| 6 | +import java.util.Set; |
3 | 7 |
|
4 | 8 | public class Solution315 { |
5 | | - // -10^4 <= nums[i] <= 10^4 |
6 | | - private static final int OFFSET = 10001; |
7 | | - |
8 | 9 | public List<Integer> countSmaller(int[] nums) { |
9 | | - int max = 0; |
10 | | - for (int num : nums) { |
11 | | - max = Math.max(max, num); |
12 | | - } |
| 10 | + int n = nums.length; |
| 11 | + // 离散化 |
| 12 | + int[] yArr = getDiscrete(nums); |
13 | 13 |
|
14 | | - int len = nums.length; |
15 | | - LinkedList<Integer> resList = new LinkedList<>(); |
16 | | - BinaryIndexedTree bit = new BinaryIndexedTree(max + OFFSET); |
17 | | - for (int i = len - 1; i >= 0; i--) { |
18 | | - bit.update(nums[i] + OFFSET); |
19 | | - // 头插法 |
20 | | - resList.offerFirst(bit.query(nums[i] - 1 + OFFSET)); |
| 14 | + Fenwick fenwick = new Fenwick(yArr.length); |
| 15 | + List<Integer> resList = new ArrayList<>(); |
| 16 | + for (int i = n - 1; i >= 0; i--) { |
| 17 | + int yId = getId(yArr, nums[i]); |
| 18 | + fenwick.add(yId, 1); |
| 19 | + resList.add(fenwick.getSum(yId - 1)); |
21 | 20 | } |
| 21 | + Collections.reverse(resList); |
22 | 22 | return resList; |
23 | 23 | } |
24 | 24 |
|
25 | | - private static class BinaryIndexedTree { |
| 25 | + private int[] getDiscrete(int[] xArr) { |
| 26 | + Set<Integer> set = new HashSet<>(); |
| 27 | + for (int x : xArr) { |
| 28 | + set.add(x); |
| 29 | + } |
| 30 | + int sz = set.size(); |
| 31 | + int[] yArr = new int[sz]; |
| 32 | + int id = 0; |
| 33 | + for (Integer x : set) { |
| 34 | + yArr[id++] = x; |
| 35 | + } |
| 36 | + Arrays.sort(yArr); |
| 37 | + return yArr; |
| 38 | + } |
| 39 | + |
| 40 | + private int getId(int[] yArr, int x) { |
| 41 | + return Arrays.binarySearch(yArr, x) + 1; |
| 42 | + } |
| 43 | + |
| 44 | + private static class Fenwick { |
26 | 45 | private final int n; |
27 | 46 | private final int[] tree; |
28 | 47 |
|
29 | | - public BinaryIndexedTree(int n) { |
| 48 | + public Fenwick(int n) { |
30 | 49 | this.n = n; |
31 | 50 | this.tree = new int[n + 1]; |
32 | 51 | } |
33 | 52 |
|
34 | | - public static int lowbit(int x) { |
35 | | - return x & (-x); |
| 53 | + public int lowbit(int x) { |
| 54 | + return x & -x; |
36 | 55 | } |
37 | 56 |
|
38 | | - public void update(int x) { |
| 57 | + public void add(int x, int k) { |
39 | 58 | while (x <= n) { |
40 | | - ++tree[x]; |
| 59 | + tree[x] += k; |
41 | 60 | x += lowbit(x); |
42 | 61 | } |
43 | 62 | } |
44 | 63 |
|
45 | | - public int query(int x) { |
| 64 | + public int getSum(int x) { |
46 | 65 | int ans = 0; |
47 | | - while (x > 0) { |
| 66 | + while (x >= 1) { |
48 | 67 | ans += tree[x]; |
49 | 68 | x -= lowbit(x); |
50 | 69 | } |
|
0 commit comments