61. 旋转链表
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head:
return
temp=head
n=1
# 计算链表长度
while temp.next:
temp=temp.next
n=n+1
k=k%n #实际需要从后往前移多少次
temp.next=head # 形成闭合环状链表
# 寻找移动后头节点位置
for i in range(n-k):
temp=temp.next
head=temp.next
temp.next=None # 断开环状链表
return head
62. 不同路径
方法一:
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[0 for _ in range(n)] for _ in range(m)]
dp[0][0] = 1
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
continue
if i > 0:
dp[i][j] = dp[i][j]+dp[i-1][j]
if j > 0:
dp[i][j] = dp[i][j]+dp[i][j-1]
return dp[m-1][n-1]
方法二:
import math
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
return math.comb(m+n-2, n-1)
63. 不同路径 II
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m,n=len(obstacleGrid),len(obstacleGrid[0])
dp=[[0 for _ in range(n)] for _ in range(m)]
# 特判初值
if obstacleGrid[0][0]==0:
dp[0][0]=1
else:
dp[0][0]=0
for i in range(m):
for j in range(n):
if obstacleGrid[i][j]==1:
continue
if i>0:
dp[i][j]=dp[i][j]+dp[i-1][j]
if j>0:
dp[i][j]=dp[i][j]+dp[i][j-1]
return dp[m-1][n-1]
64. 最小路径和
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
m=len(grid)
n=len(grid[0])
for i in range(m):
for j in range(n):
if i==0 and j==0:
grid[i][j]=grid[0][0]
elif i==0:
grid[i][j]=grid[i][j]+grid[i][j-1]
elif j==0:
grid[i][j]=grid[i][j]+grid[i-1][j]
else:
grid[i][j]=min(grid[i-1][j],grid[i][j-1])+grid[i][j]
return grid[-1][-1]
65. 有效数字
class Solution:
def isNumber(self, s: str) -> bool:
s=s.strip()
numbers=[str(i) for i in range(10)]
n=len(s)
num_show,e_show,dot_show,num_e_after=False,False,False,False
for i in range(n):
c=s[i]
if c in numbers:
num_show=True
num_e_after=True
elif c in ('+','-'):
# +—号只能出现在开头或者e后面
if i>0 and s[i-1]!='e' and s[i-1]!='E':
return False
elif c == 'e' or c =='E':
# e不能出现两次,e前面要有数字,e后面也要有数字
if e_show or not num_show:
return False
e_show=True
num_e_after=False
elif c=='.':
# .不能出现两次,也不能和e同时出现
if e_show or dot_show:
return False
dot_show=True
else:
# 出现其他字符直接false
return False
# 必须有数字并且e后要有数字
return num_show and num_e_after
66. 加一
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
s=''
for i in digits:
s=s+str(i)
res=str(int(s)+1)
ans=[int(i) for i in res]
return ans
67. 二进制求和
class Solution:
def addBinary(self, a: str, b: str) -> str:
a=a[::-1]
b=b[::-1]
i=0
carry=0
res=''
while i<len(a) or i <len(b) or carry:
if i<len(a):
carry=carry+int(a[i])
if i < len(b):
carry=carry+int(b[i])
res=res+str(carry%2)
carry=carry//2
i=i+1
return res[::-1]
68. 文本左右对齐
比较繁琐:
class Solution:
def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
res = []
i = 0
# 这里不能用for i in range(len(words)), 因为循环末尾i要重置到j - 1,再i += 1
while i < len(words):
# 看一下当前行可以放哪些单词,从下一个单词开始看
j = i + 1
# length当前单词的长度
length = len(words[i])
# 当j没有越界,并且当前单词长度加上空格,加上下一个单词长度没有超过maxWidth时,j+=1
while j < len(words) and length + 1 + len(words[j]) <= maxWidth:
length += 1 + len(words[j])
j += 1
# 循环结束后,得到可以放在当前行的单词为 words[i] ~ words[j - 1]
line = ''
# 第一种情况: 左对齐
# j == len(words)说明在最后一行,或者j = i + 1: 这一行只放一个单词words[i]
if j == len(words) or j == i + 1:
# 先把word[i] 添进这一行
line += words[i]
# 再加上空格和word[i + 1] ~ word[j - 1]
for k in range(i + 1, j):
line += ' ' + words[k]
# 不足最大长度,补上空格
while len(line) < maxWidth:
line += ' '
else:
# 第二种情况: 左右对齐
# cnt 空隙的数量, 单词数量为 j - i, 空隙数量少一个再减去1
cnt = j - i - 1
# r:有多少个剩余空格可用, length(是单词总长度以及空隙个数的空格),再加上空隙个数的空格
r = maxWidth - length + cnt
# 加上当前单词
line += words[i]
# 从第0个空隙开始
k = 0
# 先看空格较多的空隙
while k < r % cnt:
line += ' ' * (r // cnt + 1) + words[i + k + 1]
k += 1
# 空格较少空隙:
while k < cnt:
line += ' ' * (r // cnt) + words[i + k + 1]
k += 1
# 把当前行加进答案
res.append(line)
# i ~ j - 1单词已经加入,i从j开始
i = j
return res
69. x 的平方根
经典二分:
class Solution:
def mySqrt(self, x: int) -> int:
left,right=1,x
if x==0:
return 0
if x==1:
return 1
while left<right:
mid = (left+right+1)//2
if mid *mid <=x:
left=mid
else:
right=mid-1
return left
70. 爬楼梯
经典dp:
class Solution:
def climbStairs(self, n: int) -> int:
if n<3:
return n
dp=[0 for _ in range(n)]
dp[0]=1
dp[1]=2
for i in range(2,n):
dp[i]=dp[i-1]+dp[i-2]
return dp[-1]