给定一个由N 个整数组成的数组arr[] ,任务是找到需要移除的最小子数组的长度,以使剩余的数组元素连续。
例子:
Input: arr[] = {1, 2, 3, 7, 5, 4, 5}
Output: 2
Explanation:
Removing the subarray {7, 5} from the array arr[] modifies the array to {1, 2, 3, 4, 5}, which makes all array elements consecutive. Therefore, the length of the subarray removed is 2, which is minimum.
Input: arr[] = {4, 5, 6, 8, 9, 10}
Output: 3
朴素的方法:解决给定问题的最简单方法是删除生成数组arr[] 的所有可能子数组,并检查它们中的每一个,检查它们的删除是否使剩余的数组元素连续。检查所有子数组后,打印得到满足条件的最小子数组的长度。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效的方法:上述方法可以通过存储连续元素的最长前缀和后缀的长度,然后找到需要删除的子数组的最小长度来优化上述方法,使得前缀和后缀的串联形成连续元素的序列.
请按照以下步骤解决问题:
- 初始化两个变量,假设L为0 , R为(N – 1)分别存储连续元素最长前缀的结束索引和最长后缀的起始索引。
- 将L的值更新为第一个索引,其中arr[i] + 1不等于arr[i + 1] ,使得arr[0, …, L]是一个连续的前缀数组。
- 将R的值更新到从末尾开始的第一个索引,其中arr[i]不等于arr[i – 1] + 1 ,使得arr[R, …, N – 1]是一个连续的后缀数组。
- 初始化一个变量,比如ans,以存储(N – L – 1)和R的最小值 存储所需的结果。
- 如果arr[R] ≤ arr[L] + 1 的值,则存储右索引, R1为arr[0, …, L, R1, …, N – 1]是一个连续数组。
- 如果(R1 – L – 1)的值小于ANS的值,然后更新ANS至(R1 – L – 1)的值。
- 完成以上步骤后,打印ans的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of the
// smallest subarray to be removed to
// make remaining array elements consecutive
void shortestSubarray(int* A, int N)
{
int i;
// Store the ending index of the
// longest prefix consecutive array
int left_index;
// Traverse the array to find the
// longest prefix consecutive sequence
for (i = 0; i < N - 1; i++) {
if (A[i] + 1 != A[i + 1])
break;
}
// A[0...left_index] is the
// prefix consecutive sequence
left_index = i;
// Store the starting index of the
// longest suffix consecutive sequence
int right_index;
// Traverse the array to find the
// longest suffix consecutive sequence
for (i = N - 1; i >= 1; i--) {
if (A[i] != A[i - 1] + 1)
break;
}
// A[right_index...N-1] is
// the consecutive sequence
right_index = i;
int updated_right;
// Store the smallest subarray
// required to be removed
int minLength = min(N - left_index - 1,
right_index);
// Check if subarray from the
// middle can be removed
if (A[right_index]
<= A[left_index] + 1) {
// Update the right index s.t.
// A[0, N-1] is consecutive
updated_right = right_index
+ A[left_index]
- A[right_index] + 1;
// If updated_right < N, then
// update the minimumLength
if (updated_right < N)
minLength = min(minLength,
updated_right
- left_index - 1);
}
// Print the required result
cout << minLength;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 3, 7, 4, 3, 5 };
int N = sizeof(arr) / sizeof(arr[0]);
shortestSubarray(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to find the length of the
// smallest subarray to be removed to
// make remaining array elements consecutive
static void shortestSubarray(int A[], int N)
{
int i;
// Store the ending index of the
// longest prefix consecutive array
int left_index;
// Traverse the array to find the
// longest prefix consecutive sequence
for(i = 0; i < N - 1; i++)
{
if (A[i] + 1 != A[i + 1])
break;
}
// A[0...left_index] is the
// prefix consecutive sequence
left_index = i;
// Store the starting index of the
// longest suffix consecutive sequence
int right_index;
// Traverse the array to find the
// longest suffix consecutive sequence
for(i = N - 1; i >= 1; i--)
{
if (A[i] != A[i - 1] + 1)
break;
}
// A[right_index...N-1] is
// the consecutive sequence
right_index = i;
int updated_right;
// Store the smallest subarray
// required to be removed
int minLength = Math.min(N - left_index - 1,
right_index);
// Check if subarray from the
// middle can be removed
if (A[right_index] <= A[left_index] + 1)
{
// Update the right index s.t.
// A[0, N-1] is consecutive
updated_right = right_index + A[left_index] -
A[right_index] + 1;
// If updated_right < N, then
// update the minimumLength
if (updated_right < N)
minLength = Math.min(minLength,
updated_right -
left_index - 1);
}
// Print the required result
System.out.println(minLength);
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 7, 4, 3, 5 };
int N = arr.length;
shortestSubarray(arr, N);
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
# Function to find the length of the
# smallest subarray to be removed to
# make remaining array elements consecutive
def shortestSubarray(A, N):
i = 0
# Store the ending index of the
# longest prefix consecutive array
left_index = 0
# Traverse the array to find the
# longest prefix consecutive sequence
for i in range(N - 1):
if (A[i] + 1 != A[i + 1]):
break
# A[0...left_index] is the
# prefix consecutive sequence
left_index = i
# Store the starting index of the
# longest suffix consecutive sequence
right_index = 0
# Traverse the array to find the
# longest suffix consecutive sequence
i = N - 1
while (i >= 1):
if (A[i] != A[i - 1] + 1):
break
i -= 1
# A[right_index...N-1] is
# the consecutive sequence
right_index = i
updated_right = 0
# Store the smallest subarray
# required to be removed
minLength = min(N - left_index - 1, right_index)
# Check if subarray from the
# middle can be removed
if (A[right_index] <= A[left_index] + 1):
# Update the right index s.t.
# A[0, N-1] is consecutive
updated_right = (right_index + A[left_index] -
A[right_index] + 1)
# If updated_right < N, then
# update the minimumLength
if (updated_right < N):
minLength = min(minLength, updated_right -
left_index - 1)
# Print the required result
print(minLength)
# Driver Code
if __name__ == '__main__':
arr = [ 1, 2, 3, 7, 4, 3, 5 ]
N = len(arr)
shortestSubarray(arr, N)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the length of the
// smallest subarray to be removed to
// make remaining array elements consecutive
static void shortestSubarray(int[] A, int N)
{
int i;
// Store the ending index of the
// longest prefix consecutive array
int left_index;
// Traverse the array to find the
// longest prefix consecutive sequence
for(i = 0; i < N - 1; i++)
{
if (A[i] + 1 != A[i + 1])
break;
}
// A[0...left_index] is the
// prefix consecutive sequence
left_index = i;
// Store the starting index of the
// longest suffix consecutive sequence
int right_index;
// Traverse the array to find the
// longest suffix consecutive sequence
for(i = N - 1; i >= 1; i--)
{
if (A[i] != A[i - 1] + 1)
break;
}
// A[right_index...N-1] is
// the consecutive sequence
right_index = i;
int updated_right;
// Store the smallest subarray
// required to be removed
int minLength = Math.Min(N - left_index - 1,
right_index);
// Check if subarray from the
// middle can be removed
if (A[right_index] <= A[left_index] + 1)
{
// Update the right index s.t.
// A[0, N-1] is consecutive
updated_right = right_index + A[left_index] -
A[right_index] + 1;
// If updated_right < N, then
// update the minimumLength
if (updated_right < N)
minLength = Math.Min(minLength,
updated_right -
left_index - 1);
}
// Print the required result
Console.WriteLine(minLength);
}
// Driver code
static public void Main()
{
int[] arr = { 1, 2, 3, 7, 4, 3, 5 };
int N = arr.Length;
shortestSubarray(arr, N);
}
}
// This code is contributed by offbeat
Javascript
4
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。