从数组中恰好删除一个元素后最长递增连续子数组的最大长度
给定一个包含N个整数的数组arr[ ] 。任务是在从给定数组中删除一个元素后,找到最长递增的连续子数组的最大长度。
例子 :
Input : N = 5, arr[] = { 2, 4, 1, 5, 7 }
Output : 4
Explanation : After removing third element from the array, the array arr[ ] becomes [2, 4, 5, 7] . therefore, the length of longest increasing contiguous subarray is 4, which is maximum.
Input : N = 4, arr[] = { 2, 1, 3, 1 }
Output : 2
Explanation : We can either remove the second or first element from the array, and the array, arr[ ] becomes {1, 3, 1} or {2, 3, 1}, and the length of longest increasing contiguous subarray is 2, which is maximum.
方法:该任务可以通过跟踪从索引“i”开始到索引“i”结束的最长递增子序列来解决。
- 创建两个大小为N的数组front[ ]和back[ ]并用1初始化这两个数组。
- 计算从1到N的每个i的front[i]和back[i] ,其中front[i]表示从位置i开始的最长递增子序列的最大长度, back[i]表示最长递增子序列结束的最大长度在位置i。
- 数组front[ ]可以按照从左到右的顺序计算,条件如下: if(a[i] > a[i-1]) update front[i] = front[i-1] + 1, else continue .同理,数组back[ ]可以按从右到左的顺序计算,条件如下: if(a[i] < a[i+1]) update back[i] = back[i+1] + 1 , 否则继续
- 现在用这两个数组计算ans,初始化为 1。
- 更新ans if (a[i] < a[i+2]),表示(i+1) th 元素被删除,与back[]数组相同。
下面是上述方法的实现:
C++
// c++ program for the above approach
#include
using namespace std;
// Function to find the maximum length of longest
// increasing contiguous subarray after removing
// exactly one element from array
int maxLenSubarr(int arr[], int n)
{
// Creating front[] and back[] arrays
int front[n], back[n];
for (int i = 0; i < n; i++) {
front[i] = 1;
back[i] = 1;
}
// Calculating the front[]
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// Update front[i]
front[i] = front[i - 1] + 1;
}
}
// Calculating the back[]
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
// update back[i]
back[i] = back[i + 1] + 1;
}
}
// Store the length of longest increasing
// contiguous subarray
int ans = 1;
// Check whether first element is
// contributing in subarray or not
bool check_first = true;
// Keep track of longest subarray when
// first element is removed
int ans_first = 1;
for (int i = 1; i < n; i++) {
// front[i] == 1 means contribution of
// first element in max
// length subarray has ended
if (front[i] == 1) {
check_first = true;
}
ans_first = max(ans_first, front[i]);
}
// First element contributes in the subarray
if (check_first == false) {
ans_first -= 1;
}
// Check whether last element is
// contributing in subarray or not
bool check_last = true;
// Keep track of longest subarray when
// last element is removed
int ans_last = 1;
for (int i = n - 2; i >= 0; i--) {
// back[i] == 1 means contribution of
// last element in max
// length subarray has ended
if (back[i] == 1) {
check_last = true;
}
ans_last = max(ans_last, back[i]);
}
// Last element contributes in the subarray
if (check_last == false) {
ans_last -= 1;
}
// Update ans
ans = max(ans_first, ans_last);
// Calculating max length when
// (i+1)th element is deleted
for (int i = 0; i < n - 2; i++) {
if (arr[i] < arr[i + 2]) {
ans = max(ans,
front[i] + back[i + 2]);
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 2, 1, 3, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxLenSubarr(arr, n);
return 0;
}
Java
// Java program for the above approach
public class GFG {
// Function to find the maximum length of longest
// increasing contiguous subarray after removing
// exactly one element from array
static int maxLenSubarr(int arr[], int n)
{
// Creating front[] and back[] arrays
int front[] = new int[n];
int back[] = new int[n];
for (int i = 0; i < n; i++) {
front[i] = 1;
back[i] = 1;
}
// Calculating the front[]
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// Update front[i]
front[i] = front[i - 1] + 1;
}
}
// Calculating the back[]
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
// update back[i]
back[i] = back[i + 1] + 1;
}
}
// Store the length of longest increasing
// contiguous subarray
int ans = 1;
// Check whether first element is
// contributing in subarray or not
boolean check_first = true;
// Keep track of longest subarray when
// first element is removed
int ans_first = 1;
for (int i = 1; i < n; i++) {
// front[i] == 1 means contribution of
// first element in max
// length subarray has ended
if (front[i] == 1) {
check_first = true;
}
ans_first = Math.max(ans_first, front[i]);
}
// First element contributes in the subarray
if (check_first == false) {
ans_first -= 1;
}
// Check whether last element is
// contributing in subarray or not
boolean check_last = true;
// Keep track of longest subarray when
// last element is removed
int ans_last = 1;
for (int i = n - 2; i >= 0; i--) {
// back[i] == 1 means contribution of
// last element in max
// length subarray has ended
if (back[i] == 1) {
check_last = true;
}
ans_last = Math.max(ans_last, back[i]);
}
// Last element contributes in the subarray
if (check_last == false) {
ans_last -= 1;
}
// Update ans
ans = Math.max(ans_first, ans_last);
// Calculating max length when
// (i+1)th element is deleted
for (int i = 0; i < n - 2; i++) {
if (arr[i] < arr[i + 2]) {
ans = Math.max(ans,
front[i] + back[i + 2]);
}
}
return ans;
}
// Driver code
public static void main (String[] args) {
int arr[] = { 2, 1, 3, 1 };
int n = arr.length;
System.out.println(maxLenSubarr(arr, n));
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to find the maximum length of longest
# increasing contiguous subarray after removing
# exactly one element from array
def maxLenSubarr(arr, n) :
# Creating front[] and back[] arrays
front = [0] * n; back = [0] * n;
for i in range(n) :
front[i] = 1;
back[i] = 1;
# Calculating the front[]
for i in range(1, n) :
if (arr[i] > arr[i - 1]) :
# Update front[i]
front[i] = front[i - 1] + 1;
# Calculating the back[]
for i in range(n - 2, -1, -1) :
if (arr[i] < arr[i + 1]) :
# update back[i]
back[i] = back[i + 1] + 1;
# Store the length of longest increasing
# contiguous subarray
ans = 1;
# Check whether first element is
# contributing in subarray or not
check_first = True;
# Keep track of longest subarray when
# first element is removed
ans_first = 1;
for i in range(1, n) :
# front[i] == 1 means contribution of
# first element in max
# length subarray has ended
if (front[i] == 1) :
check_first = True;
ans_first = max(ans_first, front[i]);
# First element contributes in the subarray
if (check_first == False) :
ans_first -= 1;
# Check whether last element is
# contributing in subarray or not
check_last = True;
# Keep track of longest subarray when
# last element is removed
ans_last = 1;
for i in range(n - 2, -1, -1) :
# back[i] == 1 means contribution of
# last element in max
# length subarray has ended
if (back[i] == 1) :
check_last = True;
ans_last = max(ans_last, back[i]);
# Last element contributes in the subarray
if (check_last == False) :
ans_last -= 1;
# Update ans
ans = max(ans_first, ans_last);
# Calculating max length when
# (i+1)th element is deleted
for i in range( n - 2) :
if (arr[i] < arr[i + 2]) :
ans = max(ans, front[i] + back[i + 2]);
return ans;
# Driver code
if __name__ == "__main__" :
arr = [ 2, 1, 3, 1 ];
n = len(arr);
print(maxLenSubarr(arr, n));
# This code is contributed by AnkThon
C#
// C# program for the above approach
using System;
public class GFG {
// Function to find the maximum length of longest
// increasing contiguous subarray after removing
// exactly one element from array
static int maxLenSubarr(int []arr, int n)
{
// Creating front[] and back[] arrays
int []front = new int[n];
int []back = new int[n];
for (int i = 0; i < n; i++) {
front[i] = 1;
back[i] = 1;
}
// Calculating the front[]
for (int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
// Update front[i]
front[i] = front[i - 1] + 1;
}
}
// Calculating the back[]
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
// update back[i]
back[i] = back[i + 1] + 1;
}
}
// Store the length of longest increasing
// contiguous subarray
int ans = 1;
// Check whether first element is
// contributing in subarray or not
bool check_first = true;
// Keep track of longest subarray when
// first element is removed
int ans_first = 1;
for (int i = 1; i < n; i++) {
// front[i] == 1 means contribution of
// first element in max
// length subarray has ended
if (front[i] == 1) {
check_first = true;
}
ans_first = Math.Max(ans_first, front[i]);
}
// First element contributes in the subarray
if (check_first == false) {
ans_first -= 1;
}
// Check whether last element is
// contributing in subarray or not
bool check_last = true;
// Keep track of longest subarray when
// last element is removed
int ans_last = 1;
for (int i = n - 2; i >= 0; i--) {
// back[i] == 1 means contribution of
// last element in max
// length subarray has ended
if (back[i] == 1) {
check_last = true;
}
ans_last = Math.Max(ans_last, back[i]);
}
// Last element contributes in the subarray
if (check_last == false) {
ans_last -= 1;
}
// Update ans
ans = Math.Max(ans_first, ans_last);
// Calculating max length when
// (i+1)th element is deleted
for (int i = 0; i < n - 2; i++) {
if (arr[i] < arr[i + 2]) {
ans = Math.Max(ans,
front[i] + back[i + 2]);
}
}
return ans;
}
// Driver code
public static void Main(string[] args) {
int []arr = { 2, 1, 3, 1 };
int n = arr.Length;
Console.WriteLine(maxLenSubarr(arr, n));
}
}
// This code is contributed by AnkThon
Javascript
2
时间复杂度: O(N)
辅助空间: O(N)