91、解码方法
一条包含字母 A-Z 的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数
解:这道题用递归显然是没有问题的。这里要注意的是0,单独一个0显然无法解码,0只能变为10,20来解码,否则s是无法解码的。
class Solution:
def numDecodings(self, s: str) -> int:
n=len(s)
if n==1:
if s[0]=='0':
return 0
else:
return 1
if n==2:
if s[0]=='0':
return 0
elif s[1]=='0' and int(s)<=26:
return 1
elif s[1]=='0' and int(s)>26:
return 0
elif int(s)<=26:
return 2
else:
return 1
if s[-1]=='0':
if int(s[-2])>2 or s[-2]=='0':
return 0
else:
return self.numDecodings(s[:n-2])
elif s[-2]=='0':
return self.numDecodings(s[:n-1])
elif int(s[-2:])<=26:
return self.numDecodings(s[:n-2])+self.numDecodings(s[:n-1])
else:
return self.numDecodings(s[:n-1])
然而很遗憾,最后会超时,但可以改成记忆化的递归
class Solution:
def numDecodings(self, s: str) -> int:
n=len(s)
ans=[0]
def memory(s,ans,i):
if i==1:
if s[0]=='0':
return 0
else:
return 1
if i==2:
if s[0]=='0':
return 0
elif s[1]=='0' and int(s)<=26:
return 1
elif s[1]=='0' and int(s)>26:
return 0
elif int(s)<=26:
return 2
else:
return 1
if s[-1]=='0':
if int(s[-2])>2 or s[-2]=='0':
return 0
else:
return ans[i-2]
elif s[-2]=='0':
return ans[i-1]
elif int(s[-2:])<=26:
return ans[i-2]+ans[i-1]
else:
return ans[i-1]
for i in range(1,n+1):
a=memory(s[:i],ans,i)
ans.append(a)
return ans[n]
这样就满足时间限制了
执行用时:36 ms, 在所有 Python3 提交中击败了94.01%的用户
内存消耗:13.5 MB, 在所有 Python3 提交中击败了92.10%的用户
92、反转链表 II
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
解:用一趟完成说明要用很多变量
先移动m次,同时记录m-1和m,在移动n-m+1次,这时要再引入两个新变量,一个记录下一步,一个用来反转即next=res.next,res.next=trans,trans=res,res=next,这样就完成了一次旋转,走完n-m+1步后res在n+1,trans在n,让m-1连n,m连n+1就可以了
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
count=0
ans=ListNode(None)
ans.next=head
res=ans
for _ in range(m):
pre=res#pre记录m-1
res=res.next#res记录m
M=res#记录m
resNext=None
back=None#用于反转的
for _ in range(n-m+1):
resNext=res.next
res.next=back
back=res
res=resNext
pre.next=back#m-1的下一个是n
M.next=res#m的下一个是n+1
return ans.next
执行用时:40 ms, 在所有 Python3 提交中击败了75.39%的用户
内存消耗:13.5 MB, 在所有 Python3 提交中击败了97.43%的用户
93、复原IP地址
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。
解:这种题还是用dfs最靠谱,而且由于数字小,所以不会花费太长的时间。
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
def dfs(s,path,depth,n,ans):
if len(path)>4 or (len(path)==4 and depth<n-1):#没找对
return
if depth >=n:
if len(path)==4:
ans.append(".".join(path))
return
if s[depth]=='0':
dfs(s,path+[s[depth]],depth+1,n,ans)
return
for i in range(depth,n):
if 0<int(s[depth:i+1])<=255:
dfs(s,path+[s[depth:i+1]],i+1,n,ans)
else:
break
return
n=len(s)
ans=[]
dfs(s,[],0,n,ans)
return ans
执行用时:32 ms, 在所有 Python3 提交中击败了99.14%的用户
内存消耗:13.7 MB, 在所有 Python3 提交中击败了48.44%的用户
速度快得令人难以置信,说明这道题只能遍历
94、二叉树的中序遍历
给定一个二叉树,返回它的中序 遍历。
解:递归先遍历左子树,再加入根,再遍历右子树。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
执行用时:36 ms, 在所有 Python3 提交中击败了88.05%的用户
内存消耗:13.6 MB, 在所有 Python3 提交中击败了67.31%的用户
95、不同的二叉搜索树 II
给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。
解法一:比父节点小的key都出现在左子树,比父节点大的都出现在右子树。
这种题用递归和dfs都是可以的,但是递归的思路更简单,因为当确定了根节点后问题自然被分成了更小的两部分。解法一就先用递归。
对于k作为根顶点的情况1,…,k-1在左子树,递归[1,…,k-1]的情况,k+1,…n在右子树,递归[k+1,…n]的情况。当n=0或1时是特殊情况或者说递归的初始条件。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def generateTrees(self, n: int) -> List[TreeNode]:
if n==0:
return []
def generation(nums):
k=len(nums)
if k==0:
return [None]#返回null
if k==1:
return [TreeNode(nums[0])]
ans = []
for i in range(k):
for left in generation(nums[:i]):
for right in generation(nums[i + 1:]):
ans.append(TreeNode(nums[i], left=left, right=right))
return ans
return generation(list(range(1, n+1)))
执行用时:68 ms, 在所有 Python3 提交中击败了83.93%的用户
内存消耗:15.7 MB在所有 Python3 提交中击败了5.21%的用户