[Leetcode] [チュートリアル] 多次元動的プログラミング


62. 異なる道

ロボットは m ∗ *に位置します n グリッドの左上隅 (開始点は、下の図で「開始」とマークされています)。

ロボットは一度に 1 ステップ下または右へのみ移動できます。ロボットはグリッドの右下隅に到達しようとします。

異なるパスは合計で何通りありますか?

例 1:

入力: m = 3、n = 7
出力: 28

解決

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[1] * n for _ in range(m)]
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        return dp[m - 1][n - 1]

64. 最小パス合計

負でない整数を含む mxn グリッドが与えられた場合、パス上の数値の合計が最小になるように、左上隅から右下隅までのパスを見つけます。

注: 一度に下または右に 1 ステップのみ移動できます。

例:

入力: Grid = [[1,3,1],[1,5,1],[4,2,1]]
出力: 7
説明: パス 1→3→1→1→1 の合計は一番小さい。

解決

5. 最長の回文部分文字列

文字列 s が与えられた場合、s 内の最長の回文部分文字列を見つけます。

例:
入力: s = "babad"
出力: "bab"
説明: "aba" も質問の意味に合った答えです。

解決

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n < 2:
            return s

        # 初始化动态规划的表
        dp = [[False] * n for _ in range(n)]
        start = 0  # 记录最长回文子串的起始位置
        max_len = 1  # 记录最长回文子串的长度

        # 初始化长度为1的所有子串为回文
        for i in range(n):
            dp[i][i] = True

        # 动态规划填表
        for j in range(1, n):
            for i in range(0, j):
                if s[i] == s[j]:
                    if j - i < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i + 1][j - 1]

                # 更新最长回文子串的信息
                if dp[i][j]:
                    if j - i + 1 > max_len:
                        max_len = j - i + 1
                        start = i

        return s[start:start + max_len]

中心拡張アルゴリズムを使用する基本的な考え方は、各文字を回文の中心とみなして外側に拡張することです。回文の長さは奇数でも偶数でもよいことに注意してください。たとえば、「aba」は「b」を中心とする奇数長の回文であり、「abba」は「bb」を中心とする偶数長の回文です。

文字列の各文字を反復処理し、各文字に対して奇数展開と偶数展開を試みて、最長の回文部分文字列を見つけることができます。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 特殊情况,空字符串或长度为1的字符串直接返回
        if len(s) < 2:
            return s
        
        start = 0  # 最长回文子串的起始位置
        max_len = 1  # 最长回文子串的长度

        for i in range(len(s)):
            # 奇数长度的回文检查
            l, r = i, i
            while l >= 0 and r < len(s) and s[l] == s[r]:
                l -= 1
                r += 1
            if r - l - 1 > max_len:
                max_len = r - l - 1
                start = l + 1

            # 偶数长度的回文检查
            l, r = i, i + 1
            while l >= 0 and r < len(s) and s[l] == s[r]:
                l -= 1
                r += 1
            if r - l - 1 > max_len:
                max_len = r - l - 1
                start = l + 1

        return s[start: start + max_len]

おすすめ

転載: blog.csdn.net/weixin_45427144/article/details/132247979