315. Count of Smaller Numbers After Self
You are given an integer arraynumsand you have to return a newcountsarray. Thecountsarray has the property wherecounts[i]is the number of smaller elements to the right ofnums[i].
Example:
Input:
[5,2,6,1]
Output:
[2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.Thoughts:
Failed to use template for positive entry... (attaching the code)
d
Code that I failed to implement (failed to handle properly the negative case):
class Solution {
class SegmentTreeNode{
public int start , end, cnt;
public SegmentTreeNode left, right;
public SegmentTreeNode (int start, int end, int cnt){
this.start = start;
this.end = end;
this.cnt = cnt;
this.left = this.right = null;
}
}
public List<Integer> countSmaller(int[] nums) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int num: nums){
if (num > max)
max = num;
if (num < min)
min = num;
}
// System.out.println("1: max: " + max);
SegmentTreeNode root = build(min, max);
List<Integer> ans = new ArrayList<Integer>();
int [] record = new int[nums.length];
for (int i = nums.length - 1; i >=0; i--){
// if(nums[i] > 0){
record[i] = query(root, min, nums[i] - 1);
System.out.println("i: " + i + "; nums[i]: " + nums[i] + " query: " + query(root, min, nums[i] - 1));
modify(root, nums[i], 1);
// }
}
for(int num: record){
ans.add(num);
}
// if (ans.isEmpty()){
// ans.add(0);
// return ans;
// }
return ans;
}
public SegmentTreeNode build (int start, int end){
if (start > end){
return null;
}
if(start == end){
return new SegmentTreeNode (start, end, 0);
}
int mid = (start + end) / 2;
if(mid == end){
mid -= 1;
}
System.out.println("build start: " + start + " end: " + end + " mid: " + mid);
SegmentTreeNode left = build(start, mid);
SegmentTreeNode right = build(mid + 1, end);
SegmentTreeNode ret = new SegmentTreeNode (start, end, 0);
ret.left = left;
ret.right = right;
return ret;
}
public void modify(SegmentTreeNode root, int index, int val){
if(root.start == root.end && root.end == index ){
root.cnt = val;
// System.out.println("index: " + index + " modified as: " + val);
return;
}
int mid = (root.start + root.end) /2 ;
if(mid == root.end){
mid -= 1;
}
if(root.start <= index && index <=mid){
modify(root.left, index, val);
}
if(mid < index && index <= root.end) {
modify(root.right, index, val);
}
root.cnt = root.left.cnt + root.right.cnt;
return;
}
public int query(SegmentTreeNode root, int start, int end){
if(start > end) return 0;
int mid = (root.start + root.end) / 2;
if(mid == root.end){
mid -= 1;
}
System.out.println("Query start: " + start + " end: " + end +
"; root start: " + root.start + " root end: " + root.end + " mid: " + mid
);
if (start == root.start && root.end == end){
System.out.println("exact!");
return root.cnt;
}
int ret = 0;
if (start <= mid ){
System.out.println("left!");
ret += query(root.left, start, mid);
}
if (mid + 1 <= end ){
System.out.println("right!");
ret += query(root.right, mid + 1, end);
}
return ret;
}
}SegmentTree implementation:
BinaryIndexedTree implementation:
BinarySearchTree implementation:
MergeSort implementation T: O(nlogn) S: O(n)
Last updated
Was this helpful?