Give you an integer array (index from 0 to n-1, where n is the size of this array, data value from 0 to 10000) . For each element
Ai
in the array, count the number of element before this element Ai
is smaller than it and return count number array.Example
Example 1:
Input:
[1,2,7,8,5]
Output:
[0,1,2,3,2]
Example 2:
Input:
[7,8,2,1,3]
Output:
[0,1,0,0,2]
Clarification
Before you do this, you'd better complete the following three questions: Segment Tree Build, Segment Tree Query II,and Count of Smaller Number before itself I 。
Notice
We suggest you finish problem Segment Tree Build, Segment Tree Query II and Count of Smaller Number first.
Code (Java):public class Solution { /** * @param A: an integer array * @return: A list of integers includes the index of the first number and the index of the last number */ public List<Integer> countOfSmallerNumberII(int[] A) { // write your code here List<Integer> ans = new ArrayList<>(); if (A == null || A.length == 0) { return ans; } SegmentTree segmentTree = new SegmentTree(); segmentTree.build(0, 10000); for (int num : A) { int count = segmentTree.query(0, num - 1); ans.add(count); segmentTree.modify(num, 1); } return ans; } } class SegmentTree { SegmentTreeNode root = null; public void build(int start, int end) { root = buildHelper(start, end); } public int query(int start, int end) { return queryHelper(root, start, end); } public void modify(int index, int value) { modifyHelper(root, index, value); } private void modifyHelper(SegmentTreeNode root, int index, int value) { if (root == null) { return; } if (root.start == root.end && root.start == index) { root.count += value; return; } int mid = root.start + (root.end - root.start) / 2; if (index <= mid) { modifyHelper(root.left, index, value); } else { modifyHelper(root.right, index, value); } root.count = root.left.count + root.right.count; } private int queryHelper(SegmentTreeNode root, int start, int end) { if (root == null || start > end) { return 0; } if (start == root.start && end == root.end) { return root.count; } int mid = root.start + (root.end - root.start) / 2; int leftCount = queryHelper(root.left, Math.max(start, root.start), Math.min(mid, end)); int rightCount = queryHelper(root.right, Math.max(mid + 1, start), Math.min(root.end, end)); return leftCount + rightCount; } private SegmentTreeNode buildHelper(int start, int end) { if (start > end) { return null; } if (start == end) { return new SegmentTreeNode(start, start, 0); } int mid = start + (end - start) / 2; SegmentTreeNode leftChild = buildHelper(start, mid); SegmentTreeNode rightChild = buildHelper(mid + 1, end); SegmentTreeNode root = new SegmentTreeNode(start, end, leftChild.count + rightChild.count); root.left = leftChild; root.right = rightChild; return root; } } class SegmentTreeNode { int start, end; SegmentTreeNode left, right; int count; public SegmentTreeNode(int start, int end, int count) { this.start = start; this.end = end; this.count = count; } }
No comments:
Post a Comment