Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) and an query list. For each query, give you an integer, return the number of element in the array that are smaller than the given integer.
For array [1,2,7,8,5]
, and queries [1,8,5]
, return [0,4,2]
用个segment tree的解法
public class Solution { /** * @param A: An integer array * @return: The number of element in the array that * are smaller that the given integer */ public ArrayList<Integer> countOfSmallerNumber(int[] A, int[] queries) { // write your code here ArrayList<Integer> result = new ArrayList<Integer>(); if(A == null) return result; SegmentTreeNode root = build(0, 10000); for(int i = 0; i < A.length; i++){ modify(root, A[i]); } for(int i = 0; i < queries.length; i++){ result.add(query(root, 0, queries[i] - 1)); } return result; } public class SegmentTreeNode{ public int start; public int end; public SegmentTreeNode left; public SegmentTreeNode right; public int count; public SegmentTreeNode(int start, int end){ this.start = start; this.end = end; this.left = null; this.right = null; this.count = 0; } } public SegmentTreeNode build(int start, int end) { // write your code here if(start > end) return null; if(start == end) return new SegmentTreeNode(start, end); SegmentTreeNode root = new SegmentTreeNode(start, end); SegmentTreeNode left = build(start, start + (end - start) / 2); SegmentTreeNode right = build(start + (end - start) / 2 + 1, end); root.left = left; root.right = right; return root; } public void modify(SegmentTreeNode root, int index) { // write your code here if(index > root.end || index < root.start) return; if(root.start == root.end && root.start == index){ root.count++; return; } int mid = root.start + (root.end - root.start) / 2; if(index <= mid){ modify(root.left, index); } else{ modify(root.right, index); } root.count = root.left.count + root.right.count; return; } public int query(SegmentTreeNode root, int start, int end) { // write your code here if(start > end || end < root.start || start > root.end) return 0; if(root.start == start && root.end == end) return root.count; int leftcount = 0; int rightcount = 0; int mid = root.start + (root.end - root.start) / 2; if(start <= mid){ if(end <= mid){ leftcount = query(root.left, start, end); } else{ leftcount = query(root.left, start, mid); } } if(end > mid){ if(start > mid){ rightcount = query(root.right, start, end); } else{ rightcount = query(root.right, mid + 1, end); } } return leftcount + rightcount; } }