記事ディレクトリ
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]