zoukankan      html  css  js  c++  java
  • 【leetcode】1312. Minimum Insertion Steps to Make a String Palindrome

    题目如下:

    Given a string s. In one step you can insert any character at any index of the string.

    Return the minimum number of steps to make s palindrome.

    A Palindrome String is one that reads the same backward as well as forward.

    Example 1:

    Input: s = "zzazz"
    Output: 0
    Explanation: The string "zzazz" is already palindrome we don't need any insertions.
    

    Example 2:

    Input: s = "mbadm"
    Output: 2
    Explanation: String can be "mbdadbm" or "mdbabdm".
    

    Example 3:

    Input: s = "leetcode"
    Output: 5
    Explanation: Inserting 5 characters the string becomes "leetcodocteel".
    

    Example 4:

    Input: s = "g"
    Output: 0
    

    Example 5:

    Input: s = "no"
    Output: 1 

    Constraints:

    • 1 <= s.length <= 500
    • All characters of s are lower case English letters.

    解题思路:动态规划。假设dp[i][i+j]为使得子串s[i:i+j]变成回文需要插入的最大字符数,那么有以下几种情况建立状态转移方程:

    1,如果s[i] == s[i+j],求下面三种情况的最小值

         a. s[i] 和 s[i+j] 配对,表示不需要额外插入字符,那么 dp[i][j] = dp[i+1][i+j-1]

         b. 在s[i+j]后面新插入一个字符和 s[i]配对, 那么 dp[i][j] = dp[i+1][i+j] + 1 

         c.在s[i]前面插入一个字符和 s[i+j]配对,那么 dp[i][j] = dp[i][i+j-1] + 1

    2,如果s[i] != s[i+j],求下面三种情况的最小值  

         a. 在s[i+j]后面新插入一个字符和 s[i]配对, 那么 dp[i][j] = dp[i+1][i+j] + 1 

         b. 在s[i]前面插入一个字符和 s[i+j]配对,那么 dp[i][j] = dp[i][i+j-1] + 1

         c. 在s[i+j]后面新插入一个字符和 s[i]配对,并且 在s[i]前面插入一个字符和 s[i+j]配对,那么 dp[i][j] = dp[i+1][i+j-1] + 2

    最后dp[0][-1] 的值即为结果。

    代码如下:

    class Solution(object):
        def minInsertions(self, s):
            """
            :type s: str
            :rtype: int
            """
            dp = [[0] * len(s) for _ in s]
            for j in range(1,len(s)): #j : the lenght of substring
                for i in range(len(s)):
                    if i + j >= len(s):continue
                    elif i + 1 > i + j - 1 and s[i] == s[i+j]:
                        continue
                    elif i + 1 > i + j - 1 and s[i] != s[i + j]:
                        dp[i][i + j] = 1
                    elif s[i] == s[i+j]:
                        dp[i][i+j] = min(dp[i+1][i+j-1],dp[i+1][i+j]+1,dp[i][i+j-1] + 1)
                    else:
                        dp[i][i + j] = min(dp[i + 1][i + j] + 1,dp[i + 1][i + j-1] + 2, dp[i][i + j-1] + 1)
            #print dp
            return dp[0][-1]
  • 相关阅读:
    把数组排成最小的数
    整数中1出现的次数
    连续子数组的最大和
    快速排序
    penCV入门
    OpenCV视频操作
    linux下导入oracle数据表
    js工作备注
    oracle创建默认表空间---重要
    oracle的导入导出
  • 原文地址:https://www.cnblogs.com/seyjs/p/12161469.html
Copyright © 2011-2022 走看看