LeetCode Count of Smaller Numbers After Self

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>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章