目录
1两数之和
2两数相加
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
pos = 0
self.res = None
while l1 or l2 or pos==1:
v1 = l1.val if l1 else 0 # 指针空值为0
v2 = l2.val if l2 else 0 # python的if使用可以很整齐
pos = self.handle(v1+v2+pos)
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return self.res
def handle(self, sum):
if self.res: # 计算十位、百位等
self.temp.next = ListNode(val=sum%10, next=None)
self.temp = self.temp.next
else: # 计算个位值
self.res = ListNode(val=sum%10, next=None)
self.temp = self.res
pos = 1 if sum >=10 else 0 # 计算进位
return pos
3无重复字符的最长子串-滑动窗口
第一次学到滑动窗口,好用点赞
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s: return 0 # 空
r, e, size = 0, 1, 0
# 存好每个字符最近一次出现的位置
dic = {s[r]: r} # 第一个元素
while r < len(s):
# 窗口右边滑动
while e < len(s) and s[e] not in s[r:e]:
dic[s[e]] = e
e +=1
# 窗口停止,比较
size = max(size, e-r)
# 窗口左边滑动
if e == len(s): break
r = dic[s[e]]+1
return size
4寻找两个正序数组的中位数
难度是困难,但用python很简单:合并、排序、取长度中间值
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums1.extend(nums2) # 合并
nums1.sort() # 排序
leng = len(nums1)
i = int(leng/2)
if leng%2==1: # 长度为奇数,直接取中位数
return round(nums1[i], 5)
else: # 长度为偶数,取中间两位数的平均值
sum = nums1[i] + nums1[i -1]
return round(sum/2, 5)
5最长回文子串
class Solution:
def longestPalindrome(self, s: str) -> str:
self.maxStart = 0
self.maxLeng = 1
self.s = s
for i in range(1,len(s)):
self.center(i, i) # 长度奇数,以同一个数为中心,向左向右蔓延
self.center(i-1, i) # 长度偶数,以左右两数为中心,向左向右蔓延
return s[self.maxStart: self.maxStart+self.maxLeng]
def center(self, i1, i2): # 对比中心左右两边是否相同,回文一定相同,否则不是回文
while i1>=0 and i2<len(self.s):
if self.s[i1] == self.s[i2]:
i1, i2 = i1-1, i2+1
else:
break
if i2-i1-1 > self.maxLeng:
self.maxStart = i1+1
self.maxLeng = i2-i1-1
6 Z字形变换
class Solution:
def convert(self, s: str, numRows: int) -> str:
leng = len(s)
if leng < numRows or numRows ==1: return s
# 以|/为一组。其中,|有numRows个,/上有numRows-2个,因此一组有2*numRows -2个
factor = 2*numRows -2
# 一共有多少组:最后一组可能没满编,保险+1
n_group = leng//factor+1
res = ""
for rowid in range(numRows):
for n in range(n_group):
if rowid in [0, numRows-1]: # 每组中,第一行、最后一行只有一个字母
if n*factor+rowid < leng: res += s[n*factor+rowid]
else: # 其他行,应该有两个字母,但要考虑最后一组未满编的情况
if n*factor+rowid < leng: res += s[n*factor+rowid]
if n*factor+factor-rowid < leng: res += s[n*factor+factor-rowid]
return res
7整数反转
class Solution:
def reverse(self, x: int) -> int:
n = abs(x) # 取绝对值
n_str = str(n) # 转字符串
n_re = n_str[::-1] # 字符串反转
res = int(n_re) # 转整数
if x<0: res = -res # 判断正负
if res < -2**31 or res >2**31 - 1:
return 0
return res
8字符串转换整数(atoi)
python字符串反转有两种,方法一比方法二快
① s1 = s[::-1]
② s1 = ''.join([s[len(s)-1-i] for i in range(len(s))])
class Solution:
def myAtoi(self, s: str) -> int:
# 读入字符串并丢弃无用的前导空格
s1 = s.lstrip()
# 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。
# 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
start, eff = 0, ['+', '-']
while start < len(s1) and s1[start] in eff:
start +=1
# 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
end, eff = start, [str(i) for i in range(10)]
while end < len(s1) and s1[end] in eff:
end +=1
# 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。
# 如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
if start >1 or end == start:
return 0
# 如果整数数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内
# 具体来说,小于 −2^31 的整数应该被固定为 −2^31 ,大于 2^31 − 1 的整数应该被固定为 2^31 − 1 。
res = int(s1[:end])
if res < -2**31: return -2**31
elif res > 2**31-1: return 2**31-1
# 返回整数作为最终结果。
else: return res
9回文数
class Solution:
def isPalindrome(self, x: int) -> bool:
s = str(x)
s1 = s[::-1]
return s1==s
10正则表达式匹配
用re库可以直接过关,但是建议不要这么做(实在是博主虽然有动态规划的思路,但时限里做不出来,就直接上re了)
import re # 正则表达式库
class Solution:
def isMatch(self, s: str, p: str) -> bool:
res = re.match(r""+p, s)
if not res: return False
return res.group()==s