Count of Smaller Numbers After Self leetCode
Given an integer array nums, return an integer array counts where counts[i] is the number of smaller elements to the right of nums[i].
Example 1:
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.
Example 2:
Input: nums = [-1]
Output: [0]
Example 3:
Input: nums = [-1,-1]
Output: [0,0]
BruteForce :
class Solution {
public List<Integer> countSmaller(int[] nums) {
List<Integer> result= new ArrayList<>();
int n=nums.length;
for(int i=0;i<n;i++)
{
int count=0;
for(int j=i+1;j<n;j++)
{
if(nums[i]>nums[j])
{
count++;
}
}
result.add(count);
}
return result;
}
}
Optimal Approach:
class Solution {
public List<Integer> countSmaller(int[] nums) {
int n = nums.length;
int[] result = new int[n];
int[][] pairs = new int[n][2]; // [value, index]
for (int i = 0; i < n; i++) {
pairs[i][0] = nums[i];
pairs[i][1] = i;
}
mergeSort(pairs, 0, n - 1, result);
List<Integer> resList = new ArrayList<>();
for (int count : result) {
resList.add(count);
}
return resList;
}
private void mergeSort(int[][] arr, int left, int right, int[] result) {
if (left >= right) return;
int mid = (left + right) / 2;
mergeSort(arr, left, mid, result);
mergeSort(arr, mid + 1, right, result);
merge(arr, left, mid, right, result);
}
private void merge(int[][] arr, int left, int mid, int right, int[] result) {
List<int[]> temp = new ArrayList<>();
int i = left, j = mid + 1;
int rightCount = 0;
while (i <= mid && j <= right) {
if (arr[i][0] <= arr[j][0]) {
result[arr[i][1]] += rightCount;
temp.add(arr[i++]);
} else {
rightCount++;
temp.add(arr[j++]);
}
}
while (i <= mid) {
result[arr[i][1]] += rightCount;
temp.add(arr[i++]);
}
while (j <= right) {
temp.add(arr[j++]);
}
for (int k = left; k <= right; k++) {
arr[k] = temp.get(k - left);
}
}
}
Comments
Post a Comment