在C ++上删除回文
假设我们有一个称为arr的整数数组,现在,我们可以从索引i到j的回文子数组中选择i<=j,然后从给定数组中删除该子数组。我们必须记住,删除子数组后,该子数组左右两侧的元素将移动以填充删除项所留下的空白。我们必须找到从数组中删除所有数字所需的最小移动数。
因此,如果输入像arr=[1,3,4,1,5],那么输出将为3,因为我们可以按此顺序删除,先删除[4],然后再删除[1,3,1],然后删除[5]。
为了解决这个问题,我们将遵循以下步骤-
n:=arr的大小
定义一个大小为(n+1)x(n+1)的2D数组dp
对于初始化l:=1,当l<=n时,更新(将l增加1),-
如果l与1相同,则-
除此以外
dp[i,j]:=1
如果arr[i]与arr[k]相同,则-
dp[i,j]:=dp[i,j]和dp[i+1,k-1]+dp[k+1,j]的最小值
dp[i,j]:=dp[i,j]和1+dp[i+2,j]的最小值
dp[i,j]:=1+dp[i+1,j]
如果i+1<n并且arr[i]与arr[i+1]相同,则-
对于初始化k:=i+2,当k<=j时,更新(将k增加1),-
对于初始化i:=0,j:=l-1,当j<n时,更新(i增加1),(j增加1),-
返回dp[0,n-1]
让我们看下面的实现以更好地理解-
示例
#include <bits/stdc++.h> using namespace std; class Solution { public: int minimumMoves(vector<int>& arr) { int n = arr.size(); vector<vector<int> > dp(n + 1, vector<int>(n + 1)); for (int l = 1; l <= n; l++) { for (int i = 0, j = l - 1; j < n; i++, j++) { if (l == 1) { dp[i][j] = 1; } else { dp[i][j] = 1 + dp[i + 1][j]; if (i + 1 < n && arr[i] == arr[i + 1]) dp[i][j] = min(dp[i][j], 1 + dp[i + 2][j]); for (int k = i + 2; k <= j; k++) { if (arr[i] == arr[k]) { dp[i][j] = min(dp[i][j], dp[i + 1][k - 1] + dp[k + 1][j]); } } } } } return dp[0][n - 1]; } }; main(){ Solution ob; vector<int> v = {1,2}; cout << (ob.minimumMoves(v)); }
输入值
[1,2]
输出结果
2