给定一个由N 个整数组成的数组arr[] ,任务是计算每个数组元素右侧的较大元素的数量。
例子:
Input: arr[] = {3, 7, 1, 5, 9, 2}
Output: {3, 1, 3, 1, 0, 0}
Explanation:
For arr[0], the elements greater than it on the right are {7, 5, 9}.
For arr[1], the only element greater than it on the right is {9}.
For arr[2], the elements greater than it on the right are {5, 9, 2}.
For arr[3], the only element greater than it on the right is {9}.
For arr[4] and arr[5], no greater elements exist on the right.
Input: arr[] = {5, 4, 3, 2}
Output: {0, 0, 0, 0}
朴素的方法:最简单的方法是使用两个循环迭代所有数组元素,对于每个数组元素,在其右侧计算大于它的元素数,然后打印它。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:可以使用降序归并排序的概念来解决问题。请按照以下步骤解决问题:
- 初始化一个数组count[] ,其中count[i]存储每个arr[i]右侧更大元素的相应计数
- 获取索引i和j ,并比较数组中的元素。
- 如果较高索引元素大于较低索引元素,则所有较高索引元素将大于该较低索引之后的所有元素。
- 由于左侧部分已经排序,因此将较低索引元素之后的元素计数添加到较低索引的count[]数组中。
- 重复以上步骤,直到整个数组排序完毕。
- 最后打印count[]数组的值。
下面是上述方法的实现:
Java
// Java program for the above approach
import java.util.*;
public class GFG {
// Stores the index & value pairs
static class Item {
int val;
int index;
public Item(int val, int index)
{
this.val = val;
this.index = index;
}
}
// Function to count the number of
// greater elements on the right
// of every array element
public static ArrayList
countLarge(int[] a)
{
// Lemgth of the array
int len = a.length;
// Stores the index-value pairs
Item[] items = new Item[len];
for (int i = 0; i < len; i++) {
items[i] = new Item(a[i], i);
}
// Stores the count of greater
// elements on right
int[] count = new int[len];
// Perform MergeSort operation
mergeSort(items, 0, len - 1,
count);
ArrayList res
= new ArrayList<>();
for (int i : count) {
res.add(i);
}
return res;
}
// Function to sort the array
// using Merge Sort
public static void mergeSort(
Item[] items, int low int high,
int[] count)
{
// Base Case
if (low >= high) {
return;
}
// Find Mid
int mid = low + (high - low) / 2;
mergeSort(items, low, mid,
count);
mergeSort(items, mid + 1,
high, count);
// Merging step
merge(items, low, mid,
mid + 1, high, count);
}
// Utility function to merge sorted
// subarrays and find the count of
// greater elements on the right
public static void merge(
Item[] items, int low, int lowEnd,
int high, int highEnd, int[] count)
{
int m = highEnd - low + 1; // mid
Item[] sorted = new Item[m];
int rightCounter = 0;
int lowInd = low, highInd = high;
int index = 0;
// Loop to store the count of
// larger elements on right side
// when both array have elements
while (lowInd <= lowEnd
&& highInd <= highEnd) {
if (items[lowInd].val
< items[highInd].val) {
rightCounter++;
sorted[index++]
= items[highInd++];
}
else {
count[items[lowInd].index] += rightCounter;
sorted[index++] = items[lowInd++];
}
}
// Loop to store the count of
// larger elements in right side
// when only left array have
// some element
while (lowInd <= lowEnd) {
count[items[lowInd].index] += rightCounter;
sorted[index++] = items[lowInd++];
}
// Loop to store the count of
// larger elements in right side
// when only right array have
// some element
while (highInd <= highEnd) {
sorted[index++] = items[highInd++];
}
System.arraycopy(sorted, 0, items,
low, m);
}
// Utility function that prints
// the count of greater elements
// on the right
public static void
printArray(ArrayList countList)
{
for (Integer i : countList)
System.out.print(i + " ");
System.out.println();
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 3, 7, 1, 5, 9, 2 };
int n = arr.length;
// Function Call
ArrayList countList
= countLarge(arr);
printArray(countList);
}
}
3 1 3 1 0 0
时间复杂度: O(N*log N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live