leetcode 5. 最长回文子串 6. Z 字形变换
5. 最长回文子串
难度中等3632收藏分享切换为英文接收动态反馈
给你一个字符串 s
,找到 s
中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
提示:
1 <= s.length <= 1000
s
仅由数字和英文字母(大写和/或小写)组成
class Solution:
def longestPalindrome(self, s: str) -> str:
ans = s[0]
for i in range(len(s)):
arr = []
s2 = s
l = 0
while True:
l = s2.find(s[i],l+1)
if l == -1:
break
arr.append(l)
for n in arr:
if n != i and n > -1:
f = s[i:n+1]
if f == f[::-1]:
if len(f) > len(ans):
ans = f
return ans
"""
优化版
"""
def longestPalindrome2(self, s: str) -> str:
ans = s[0]
for i in range(len(s)):
l = len(s)
while True:
a = s.rfind(s[i],i,l)
if a == -1:
break
f = s[i:a + 1]
if f == f[::-1]:
if len(ans) < len(f):
ans = f
l = a
return ans
"""
官方解法
"""
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
max_len = 1
begin = 0
# dp[i][j] 表示 s[i..j] 是否是回文串
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
# 递推开始
# 先枚举子串长度
for L in range(2, n + 1):
# 枚举左边界,左边界的上限设置可以宽松一些
for i in range(n):
# 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
j = L + i - 1
# 如果右边界越界,就可以退出当前循环
if j >= n:
break
if s[i] != s[j]:
dp[i][j] = False
else:
if j - i < 3:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1]
# 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
begin = i
return s[begin:begin + max_len]
if __name__ == '__main__':
a = {"a":1,"b":2}
print(Solution().longestPalindrome3("babadasdasfdsfsadfasdfafds"))
6. Z 字形变换
难度中等1136收藏分享切换为英文接收动态反馈
将一个给定字符串 s
根据给定的行数 numRows
,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING"
行数为 3
时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"
。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入:s = "A", numRows = 1
输出:"A"
提示:
1 <= s.length <= 1000
s
由英文字母(小写和大写)、','
和'.'
组成1 <= numRows <= 1000
class Solution:
def convert(self, s: str, numRows: int) -> str:
if len(s) <= numRows or numRows == 1:
return s
arr = ""
lens = len(s)
sp = 2 + (numRows - 2) * 2
rows = lens//sp +1
for i in range(numRows):
for i2 in range(rows):
n = i2*sp+i
if n<len(s):
arr += s[n]
sp2 = 2 + (numRows - i - 2) * 2
if i > 0 and i < numRows - 1 and n+sp2 < len(s):
arr += s[n + sp2]
return arr
if __name__ == '__main__':
print(Solution().convert("PAYPALISHIRING",3))