Description:
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i]
is the number of smaller elements to the right of nums[i]
.
Solution:
经典题目,动态求逆序对,线段树或者树状数组都可以。
另外因为这道题目又没有给数据范围,我做了一下哈希。
<span style="font-size:18px;">import java.util.*;
public class Solution {
List<Integer> list = new ArrayList<Integer>();
public List<Integer> countSmaller(int[] nums) {
int n = nums.length;
if (n == 0)
return list;
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
for (int i = 0; i < n; i++)
if (!map.containsKey(nums[i]))
map.put(nums[i], 0);
int size = map.size();
SegmentTree st = new SegmentTree(new int[size]);
int token = 0;
for (Iterator<Integer> ite = map.keySet().iterator(); ite.hasNext();) {
int key = ite.next();
token++;
map.put(key, token);
}
for (int i = n - 1; i >= 0; i--) {
int key = map.get(nums[i]);
if (key == 1)
list.add(0, 0);
else
list.add(0, st.query(1, key - 1, 1));
st.update(key, 1, 1);
}
return list;
}
class SegmentTree {
int[] lazy;
int n;
node[] nodes;
SegmentTree(int[] arr) {
this.n = arr.length;
lazy = new int[n + 1];
for (int i = 1; i <= n; i++)
lazy[i] = arr[i - 1];
nodes = new node[n * 5];
build(1, n, 1);
}
public int build(int left, int right, int idx) {
nodes[idx] = new node();
nodes[idx].left = left;
nodes[idx].right = right;
if (left == right)
return nodes[idx].lazy = lazy[left];
int mid = (left + right) >> 1;
return nodes[idx].lazy = build(left, mid, idx << 1)
+ build(mid + 1, right, idx << 1 | 1);
}
public void update(int key, int x, int idx) {
nodes[idx].lazy += x;
if (nodes[idx].left == nodes[idx].right)
return;
int mid = nodes[idx].calmid();
if (key <= mid)
update(key, x, idx << 1);
else
update(key, x, idx << 1 | 1);
}
public int query(int left, int right, int idx) {
if (left == nodes[idx].left && right == nodes[idx].right)
return nodes[idx].lazy;
int mid = nodes[idx].calmid();
if (mid >= right)
return query(left, right, idx << 1);
if (mid + 1 <= left)
return query(left, right, idx << 1 | 1);
return query(left, mid, idx << 1)
+ query(mid + 1, right, idx << 1 | 1);
}
}
class node {
int left, right, lazy;
int calmid() {
return (left + right) >> 1;
}
}
public static void main(String[] args) {
int[] arr = { 5, 2, 6, 1 };
Solution s = new Solution();
System.out.println(s.countSmaller(arr));
}
}</span>