Array 通过 0 转换可以形成的最长连续序列的长度
给定一个包含N个整数的数组arr ,任务是计算可以从数组中形成的最长连续整数序列的长度。还假设数组中的 0 可以转换为任何值。
例子:
Input: N = 7, A = {0, 6, 5, 10, 3, 0, 11}
Output: 5
Explanation: The maximum consecutive sequence formed can be {3, 4, 5, 6, 7}. As 4, 7 are not present in the array, we can change 2 zeroes to 4 and 7.
Input: N = 6, A = {0, 0, 1, 2, 6, 0}
Output: 6
Explanation: The maximum consecutive sequence formed can be {1, 2, 3, 4, 5, 6}
方法:给定的问题可以借助二分查找和前缀和数组来解决:
- 计算数组中的总零并将它们存储在变量计数中,该变量表示可以进行的总可能更改
- 删除给定数组中的重复值和零值,以便数组仅包含唯一的非零值
- 创建一个辅助数组并将这些索引值初始化为 1,其值存在于给定数组中
- 辅助数组变成前缀和数组
- 迭代前缀数组,并在每次迭代时执行二进制搜索,下限作为当前索引,上限作为数组的最后一个索引
- 设当前索引为l ,最右边的可能索引为r 。对于每个mid = (l + r) / 2 ,检查此范围 [ l , mid ] 是否可以通过总允许更改来实现
- 如果上述陈述为真,则更新l = mid +1否则r = mid – 1
- 计算所有起始值的最大长度
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to calculate maximum
// possible consecutive numbers
// with changes allowed
int maximumConsecutiveNumbers(int arr[], int N)
{
// Store all non-zero elements
// in a new vector and
// calculate total zero elements
vector v;
// Variable to store the
// count of zero elements
int count = 0;
for (int i = 0; i < N; i++) {
if (arr[i] == 0) {
count++;
}
else {
v.push_back(arr[i]);
}
}
// Sort the array
sort(v.begin(), v.end());
// Remove all the duplicates
// from the array
(v).erase(unique(v.begin(),
v.end()),
(v).end());
// Variable to store the maximum
// value of the sequence
int MAXN = 1100000;
// Make the prefix array
vector pref(MAXN + 1, 0);
for (int i = 0; i < v.size(); i++) {
pref[v[i]]++;
}
for (int i = 1; i <= MAXN; i++) {
pref[i] += pref[i - 1];
}
int mx = 0;
// Iterate for each element and
// use binary search
for (int i = 1; i <= MAXN; i++) {
int l = i, r = MAXN;
int local_max = 0;
while (l <= r) {
int mid = (l + r) / 2;
// Conversions equal to number
// of zeros, can be made upto mid
if (pref[mid] - pref[i - 1]
+ count
>= (mid - i + 1)) {
l = mid + 1;
local_max = max(local_max,
mid - i + 1);
}
else {
r = mid - 1;
}
}
mx = max(mx, local_max);
}
return mx;
}
// Driver Code
int main()
{
int N = 7;
int arr[] = { 0, 6, 5, 10, 3, 0, 11 };
cout << maximumConsecutiveNumbers(arr, N);
}
Python3
# Python 3 implementation for the above approach
# Function to calculate maximum
# possible consecutive numbers
# with changes allowed
def maximumConsecutiveNumbers(arr, N):
# Store all non-zero elements
# in a new vector and
# calculate total zero elements
v = []
# Variable to store the
# count of zero elements
count = 0
for i in range(N):
if(arr[i] == 0):
count += 1
else:
v.append(arr[i])
# Sort the array
v.sort()
# Remove all the duplicates
# from the array
v = set(v)
v = list(v)
# Variable to store the maximum
# value of the sequence
MAXN = 110000
# Make the prefix array
pref = [0 for i in range(MAXN+1)]
for i in range(len(v)):
pref[v[i]] += 1
for i in range(1,MAXN+1,1):
pref[i] += pref[i - 1]
mx = 0
# Iterate for each element and
# use binary search
for i in range(1,MAXN+1,1):
l = i
r = MAXN
local_max = 0
while (l <= r):
mid = (l + r) // 2
# Conversions equal to number
# of zeros, can be made upto mid
if (pref[mid] - pref[i - 1] + count >= (mid - i + 1)):
l = mid + 1
local_max = max(local_max,mid - i + 1)
else:
r = mid - 1
mx = max(mx, local_max)
return mx
# Driver Code
if __name__ == '__main__':
N = 7
arr = [0, 6, 5, 10, 3, 0, 11]
print(maximumConsecutiveNumbers(arr, N))
# This code is contributed by ipg2016107.
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
// Function to calculate maximum
// possible consecutive numbers
// with changes allowed
static int maximumConsecutiveNumbers(int[] arr, int N)
{
// Store all non-zero elements
// in a new vector and
// calculate total zero elements
List v = new List();
// Variable to store the
// count of zero elements
int count = 0;
for (int i = 0; i < N; i++) {
if (arr[i] == 0) {
count++;
}
else {
v.Add(arr[i]);
}
}
// Sort the array
v.Sort();
// Remove all the duplicates
// from the array
List distinct = v.Distinct().ToList();
// Variable to store the maximum
// value of the sequence
int MAXN = 1100000;
// Make the prefix array
List pref = new List(new int[MAXN + 1]);
for (int i = 0; i < distinct.Count; i++) {
pref[distinct[i]]++;
}
for (int i = 1; i <= MAXN; i++) {
pref[i] += pref[i - 1];
}
int mx = 0;
// Iterate for each element and
// use binary search
for (int i = 1; i <= MAXN; i++) {
int l = i, r = MAXN;
int local_max = 0;
while (l <= r) {
int mid = (l + r) / 2;
// Conversions equal to number
// of zeros, can be made upto mid
if (pref[mid] - pref[i - 1] + count
>= (mid - i + 1)) {
l = mid + 1;
local_max
= Math.Max(local_max, mid - i + 1);
}
else {
r = mid - 1;
}
}
mx = Math.Max(mx, local_max);
}
return mx;
}
// Driver Code
public static void Main()
{
int N = 7;
int[] arr = { 0, 6, 5, 10, 3, 0, 11 };
Console.Write(maximumConsecutiveNumbers(arr, N));
}
}
// This code is contributed by ukasp.
Javascript
输出
5
时间复杂度: O(N*log(K)),其中 K 是数组中的最大值
辅助空间: O(N)