classSolution(object): deffindMedianSortedArrays(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: float """ deffindKth(A,B,k): iflen(A) == 0: return B[k-1] iflen(B) == 0: return A[k-1] if k == 1: returnmin(A[0],B[0]) a = A[k//2-1] iflen(A) >= k // 2elseNone b = B[k//2-1] iflen(B) >= k // 2elseNone # if a is None: # return findKth(A, B[k // 2:], k - k // 2) # 这里要注意:因为 k//2 不一定等于 (k - k//2) # if b is None: # return findKth(A[k // 2:], B, k - k // 2) # if a < b: # return findKth(A[k // 2:], B, k - k // 2) # else: # return findKth(A, B[k // 2:], k - k // 2)
if b isNoneor (a isnotNoneand a < b): return findKth(A[k // 2:], B, k - k // 2) return findKth(A, B[k // 2:], k - k // 2) n = len(nums1) + len(nums2) if n % 2 == 1: return findKth(nums1,nums2,n//2+1) else: small = findKth(nums1,nums2,n//2) large = findKth(nums1,nums2,n//2+1) return (small + large) / 2.0
classSolution(object): deffindMedianSortedArrays(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: float """ deffindKth(A, pa, B, pb, k): res = 0 m = 0 while pa < len(A) and pb < len(B) and m < k: if A[pa] < B[pb]: res = A[pa] pa += 1 else: res = B[pb] pb += 1 m += 1 while pa < len(A) and m < k: res = A[pa] pa += 1 m += 1 while pb < len(B) and m < k: res = B[pb] pb += 1 m += 1 return res n = len(nums1) + len(nums2) if n % 2 == 1: return findKth(nums1, 0, nums2, 0, n // 2 + 1) else: smaller = findKth(nums1, 0, nums2, 0, n // 2) bigger = findKth(nums1, 0, nums2, 0, n // 2 + 1) return (smaller + bigger) / 2.0
2. 最长回文字串(Medium)
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
1 2 3
输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。
示例 2:
1 2
输入: "cbbd" 输出: "bb"
解答:
思路一:时间复杂度$O(n^2)$,空间复杂度$O(n^2)$
动态规划思想:dp[i][j]表示s[i:j+1]是否是palindrome
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution(object): deflongestPalindrome(self, s): """ :type s: str :rtype: str """ res = '' dp = [[False] * len(s) for i inrange(len(s))] for i inrange(len(s),-1,-1): for j inrange(i,len(s)): dp[i][j] = (s[i] == s[j]) and (j-i<3or dp[i+1][j-1]) if dp[i][j] and j-i+1>len(res): res = s[i:j+1] return res
思路二:时间复杂度$O(n^2)$,空间复杂度$O(1)$
回文字符串长度为奇数和偶数是不一样的:
奇数:'xxx s[i] xxx', 比如 'abcdcba'
偶数:'xxx s[i] s[i+1] xxx', 比如 'abcddcba'
我们区分回文字符串长度为奇数和偶数的情况,然后依次把每一个字符当做回文字符串的中间字符,向左右扩展到满足回文的最大长度,不停更新满足回文条件的最长子串的左右index: l 和r,最后返回s[l:r+1]即为结果。
classSolution(object): deflongestPalindrome(self, s): """ :type s: str :rtype: str """ l = 0# left index of the current substring r = 0# right index of the current substring max_len = 0# length of the longest palindromic substring for now n = len(s) for i inrange(n): # odd case: 'xxx s[i] xxx', such as 'abcdcba' for j inrange(min(i+1, n-i)): # 向左最多移动 i 位,向右最多移动 (n-1-i) 位 if s[i-j] != s[i+j]: # 不对称了就不用继续往下判断了 break if2 * j + 1 > max_len: # 如果当前子串长度大于目前最长长度 max_len = 2 * j + 1 l = i - j r = i + j
# even case: 'xxx s[i] s[i+1] xxx', such as 'abcddcba' if i+1 < n and s[i] == s[i+1]: for j inrange(min(i+1, n-i-1)): # s[i]向左最多移动 i 位,s[i+1]向右最多移动 [n-1-(i+1)] 位 if s[i-j] != s[i+1+j]: # 不对称了就不用继续往下判断了 break if2 * j + 2 > max_len: max_len = 2 * j + 2 l = i - j r = i + 1 + j return s[l:r+1]
classSolution(object): defconvert(self, s, numRows): """ :type s: str :type numRows: int :rtype: str """ if numRows == 1orlen(s) <= numRows: return s res = [''] * numRows idx,step = 0,1 for c in s: res[idx] += c if idx == 0: step = 1 elif idx == numRows - 1: step = -1 idx += step return''.join(res)
思路二:模拟过程
Z字形,就是两种状态,一种垂直向下,还有一种斜向上
控制好边界情况就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: defconvert(self, s: str, numRows: int) -> str: ifnot s: return"" if numRows == 1:return s s_Rows = [""] * numRows i = 0 n = len(s) while i < n: for j inrange(numRows): if i < n: s_Rows[j] += s[i] i += 1 for j inrange(numRows-2,0,-1): if i < n: s_Rows[j] += s[i] i += 1 return"".join(s_Rows)