给定一个由N 个元素组成的数组arr[] ,任务是找到从数组中删除所有元素所需的最小回文子数组删除。
例子:
Input: arr[] = {1, 3, 4, 1, 5}, N = 5
Output: 3
Explanation:
Removal of 4 from the array leaves {1, 3, 1, 5}.
Removal of {1, 3, 1} leaves {5}.
Removal of 5 makes the array empty.
Input: arr[] = {1, 2, 3, 5, 3, 1}, N = 5
Output: 2
Explanation:
Removal of {3, 5, 3} leaves {1, 2, 1}.
Removal of {1, 2, 1} makes the array empty.
方法:
我们可以使用区间动态规划来解决这个问题。请按照以下步骤解决问题:
- 初始化dp[][]使得每个 dp[i][j] 代表从第i个位置到第j个位置所需的最小移除次数。
- 对于i到j的区间,答案可能是i到k和k + 1到j两个区间的和,即:
dp [i][j]= minimum (dp [i][j], dp [i][k] + dp [k + 1][j]) where i ≤ k
- 除了这种可能性,我们还需要检查arr[i] = arr[j] ,然后dp[i][j] = dp[i + 1][j – 1] 。
下面是上述方法的实现:
C++
// C++ Program for the above approach
#include
using namespace std;
int dp[550][550];
int minSubarrayRemoval(vector& arr)
{
int i, j, k, l;
int n = arr.size();
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
dp[i][j] = n;
}
}
for (i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (i = 0; i < n - 1; i++) {
if (arr[i] == arr[i + 1]) {
dp[i][i + 1] = 1;
}
else {
dp[i][i + 1] = 2;
}
}
for (l = 2; l < n; l++) {
for (i = 0; i + l < n; i++) {
j = i + l;
if (arr[i] == arr[j]) {
dp[i][j] = dp[i + 1][j - 1];
}
for (k = i; k < j; k++) {
dp[i][j]
= min(
dp[i][j],
dp[i][k]
+ dp[k + 1][j]);
}
}
}
return dp[0][n - 1];
}
// Driver Program
int main()
{
vector arr
= { 2, 3, 1, 2, 2, 1, 2 };
int ans = minSubarrayRemoval(arr);
cout << ans << endl;
}
Java
// Java program for the above approach
class GFG{
static int dp[][] = new int[550][550];
static int minSubarrayRemoval(int arr[])
{
int i, j, k, l;
int n = arr.length;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
dp[i][j] = n;
}
}
for(i = 0; i < n; i++)
{
dp[i][i] = 1;
}
for(i = 0; i < n - 1; i++)
{
if (arr[i] == arr[i + 1])
{
dp[i][i + 1] = 1;
}
else
{
dp[i][i + 1] = 2;
}
}
for(l = 2; l < n; l++)
{
for(i = 0; i + l < n; i++)
{
j = i + l;
if (arr[i] == arr[j])
{
dp[i][j] = dp[i + 1][j - 1];
}
for(k = i; k < j; k++)
{
dp[i][j] = Math.min(dp[i][j],
dp[i][k] +
dp[k + 1][j]);
}
}
}
return dp[0][n - 1];
}
// Driver code
public static void main (String[] args)
{
int arr [] = new int[]{ 2, 3, 1, 2, 2, 1, 2 };
int ans = minSubarrayRemoval(arr);
System.out.println(ans);
}
}
// This code is contributed by Pratima Pandey
Python3
# Python3 program for the above approach
def minSubarrayRemoval(arr):
n = len(arr)
dp = []
for i in range(n):
l = [0] * n
for j in range(n):
l[j] = n
dp.append(l)
for i in range(n):
dp[i][i] = 1
for i in range(n - 1):
if (arr[i] == arr[i + 1]):
dp[i][i + 1] = 1
else:
dp[i][i + 1] = 2
for l in range(2, n):
for i in range(n - l):
j = i + l
if (arr[i] == arr[j]):
dp[i][j] = dp[i + 1][j - 1]
for k in range(i, j):
dp[i][j] = min(dp[i][j],
dp[i][k] +
dp[k + 1][j])
return dp[0][n - 1]
# Driver code
arr = [ 2, 3, 1, 2, 2, 1, 2 ]
ans = minSubarrayRemoval(arr)
print(ans)
# This code is contributed by shubhamsingh10
C#
// C# program for the above approach
using System;
class GFG{
static int [,]dp = new int[550, 550];
static int minSubarrayRemoval(int []arr)
{
int i, j, k, l;
int n = arr.Length;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
dp[i, j] = n;
}
}
for(i = 0; i < n; i++)
{
dp[i, i] = 1;
}
for(i = 0; i < n - 1; i++)
{
if (arr[i] == arr[i + 1])
{
dp[i, i + 1] = 1;
}
else
{
dp[i, i + 1] = 2;
}
}
for(l = 2; l < n; l++)
{
for(i = 0; i + l < n; i++)
{
j = i + l;
if (arr[i] == arr[j])
{
dp[i, j] = dp[i + 1, j - 1];
}
for(k = i; k < j; k++)
{
dp[i, j] = Math.Min(dp[i, j],
dp[i, k] +
dp[k + 1, j]);
}
}
}
return dp[0, n - 1];
}
// Driver code
public static void Main()
{
int []arr = new int[]{ 2, 3, 1, 2, 2, 1, 2 };
int ans = minSubarrayRemoval(arr);
Console.Write(ans);
}
}
// This code is contributed by Code_Mech
Javascript
输出:
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。