Problem Statement
Pattern:
Solution
// freq array prefix sum O(n)
public int[] smallerNumbersThanCurrent(int[] nums) {
// this method is viable since nums[i] < 100
final int MAX = 101;
//create freq arr
int[] freq = new int[MAX];
for (int i = 0; i < nums.length; i++) {
freq[nums[i]]++;
}
// convert into prefix sum arr
for (int i = 1; i < MAX; i++) {
// each index stores the no of elements smaller than it
freq[i] += freq[i - 1];
}
// write to nums array
for (int i = 0; i < nums.length; i++) {
// already correct/ avoid out of bounds
if(nums[i] == 0) break;
nums[i] = freq[nums[i] - 1]; // freq of nums 'up to' nums[i]
}
return nums;
}
// sort array O(nlogn)
public int[] smallerNumberThanCurrentSort(int[] nums) {
// create sorted array
int [] sortedNums = nums.clone();
Arrays.sort(sortedNums);
// insert first location
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < sortedNums.length; i++)
// insert the first pos of el in sorted array
map.putIfAbsent(sortedNums[i], i);
// rewrite array
for (int i = 0; i < nums.length; i++)
nums[i] = map.get(nums[i]);
return nums;
}
Notes
- 2 ways to do it
- Both find the number of elements before the current element
- Enter freqs into a freq array
- Convert into prefix sum
freq[i]
gives you the number of elements that exist in array till valuei
innums
(including i).- So to find no. of elements till value
i
not includingi
, getfreq[i-1]
- Hashmap implmentation stores the first 0-based index of every element’s first occurrence if the array was sorted
- That gives you the no. of elements smaller
nums[i]
, - dry run with first element
1
- That gives you the no. of elements smaller