Search
 
SCRIPT & CODE EXAMPLE
 

JAVA

How to efficiently count the number of smaller elements to the right of every array element, in Java?


/*
	This is an implementation that demonstrates
	how to efficiently find the number of smaller
	elements to the right of every individual array
	element.
	Example: 
	Input: nums = [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. 
	

	Time complexity: O(nlog2(n)) 
	Space complexity: O(n)
*/

import java.util.List;
import java.util.ArrayList;

public class SmallerNumbers {
	class Item {
		int val;
		int index;

		public Item(int v, int i) {
			val = v;
			index = i;
		}

	}

	public static void main(String[] args) {
		SmallerNumbers application = new SmallerNumbers();
		int[] nums = { 5, 2, 6, 1 };
		List<Integer> output = application.countSmaller(nums);
		System.out.println(output); // [2, 1, 1, 0]
	}

	public List<Integer> countSmaller(int[] nums) {
		int n = nums.length;
		Item[] items = new Item[n];

		for (int i = 0; i < n; i++) {
			items[i] = new Item(nums[i], i);
		}

		int[] count = new int[n];
		mergeSort(items, 0, n - 1, count);

		List<Integer> result = new ArrayList<>();

		for (int c : count) {
			result.add(c);
		}

		return result;

	}

	private void mergeSort(Item[] items, int lo, int hi, int[] count) {
		if (lo >= hi)
			return;
		int mid = lo + (hi - lo) / 2;
		mergeSort(items, lo, mid, count);
		mergeSort(items, mid + 1, hi, count);
		merge(items, lo, mid, mid + 1, hi, count);
	}

	private void merge(Item[] items, int lo, int loEnd, int hi, int hiEnd, int[] count) {
		int m = hiEnd - lo + 1;
		Item[] sorted = new Item[m];
		int index = 0;
		int loPtr = lo, hiPtr = hi;

		int rightCounter = 0;

		while (loPtr <= loEnd && hiPtr <= hiEnd) {
			if (items[hiPtr].val < items[loPtr].val) {
				rightCounter++;
				sorted[index++] = items[hiPtr++];
			} else {
				count[items[loPtr].index] += rightCounter;
				sorted[index++] = items[loPtr++];
			}
		}

		while (loPtr <= loEnd) {
			count[items[loPtr].index] += rightCounter;
			sorted[index++] = items[loPtr++];
		}

		while (hiPtr <= hiEnd) {
			sorted[index++] = items[hiPtr++];
		}

		System.arraycopy(sorted, 0, items, lo, m);

	}
}
Comment

PREVIOUS NEXT
Code Example
Java :: java arraylist get number of elements with same parameter 
Java :: k combinations for range 1 through n 
Java :: spring execute code after variable injected 
Java :: vector inline java 
Java :: java swing button on click 
Java :: set html text android java 
Java :: how to open activity in android studio 
Java :: Utils code for plugin minecraft 
Java :: get sha key android 
Java :: foreach not applicable to type - binary tree sort 
Java :: java parse string to list using gson 
Java :: Which API provides a lightweight solution for GUI components? 
Java :: javafx set min window size 
Java :: how to make a bot to wait in jda 
Java :: java localdate zoneid example 
Java :: string to localdate in java 
Java :: leetcode 416 
Java :: localdatetime to timestamp 
Java :: stream sum java 
Java :: java initialize array with same value 
Java :: how to read from a txt file in java 
Java :: input string a list in java 
Java :: android studio float to int 
Java :: how to solve simultaneous equations in mathematica 
Java :: String array into LinkedList java 
Java :: how to delete files in java 
Java :: javafx textarea font size 
Java :: print line in jjava 
Java :: java date time 
Java :: difference between java and javax 
ADD CONTENT
Topic
Content
Source link
Name
2+8 =