给定二进制数组arr [] ,任务是找到最多可通过反转子数组一次来生成的非递减子序列的最大长度。
例子:
Input: arr[] = {0, 1, 0, 1}
Output: 4
Explanation:
After reversing the subarray from index [2, 3], the array modifies to {0, 0, 1, 1}.
Hence, the longest non-decreasing subsequence is {0, 0, 1, 1}.
Input: arr[] = {0, 1, 1, 1, 0, 0, 1, 1, 0}
Output: 9
Explanation:
After reversing the subarray from index [2, 6], the array modifies to {0, 0, 0, 1, 1, 1, 1, 1, 0}.
Hence, the longest non-decreasing subsequence is {0, 0, 0, 1, 1, 1, 1, 1}.
天真的方法:解决问题的最简单方法是反转给定数组中的每个可能的子数组,并在反转子数组后从数组中找到最长的非递减子序列。
时间复杂度: O(N 3 )
辅助空间: O(N)
高效方法:想法是使用动态编程解决问题。请按照以下步骤操作:
- 由于数组是二进制数组,因此可以在格式{0….0} , {0…1…} , {0..1..0…},0..1的子序列中找到最长的子序列。 ..0..1 。
- 将动态编程表初始化为dp [] [] ,该表存储以下内容:
dp[i][0] : Stores the length of the longest subsequence (0..) from a[0 to i].
dp[i][1] : Stores the length of the longest subsequence (0..1..) from a[0 to i].
dp[i][2] : Stores the length of the longest subsequence (0..1..0..) from a[0 to i].
dp[i][3] : Stores the length of the longest subsequence (0..1..0..1..) from a[0 to i].
- 因此,答案是最长的子序列或所有4个给定可能性(dp [n-1] [0],d [n-1] [1],dp [n-1] [2],dp [ n-1] [3]) 。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
void main_fun(int arr[], int n)
{
// dp[i][j] be the longest
// subsequence of a[0...i]
// with first j parts
int dp[4][n];
memset(dp, 0, sizeof(dp[0][0] * 4 * n));
if (arr[0] == 0)
dp[0][0] = 1;
else
dp[1][0] = 1;
// Maximum length sub-sequence
// of (0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
dp[0][i] = dp[0][i - 1] + 1;
else
dp[0][i] = dp[0][i - 1];
}
// Maximum length sub-sequence
// of (0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
dp[1][i] = max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1);
else
dp[1][i] = dp[1][i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
{
dp[2][i] = max(dp[2][i - 1] + 1,
max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1));
}
else
dp[2][i] = dp[2][i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
{
dp[3][i] = max(dp[3][i - 1] + 1,
max(dp[2][i - 1] + 1,
max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1)));
}
else
dp[3][i] = dp[3][i - 1];
}
// Find the max length subsequence
int ans = max(dp[2][n - 1], max(dp[1][n - 1],
max(dp[0][n - 1], dp[3][n - 1])));
// Print the answer
cout << (ans);
}
// Driver Code
int main()
{
int n = 4;
int arr[] = {0, 1, 0, 1};
main_fun(arr, n);
return 0;
}
// This code is contributed by chitranayal
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int arr[], int n)
{
// dp[i][j] be the longest
// subsequence of a[0...i]
// with first j parts
int[][] dp = new int[4][n];
if (arr[0] == 0)
dp[0][0] = 1;
else
dp[1][0] = 1;
// Maximum length sub-sequence
// of (0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
dp[0][i] = dp[0][i - 1] + 1;
else
dp[0][i] = dp[0][i - 1];
}
// Maximum length sub-sequence
// of (0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
dp[1][i] = Math.max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1);
else
dp[1][i] = dp[1][i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
{
dp[2][i] = Math.max(dp[2][i - 1] + 1,
Math.max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1));
}
else
dp[2][i] = dp[2][i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
{
dp[3][i] = Math.max(dp[3][i - 1] + 1,
Math.max(dp[2][i - 1] + 1,
Math.max(dp[1][i - 1] + 1,
dp[0][i - 1] + 1)));
}
else
dp[3][i] = dp[3][i - 1];
}
// Find the max length subsequence
int ans = Math.max(dp[2][n - 1],
Math.max(dp[1][n - 1],
Math.max(dp[0][n - 1],
dp[3][n - 1])));
// Print the answer
System.out.print(ans);
}
// Driver code
public static void main (String[] args)
{
int n = 4;
int arr[] = { 0, 1, 0, 1 };
main_fun(arr, n);
}
}
// This code is contributed by offbeat
Python3
# Python3 program to implement
# the above approach
import sys
# Function to find the maximum length
# non decreasing subarray by reversing
# at most one subarray
def main(arr, n):
# dp[i][j] be the longest
# subsequence of a[0...i]
# with first j parts
dp = [[0 for x in range(n)] for y in range(4)]
if arr[0] == 0:
dp[0][0] = 1
else:
dp[1][0] = 1
# Maximum length sub-sequence
# of (0..)
for i in range(1, n):
if arr[i] == 0:
dp[0][i] = dp[0][i-1] + 1
else:
dp[0][i] = dp[0][i-1]
# Maximum length sub-sequence
# of (0..1..)
for i in range(1, n):
if arr[i] == 1:
dp[1][i] = max(dp[1][i-1] + 1, dp[0][i-1] + 1)
else:
dp[1][i] = dp[1][i-1]
# Maximum length sub-sequence
# of (0..1..0..)
for i in range(1, n):
if arr[i] == 0:
dp[2][i] = max([dp[2][i-1] + 1,
dp[1][i-1] + 1,
dp[0][i-1] + 1])
else:
dp[2][i] = dp[2][i-1]
# Maximum length sub-sequence
# of (0..1..0..1..)
for i in range(1, n):
if arr[i] == 1:
dp[3][i] = max([dp[3][i-1] + 1,
dp[2][i-1] + 1,
dp[1][i-1] + 1,
dp[0][i-1] + 1])
else:
dp[3][i] = dp[3][i-1]
# Find the max length subsequence
ans = max([dp[2][n-1], dp[1][n-1],
dp[0][n-1], dp[3][n-1]])
# Print the answer
print(ans)
# Driver Code
if __name__ == "__main__":
n = 4
arr = [0, 1, 0, 1]
main(arr, n)
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int []arr, int n)
{
// dp[i,j] be the longest
// subsequence of a[0...i]
// with first j parts
int[,] dp = new int[4, n];
if (arr[0] == 0)
dp[0, 0] = 1;
else
dp[1, 0] = 1;
// Maximum length sub-sequence
// of (0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
dp[0, i] = dp[0, i - 1] + 1;
else
dp[0, i] = dp[0, i - 1];
}
// Maximum length sub-sequence
// of (0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
dp[1, i] = Math.Max(dp[1, i - 1] + 1,
dp[0, i - 1] + 1);
else
dp[1, i] = dp[1, i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 0)
{
dp[2, i] = Math.Max(dp[2, i - 1] + 1,
Math.Max(dp[1, i - 1] + 1,
dp[0, i - 1] + 1));
}
else
dp[2, i] = dp[2, i - 1];
}
// Maximum length sub-sequence
// of (0..1..0..1..)
for(int i = 1; i < n; i++)
{
if (arr[i] == 1)
{
dp[3, i] = Math.Max(dp[3, i - 1] + 1,
Math.Max(dp[2, i - 1] + 1,
Math.Max(dp[1, i - 1] + 1,
dp[0, i - 1] + 1)));
}
else
dp[3, i] = dp[3, i - 1];
}
// Find the max length subsequence
int ans = Math.Max(dp[2, n - 1],
Math.Max(dp[1, n - 1],
Math.Max(dp[0, n - 1],
dp[3, n - 1])));
// Print the answer
Console.Write(ans);
}
// Driver code
public static void Main(String[] args)
{
int n = 4;
int []arr = { 0, 1, 0, 1 };
main_fun(arr, n);
}
}
// This code is contributed by Amit Katiyar
4
时间复杂度: O(N)
辅助空间: O(1)