LeetCode 1246. 刪除迴文子數組(區間DP)

文章目錄

1. 題目

給你一個整數數組 arr,每一次操作你都可以選擇並刪除它的一個 迴文 子數組 arr[i], arr[i+1], ..., arr[j]( i <= j)

注意,每當你刪除掉一個子數組,右側元素都會自行向前移動填補空位。

請你計算並返回從數組中刪除所有數字所需的最少操作次數。

示例 1:
輸入:arr = [1,2]
輸出:2

示例 2:
輸入:arr = [1,3,4,1,5]
輸出:3
解釋:先刪除 [4],然後刪除 [1,3,1],最後再刪除 [5]。
 
提示:
1 <= arr.length <= 100
1 <= arr[i] <= 20

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/palindrome-removal
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

2. 解題

  • dp[i][j] 表示區間 [i,j] 的最少移除次數
  • 如果已知 dp[i][j],推導dp[i-1][j+1]
  • 如果兩側相等 arr[i-1] == arr[j+1]dp[i-1][j+1] = min(dp[i-1][j+1], dp[i][j])
  • 對區間而言,把區間分成任意的兩份,求和取最小
    對所有可能的 k,dp[i-1][j+1] = min(dp[i-1][j+1], dp[i-1][k]+dp[k+1][j+1])
class Solution {
public:
    int minimumMoves(vector<int>& arr) {
        int n = arr.size(), i, j,k, len;
        vector<vector<int>> dp(n, vector<int>(n,INT_MAX));
        for(i = 0; i < n; ++i)
        {
        	dp[i][i] = 1;//初始化
        	if(i < n-1 && arr[i]==arr[i+1])
        		dp[i][i+1] = 1;
        	else if(i < n-1 && arr[i]!=arr[i+1])
        		dp[i][i+1] = 2;
        }
        for(len = 0; len < n; ++len)
        {	//按長度遍歷
        	for(i = 0; i < n; ++i)
        	{
        		j = i+len;//右端點
        		if(j >= n || dp[i][j]==INT_MAX) continue;
        		if(i-1 >=0 && j+1 < n)
        		{
                    for(k = i-1; k <= j; ++k)
                        dp[i-1][j+1] = min(dp[i-1][j+1], dp[i-1][k]+dp[k+1][j+1]);
        			if(arr[i-1] == arr[j+1])
        				dp[i-1][j+1] = min(dp[i-1][j+1], dp[i][j]);
        		}      
        	}
        }
        return dp[0][n-1];
    }
};

440 ms 12.9 MB


我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公衆號(Michael阿明),一起加油、一起學習進步!
Michael阿明

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章