给定由N个正整数组成的数组arr [] ,任务是使数组元素的总和最大化,以使数组的第一个元素为1,并且在执行完运算后,该数组的相邻元素之间的差最大为1。以下操作:
- 以任何方式重新排列数组元素。
- 将任何元素减少到至少为1的任何数字。
例子:
Input: arr[] = {3, 5, 1}
Output: 6
Explanation:
One possible arrangement is {1, 2, 3} having maximum possible sum 6.
Input: arr[] = {1, 2, 2, 2, 3, 4, 5}
Output: 19
Explanation:
One possible arrangement is {1, 2, 2, 2, 3, 4, 5} having maximum possible sum 19.
天真的方法:最简单的方法是对给定的数组进行排序,然后遍历已排序的数组,并减少不满足给定条件的元素。
时间复杂度: O(N * log N),其中N是给定数组的大小。
辅助空间: O(N)
高效的方法:想法是使用散列概念来存储给定数组的元素的频率。请按照以下步骤解决问题:
- 创建大小为(N + 1)的辅助数组count []来存储arr [i]的频率。
- 在将频率存储在count []中时,如果arr [i]大于N,则增加count [N] 。
- 将size和ans初始化为0 ,分别存储先前选择的整数和最大可能和。
- 使用变量K遍历给定的array count []数组,然后执行以下操作:
- 对每个K循环进行一次迭代,直到count [K]> 0和size
。 - 在while循环内,将大小增加1 ,然后将大小增加ans ,并将count [K]减少1 。
- while循环结束后,用K * count [K]递增ans 。
- 对每个K循环进行一次迭代,直到count [K]> 0和size
- 完成上述步骤后,将ans的值打印为最大可能的总和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find maximum possible
// sum after changing the array elements
// as per the given constraints
long maxSum(int a[], int n)
{
// Stores the frequency of
// elements in given array
int count[n + 1] = {0};
// Update frequncy
for(int i = 0; i < n; i++)
count[min(a[i], n)]++;
// Stores the previously
// selected integer
int size = 0;
// Stores the maximum possible sum
long ans = 0;
// Traverse over array count[]
for(int k = 1; k <= n; k++)
{
// Run loop for each k
while (count[k] > 0 && size < k)
{
size++;
ans += size;
count[k]--;
}
// Update ans
ans += k * count[k];
}
// Return maximum possible sum
return ans;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = { 3, 5, 1 };
// Size of array
int n = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << (maxSum(arr, n));
return 0;
}
// This code is contributed by akhilsaini
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to find maximum possible
// sum after changing the array elements
// as per the given constraints
static long maxSum(int[] a)
{
// Length of given array
int n = a.length;
// Stores the frequency of
// elements in given array
int[] count = new int[n + 1];
// Update frequncy
for (int x : a)
count[Math.min(x, n)]++;
// stores the previously
// selected integer
int size = 0;
// Stores the maximum possible sum
long ans = 0;
// Traverse over array count[]
for (int k = 1; k <= n; k++) {
// Run loop for each k
while (count[k] > 0 && size < k) {
size++;
ans += size;
count[k]--;
}
// Update ans
ans += k * count[k];
}
// Return maximum possible sum
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int[] arr = { 3, 5, 1 };
// Function Call
System.out.println(maxSum(arr));
}
}
Python3
# Python3 program for the above approach
# Function to find maximum possible
# sum after changing the array elements
# as per the given constraints
def maxSum(a, n):
# Stores the frequency of
# elements in given array
count = [0] * (n + 1)
# Update frequncy
for i in range(0, n):
count[min(a[i], n)] += 1
# stores the previously
# selected integer
size = 0
# Stores the maximum possible sum
ans = 0
# Traverse over array count[]
for k in range(1, n + 1):
# Run loop for each k
while (count[k] > 0 and size < k):
size += 1
ans += size
count[k] -= 1
# Update ans
ans += k * count[k]
# Return maximum possible sum
return ans
# Driver Code
if __name__ == '__main__':
# Given array arr[]
arr = [ 3, 5, 1 ]
# Size of array
n = len(arr)
# Function Call
print(maxSum(arr, n))
# This code is contributed by akhilsaini
C#
// C# program for the above approach
using System;
class GFG{
// Function to find maximum possible
// sum after changing the array elements
// as per the given constraints
static long maxSum(int[] a)
{
// Length of given array
int n = a.Length;
// Stores the frequency of
// elements in given array
int[] count = new int[n + 1];
// Update frequncy
for(int i = 0; i < n; i++)
count[Math.Min(a[i], n)]++;
// stores the previously
// selected integer
int size = 0;
// Stores the maximum possible sum
long ans = 0;
// Traverse over array count[]
for(int k = 1; k <= n; k++)
{
// Run loop for each k
while (count[k] > 0 && size < k)
{
size++;
ans += size;
count[k]--;
}
// Update ans
ans += k * count[k];
}
// Return maximum possible sum
return ans;
}
// Driver Code
public static void Main()
{
// Given array arr[]
int[] arr = { 3, 5, 1 };
// Function call
Console.Write(maxSum(arr));
}
}
// This code is contributed by akhilsaini
输出:
6
时间复杂度: O(N),其中N是给定数组的大小。
辅助空间: O(N)