给定的尺寸为N []在阵列ARR阵列ARR和每个元素[]是在范围[1,N]和该阵列可以包含重复。任务是找到可以获取的唯一值的最大数量,使得任何索引 i 处的值可以是:
- 增加1。
- 减少了 1。
- 保持原样。
注意:该操作只能对每个索引执行一次,并且必须对数组 arr[] 中的所有索引执行一次。
例子:
Input: arr[] = {1, 2, 4, 4}
Output: 4
Explanation:
One way is to perform the following operations for the index:
1: Leave the value at the first index(1) as it is.
2: Leave the value at the second index(2) as it is.
3: Leave the value at the third index(4) as it is.
4: Increment the value at the fourth index(4) by 1.
Then the array becomes {1, 2, 4, 5} and there are 4 unique values.
Input: arr[]={3, 3, 3, 3}
Output: 3
Explanation:
One way is to perform the following operations for the index:
1: Leave the value at the first index(3) as it is.
2: Decrement the value at the second index(3) by 1.
3: Leave the value at the third index(3) as it is.
4: Increment the value at the fourth index(3) by 1.
Then the array becomes {3, 2, 3, 4} and there are 3 unique values.
方法:
- 对于存在于索引i处的数组中的任意元素X ,我们通过考虑以下因素来决定对其执行什么操作:
- 如果数组中不存在值 ( X – 1 ) 并且数组中不同索引处存在一个或多个其他 X,我们将值X减1。
- 如果值X在数组中仅出现一次,我们不会更改值X。
- 我们递增1的值X,如果值(X + 1)不存在于阵列中的和存在于不同的索引的阵列中的一个或多个其它的X的存在。
- 通过对每个元素进行上述决定,我们可以确保我们得到的唯一元素的最终计数是最大值。
- 但是,要对每个索引执行上述步骤并计算元素 X 的出现次数并不断更新数组 arr[],所花费的时间将是二次方的,这对于大型数组是不可行的。
- 降低时间复杂度的一种替代方法是对数组进行初始排序。通过排序,数组中的所有元素被分组并且所有重复的值聚集在一起。
- 对数组进行排序后,由于数字的范围已经给定并且是固定的,因此可以使用哈希映射,其中哈希的键是范围[1, N] 中的数字,每个键的值为布尔值用于确定键是否存在于数组中。
- 在这个问题中,由于索引本身就是散列的键,所以使用大小为 ( N + 2 ) 的数组freq[]来实现散列。
下面是上述方法的实现:
C++
// C++ program to find the maximum number of
// unique values in the array
#include
using namespace std;
// Function to find the maximum number of
// unique values in the array
int uniqueNumbers(int arr[], int n)
{
// Sorting the given array
sort(arr, arr + n);
// This array will store the frequency
// of each number in the array
// after performing the given operation
int freq[n + 2];
// Initialising the array with all zeroes
memset(freq, 0, sizeof(freq));
// Loop to apply operation on
// each element of the array
for (int x = 0; x < n; x++) {
// Incrementing the value at index x
// if the value arr[x] - 1 is
// not present in the array
if (freq[arr[x] - 1] == 0) {
freq[arr[x] - 1]++;
}
// If arr[x] itself is not present, then it
// is left as it is
else if (freq[arr[x]] == 0) {
freq[arr[x]]++;
}
// If both arr[x] - 1 and arr[x] are present
// then the value is incremented by 1
else {
freq[arr[x] + 1]++;
}
}
// Variable to store the number of unique values
int unique = 0;
// Finding the unique values
for (int x = 0; x <= n + 1; x++) {
if (freq[x]) {
unique++;
}
}
// Returning the number of unique values
return unique;
}
// Driver Code
int main()
{
int arr[] = { 3, 3, 3, 3 };
// Size of the array
int n = 4;
int ans = uniqueNumbers(arr, n);
cout << ans;
return 0;
}
Java
// Java program to find the maximum number of
// unique values in the array
import java.util.*;
class GFG {
// Function to find the maximum number of
// unique values in the array
static int uniqueNumbers(int arr[], int n)
{
// Sorting the given array
Arrays.sort(arr);
// This array will store the frequency
// of each number in the array
// after performing the given operation
int freq[] = new int[n + 2];
// Initialising the array with all zeroes
for(int i = 0; i < n + 2; i++)
freq[i] = 0;
// Loop to apply operation on
// each element of the array
for (int x = 0; x < n; x++) {
// Incrementing the value at index x
// if the value arr[x] - 1 is
// not present in the array
if (freq[arr[x] - 1] == 0) {
freq[arr[x] - 1]++;
}
// If arr[x] itself is not present, then it
// is left as it is
else if (freq[arr[x]] == 0) {
freq[arr[x]]++;
}
// If both arr[x] - 1 and arr[x] are present
// then the value is incremented by 1
else {
freq[arr[x] + 1]++;
}
}
// Variable to store the number of unique values
int unique = 0;
// Finding the unique values
for (int x = 0; x <= n + 1; x++) {
if (freq[x] != 0) {
unique++;
}
}
// Returning the number of unique values
return unique;
}
// Driver Code
public static void main (String[] args)
{
int []arr = { 3, 3, 3, 3 };
// Size of the array
int n = 4;
int ans = uniqueNumbers(arr, n);
System.out.println(ans);
}
}
// This code is contributed by Yash_R
Python3
# Python program to find the maximum number of
# unique values in the array
# Function to find the maximum number of
# unique values in the array
def uniqueNumbers(arr, n):
# Sorting the given array
arr.sort()
# This array will store the frequency
# of each number in the array
# after performing the given operation
freq =[0]*(n + 2)
# Loop to apply the operation on
# each element of the array
for val in arr:
# Incrementing the value at index x
# if the value arr[x] - 1 is
# not present in the array
if(freq[val-1]== 0):
freq[val-1]+= 1
# If arr[x] itself is not present, then it
# is left as it is
elif(freq[val]== 0):
freq[val]+= 1
# If both arr[x] - 1 and arr[x] are present
# then the value is incremented by 1
else:
freq[val + 1]+= 1
# Variable to store the
# number of unique values
unique = 0
# Finding the number of unique values
for val in freq:
if(val>0):
unique+= 1
return unique
# Driver code
if __name__ == "__main__":
arr =[3, 3, 3, 3]
n = 4
print(uniqueNumbers(arr, n))
C#
// C# program to find the maximum number of
// unique values in the array
using System;
class GFG {
// Function to find the maximum number of
// unique values in the array
static int uniqueNumbers(int []arr, int n)
{
// Sorting the given array
Array.Sort(arr);
// This array will store the frequency
// of each number in the array
// after performing the given operation
int []freq = new int[n + 2];
// Initialising the array with all zeroes
for(int i = 0; i < n + 2; i++)
freq[i] = 0;
// Loop to apply operation on
// each element of the array
for (int x = 0; x < n; x++) {
// Incrementing the value at index x
// if the value arr[x] - 1 is
// not present in the array
if (freq[arr[x] - 1] == 0) {
freq[arr[x] - 1]++;
}
// If arr[x] itself is not present, then it
// is left as it is
else if (freq[arr[x]] == 0) {
freq[arr[x]]++;
}
// If both arr[x] - 1 and arr[x] are present
// then the value is incremented by 1
else {
freq[arr[x] + 1]++;
}
}
// Variable to store the number of unique values
int unique = 0;
// Finding the unique values
for (int x = 0; x <= n + 1; x++) {
if (freq[x] != 0) {
unique++;
}
}
// Returning the number of unique values
return unique;
}
// Driver Code
public static void Main (string[] args)
{
int []arr = { 3, 3, 3, 3 };
// Size of the array
int n = 4;
int ans = uniqueNumbers(arr, n);
Console.WriteLine(ans);
}
}
// This code is contributed by Yash_R
Javascript
3
时间复杂度分析:
- 对给定数组进行排序所花费的时间为O(N * log(N)) ,其中 N 是数组的大小。
- 在已排序数组上运行循环以执行操作所需的时间为O(N) 。
- 在散列上运行循环以计算唯一值所需的时间为O(N) 。
- 因此,总时间复杂度为O(N * log(N)) + O(N) + O(N) 。由于 N * log(N) 更大,上述方法的最终时间复杂度为O(N * log(N)) 。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live