2023-06-10更新
牛客 ⌈面试必刷 TOP 101⌋ -- Python 版 【更新中】
- BM12 单链表的排序
- BM13 判断一个链表是否为回文结构
- BM14 链表的奇偶重排
- BM15 删除有序链表中重复的元素-I
- BM16 删除有序链表中重复的元素-II
- BM17 二分查找-I
- BM18 二维数组中的查找
- BM19 寻找峰值
- BM20 数组中的逆序对
- BM21 旋转数组的最小数字
- BM22 比较版本号
- BM 23 二叉树前序遍历
- BM 24 二叉树的中序遍历
- BM 25 二叉树的后序遍历
- BM26 求二叉树的层序遍历
- BM27 按之字形顺序打印二叉树
- BM28 二叉树的最大深度
- BM29 二叉树中和为某一值的路径(一)
- BM30 二叉搜索树与双向链表
- BM31 对称的二叉树
- BM32 合并二叉树
- BM33 二叉树的镜像
- BM34 判断是不是二叉搜索树
- BM35 判断是不是完全二叉树
- BM 62 斐波那契数列
- BM42 用两个栈实现队列
- BM43 包含min函数的栈
- BM63 跳台阶
- BM64
BM12 单链表的排序
思路
- 将数据存到
list
中,使用list
自带的sort()
函数排序,然后更新原来的链表数据。
代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类 the head node
# @return ListNode类
#
class Solution:
def sortInList(self , head: ListNode) -> ListNode:
# write code here
vallist=[]
p=head
while p:
vallist.append(p.val)
p=p.next
print(vallist)
vallist.sort()
p=head
for item in vallist:
p.val=item
p=p.next
return head
BM13 判断一个链表是否为回文结构
思路
- 读取链表中的值存入
list
,借助Python
的reversed
函数,将list
逆序,然后比较两个list
是否一致。
代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类 the head
# @return bool布尔型
#
class Solution:
def isPail(self , head: ListNode) -> bool:
# write code here
list1=[]
while head:
list1.append(head.val)
head=head.next
list2=list(reversed(list1))
print(list1)
print(list2)
if list1==list2:
return True
else:
return False
BM14 链表的奇偶重排
思路
- 遍历链表,使用双指针将奇项和偶项连起来,然后奇项链表的尾指偶项链表的头。
代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @return ListNode类
#
class Solution:
def oddEvenList(self , head: ListNode) -> ListNode:
# write code here
pHead1=ListNode(-1)
pHead2=ListNode(-1)
pHead11=pHead1
pHead22=pHead2
i=1
while head:
if i%2==1:
pHead1.next=head
pHead1=pHead1.next
else:
pHead2.next=head
pHead2=pHead2.next
head=head.next
# print(head.val)
i=i+1
pHead1.next=None
pHead2.next=None
pHead1.next=pHead22.next
return pHead11.next
BM15 删除有序链表中重复的元素-I
思路
- 双指针,一个为
head
指针,一个指向head
指针指向节点的前一个节点。遍历head
链表,比较head
所指的值和fhead
所指的值,如果相同,则重复,将此节点从链表中删除;如果不同,则不重复,fhead
和head
分别向后移一位。
代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @return ListNode类
#
class Solution:
def deleteDuplicates(self , head: ListNode) -> ListNode:
# write code here
if not head:
return head
rhead=head
fhead=head
head=head.next
while head:
if head.val==fhead.val:
fhead.next=head.next
else:
fhead=head
head=head.next
return rhead
BM16 删除有序链表中重复的元素-II
思路
- 双指针,
fhead
和head
,初始情况下fhead.next == head
。使用flag
标记是否出现重复值。使用head
指针遍历链表,如果head
的值和head.next
的值一样,将flag
标记为1
,head
后移;如果不一样且flag == 1
,那么fhead.next
指向head.next
,head
指向head.next
;如果不一样且flag==0
,那么fhead
和head
同时后移一位。在遍历结束后,注意flag==1
的情况。
代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @return ListNode类
#
class Solution:
def deleteDuplicates(self , head: ListNode) -> ListNode:
# write code here
if not head or not head.next:
return head
rhead=ListNode(0)
rhead.next=head
fhead=rhead
flag=0
while head.next:
print(head.val)
if head.val==head.next.val:
flag=1
elif flag==0 and head.val!=head.next.val:
fhead=head
flag=0
elif flag==1 and head.val!=head.next.val:
print("x")
fhead.next=head.next
flag=0
head=head.next
if flag==1:
fhead.next=None
return rhead.next
BM17 二分查找-I
思路
- 二分查找
- 这篇文章分析的很不错,参考:【二分查找】详细图解
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @param target int整型
# @return int整型
#
class Solution:
def search(self , nums: List[int], target: int) -> int:
# write code here
if len(nums)==0:
return -1
left=0
right=len(nums)-1
while left<=right:
middle=left+int((right-left)/2)
print(nums[middle])
if nums[middle]==target:
return middle
elif nums[middle]<target:
left=middle+1
elif nums[middle]>target:
right=middle-1
return -1
BM18 二维数组中的查找
思路
- 二维数组左下角的值ld具备的属性:当前列的最大值,当前行的最小值,将ld与target比较:
- target==ld:找到该值
- target>ld:target比当前列的最大值大,右移一列
- target<ld:target比当前行的最小值小,上移一行
- 循环结束条件:找到目标值或ld移除二维数组
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param target int整型
# @param array int整型二维数组
# @return bool布尔型
#
class Solution:
def Find(self , target: int, array: List[List[int]]) -> bool:
# write code here
h=len(array)
if h==0:
return False
w=len(array[0])
if h==1 and w==1:
return False
ld_i=h-1
ld_j=0
while ld_i>=0 and ld_j<w:
if target ==array[ld_i][ld_j]:
return True
elif target<array[ld_i][ld_j]:
ld_i=ld_i-1
elif target>array[ld_i][ld_j]:
ld_j=ld_j+1
return False
BM19 寻找峰值
思路
- 这道题,只能说很抽象,因为左右两边都是最小值,所以如果最开始是递减或最末尾是递增,那么也算是峰值。举两个例子:
- [2,4,1,2,7,8,4],输出5
- [2,4,1,2,7,8,9],输出6
- [4,3,2,1],输出0
- 参考链接:(寻找峰值(二分法)_osillto的博客-CSDN博客
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @return int整型
#
class Solution:
def findPeakElement(self , nums: List[int]) -> int:
left,right = 0,len(nums)-1
while left<right:
mid = (left+right)//2
if nums[mid] < nums[mid+1]: left = mid+1
else: right = mid
return left
BM20 数组中的逆序对
思路
- 首先,全遍历不行,复杂度不满足要求
- 然后参考合并排序思路,进行逆数对统计。
- 思路参考:
- 代码参考:
- Python 列表逆序方法:(Python 列表逆序排列的 3 种方式_python中的逆序排列_Nick Blog的博客-CSDN博客
Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> arr=[1,2,3,4,5,6,7] >>> arr[::-1] [7, 6, 5, 4, 3, 2, 1] >>> arr[:5] [1, 2, 3, 4, 5] >>> arr[:5][::-1] [5, 4, 3, 2, 1] >>>
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param data int整型一维数组
# @return int整型
#
class Solution:
def __init__(self):
self.res=0
self.kmod=1000000007
def mergeSort(self,arr):
n=len(arr)
if n==1:
return arr
mid =n//2
leftList=self.mergeSort(arr[:mid])
rightList=self.mergeSort(arr[mid:])
temp=[]
i=len(leftList)-1
j=len(rightList)-1
while i>=0 and j>=0:
if leftList[i]>=rightList[j]:
temp.append(leftList[i])
i=i-1
self.res=(self.res+j+1)%self.kmod
else:
temp.append(rightList[j])
j=j-1
if i==-1:
temp+=rightList[:j+1][::-1]
elif j==-1:
temp+=leftList[:i+1][::-1]
return temp[::-1]
def InversePairs(self , data: List[int]) -> int:
# write code here
self.mergeSort(data)
return self.res
BM21 旋转数组的最小数字
思路
- 二分查找,但是判断条件有些混乱。再理一下:
- 如果中间的值等于左边的值:那么最小值肯定不在mid左边,所以left=mid
- 如果中间的值等于右边的值:那么最小值肯定不在mid右边,所以right=mid
- 如果左边的值大于中间的值:那么最小值一定在左边,所以right=mid
- 如果右边的值小于中间的值:那么最小值一定在右边,所以left=mid
- 当left+1==right的时候,两个数中较小的值是最小值
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param rotateArray int整型一维数组
# @return int整型
#
class Solution:
def minNumberInRotateArray(self , rotateArray: List[int]) -> int:
# write code here
left=0
right=len(rotateArray)-1
while(left+1<right):
mid=(left+right)//2
print(left,mid,right)
if rotateArray[mid]>rotateArray[mid+1]:
return rotateArray[mid+1]
elif rotateArray[mid]==rotateArray[len(rotateArray)-1] or rotateArray[mid]<rotateArray[0]:
right=mid
elif rotateArray[mid]==rotateArray[0] or rotateArray[mid]>rotateArray[len(rotateArray)-1]:
left=mid
if rotateArray[left]<rotateArray[right]:
return rotateArray[left]
else:
return rotateArray[right]
BM22 比较版本号
思路
- 使用python字符串的split函数,将版本号基于“.”拆分成数组,逐个比较。
- 参考链接:https://blog.csdn.net/qq_61959780/article/details/127690872
- 代码参考:GPT
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 比较版本号
# @param version1 string字符串
# @param version2 string字符串
# @return int整型
#
class Solution:
def compare(self , version1: str, version2: str) -> int:
# write code here
lst1=version1.split(".")
lst2=version2.split(".")
i=0
while i<len(lst1) or i<len(lst2):
data1=lst1[i] if i<len(lst1) else 0
data2=lst2[i] if i<len(lst2) else 0
if int(data1)<int(data2):
return -1
elif int(data1)>int(data2):
return 1
i+=1
return 0
BM 23 二叉树前序遍历
思路
- 递归
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return int整型一维数组
#
class Solution:
def preorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
res=[]
def dfs(node):
if not node:
return
res.append(node.val)
dfs(node.left)
dfs(node.right)
dfs(root)
return res
BM 24 二叉树的中序遍历
思路
- 先读取节点值,再遍历左子树,再遍历右子树。
- 代码和BM23只有读取节点值的位置不同。
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return int整型一维数组
#
class Solution:
def inorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
res=[]
def dfs(node):
if not node:
return
dfs(node.left)
res.append(node.val)
dfs(node.right)
dfs(root)
return res
BM 25 二叉树的后序遍历
思路
- 先遍历左子树,再遍历右子树,再读取节点值。
- 代码和BM23只有读取节点值的位置不同。
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return int整型一维数组
#
class Solution:
def postorderTraversal(self , root: TreeNode) -> List[int]:
# write code here
res=[]
def dfs(node):
if not node:
return
dfs(node.left)
dfs(node.right)
res.append(node.val)
dfs(root)
return res
BM26 求二叉树的层序遍历
思路
- GPT生成代码及思路
- 其中,TreeNode是二叉树节点的定义,Solution中的levelOrder方法是层序遍历的实现,使用了队列的方式。层序遍历的顺序是按照从上到下、从左到右的顺序访问每个节点,因此在实现中使用一个队列来存储当前层的节点,在访问当前层的节点时,将其子节点加入队列中,以便在下一层访问。
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return int整型二维数组
#
class Solution:
def levelOrder(self , root: TreeNode) -> List[List[int]]:
# write code here
if not root:
return []
res = []
queue = [root]
while queue:
level = []
for _ in range(len(queue)):
node = queue.pop(0)
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res
BM27 按之字形顺序打印二叉树
思路
- 层序遍历,同时利用[::-1]实现逆序输出。
- 列表逆序的三种方式:
- lst[::-1]
- list(reversed(lst))
- lst.reverse() 注:lista.reverse() 这一步操作的返回值是一个None,其作用的结果,需要通过打印被作用的列表才可以查看出具体的效果
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pRoot TreeNode类
# @return int整型二维数组
#
class Solution:
def Print(self , pRoot: TreeNode) -> List[List[int]]:
# write code here
if not pRoot:
return []
res=[]
queue=[pRoot]
flag=1
while queue:
layer=[]
for _ in range(len(queue)):
node=queue[0]
queue.pop(0)
layer.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
if flag:
res.append(layer)
flag=0
else:
res.append(layer[::-1])
flag=1
return res
BM28 二叉树的最大深度
思路
- dfs,同时记录当前分支上最大深度,返回左右子树中较大值。
代码
- 代码1,函数里面套函数套函数,冗余,精简版看代码2
# class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param root TreeNode类 # @return int整型 # class Solution: def maxDepth(self , root: TreeNode) -> int: # write code here if not root: return 0 def dfs(troot:TreeNode,deep=0) -> int: if not troot: return deep deep=deep+1 deepl=dfs(troot.left,deep) deepr=dfs(troot.right,deep) return deepl if deepl>deepr else deepr return dfs(root)
- 代码2
# class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param root TreeNode类 # @return int整型 # class Solution: def maxDepth(self , root: TreeNode) -> int: # write code here if not root: return 0 else: return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))
BM29 二叉树中和为某一值的路径(一)
思路
- 注意一个点,如果初始树为空,sum为0的情况,要单独考虑。
- 如何判定到达叶子结点:not root.left and not root.right 等同于 not(root.left or root.left)
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @param sum int整型
# @return bool布尔型
#
class Solution:
def hasPathSum(self , root: TreeNode, sum: int) -> bool:
# write code here
if not root:
return False
elif not root.left and not root.right and sum==root.val:
return True
elif self.hasPathSum(root.left,sum-root.val):
return True
else:
return self.hasPathSum(root.right,sum-root.val)
BM30 二叉搜索树与双向链表
思路
- 思路:
- 参考:
代码
- 正确代码:
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
#
# @param pRootOfTree TreeNode类
# @return TreeNode类
#
class Solution:
def Convert(self , pRootOfTree ):
# write code here
if not pRootOfTree:
return
left=self.Convert(pRootOfTree.left)
p=left
while p and p.right:
p=p.right
if left:
pRootOfTree.left=p
p.right=pRootOfTree
right=self.Convert(pRootOfTree.right)
if right:
pRootOfTree.right=right
right.left=pRootOfTree
return left if left else pRootOfTree
- chatgpt给的代码:
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
#
# @param pRootOfTree TreeNode类
# @return TreeNode类
#
class Solution:
def Convert(self , pRootOfTree ):
# write code here
if not pRootOfTree:
return None
nodes = []
self.inorder(pRootOfTree, nodes)
for i in range(len(nodes) - 1):
nodes[i].right = nodes[i + 1]
nodes[i + 1].left = nodes[i]
return nodes[0]
def inorder(self, root, nodes):
if not root:
return
self.inorder(root.left, nodes)
nodes.append(root)
self.inorder(root.right, nodes)
- 自己写的错误代码:
class Solution:
def Convert(self , pRootOfTree ):
# write code here
if not pRootOfTree:
return pRootOfTree
elif not pRootOfTree.left and not pRootOfTree.right:
return pRootOfTree
def calcAZ(root: TreeNode):
if not root.left:
aa=root
else:
aa=calcAZ(root.left)[0]
if not root.right:
zz=root
else:
zz=calcAZ(root.right)[1]
return aa,zz
if pRootOfTree.left and pRootOfTree.right:
newroot,zz=calcAZ(pRootOfTree.left)
pRootOfTree.left=zz
zz.right=pRootOfTree
aa=calcAZ(pRootOfTree.right)[0]
pRootOfTree.right=aa
aa.left=pRootOfTree
elif not pRootOfTree.left:
aa=calcAZ(pRootOfTree.right)[0]
pRootOfTree.right=aa
aa.left=pRootOfTree
newroot=pRootOfTree
elif not pRootOfTree.right:
newroot,zz=calcAZ(pRootOfTree.left)
pRootOfTree.left=zz
zz.right=pRootOfTree
return newroot
BM31 对称的二叉树
思路
- 递归,首先判断根节点是否存在(不存在肯定对称)
- 如果存在,
- 以左右节点为根节点,判断这两棵子树是否对称
- 首先判断左右节点是否都不存在
- 如果都不存在,那么返回true
- 判断左右节点是否都存在且值都一样
- 如果有一点不满足,返回FALSE
- 如果都满足:
- 判断左节点的左子节点和右节点的右子节点是否对称
- 判断左节点的右子节点和右节点的左子节点是否对称
- 如果都对称,那么说明该根节点对应的树对称,返回true;否则不对称,返回false
- 如果不存在(也即是递归结束的条件之一,返回true)
- 如果存在,
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pRoot TreeNode类
# @return bool布尔型
#
class Solution:
def isSymmetrical(self , pRoot: TreeNode) -> bool:
# write code here
def areMirror(left,right)->bool:
if not (left or right):
return True
elif (not left and right) or (not right and left) or left.val!=right.val:
return False
else:
return areMirror(left.left,right.right) and areMirror(left.right,right.left)
if not pRoot:
return True
else:
return areMirror(pRoot.left,pRoot.right)
BM32 合并二叉树
思路
- 将t2合并到t1上
- 如果t1或者t2中有一个为空,那就返回另一个根节点
- 否则,
- t1的值等于t1加t2的值
- t1的左节点等于t1的左节点与t2的左节点合并
- t1的右节点等于t1的右节点与t2的右节点合并
- 返回t1
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param t1 TreeNode类
# @param t2 TreeNode类
# @return TreeNode类
#
class Solution:
def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
# write code here
if not t1 or not t2:
return t1 if t1 else t2
else:
t1.val=t1.val+t2.val
t1.left=self.mergeTrees(t1.left,t2.left)
t1.right=self.mergeTrees(t1.right,t2.right)
return t1
BM33 二叉树的镜像
思路
- 思路一(对应代码1,2)
代码
- 代码1:空间复杂度O(n)
# class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param pRoot TreeNode类 # @return TreeNode类 # class Solution: def Mirror(self , pRoot: TreeNode) -> TreeNode: # write code here if not pRoot: return pRoot pRoot.left, pRoot.right = self.Mirror(pRoot.right), self.Mirror(pRoot.left) # 注意:同时赋值 return pRoot
- 代码2:
class Solution: def Mirror(self, pRoot: TreeNode) -> TreeNode: # write code here if not pRoot: return pRoot tmp = pRoot.left pRoot.left = pRoot.right pRoot.right = tmp self.Mirror(pRoot.right) self.Mirror(pRoot.left) # 注意:不同时赋值 return pRoot
- 代码3:空间复杂度O(1)
class Solution: def Mirror(self , pRoot: TreeNode) -> TreeNode: # write code here if pRoot: stack = [pRoot] while stack: curr = stack.pop() curr.left, curr.right = curr.right, curr.left if curr.right: stack.append(curr.right) if curr.left: stack.append(curr.left) return pRoot
BM34 判断是不是二叉搜索树
思路
- 中序深度优先遍历,遍历结果从小到大排序后和排序前是否一致
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return bool布尔型
#
class Solution:
def isValidBST(self , root: TreeNode) -> bool:
# write code here
nodes=[]
def dfs(pRoot: TreeNode):
if not pRoot: return
dfs(pRoot.left)
nodes.append(pRoot.val)
dfs(pRoot.right)
return
dfs(root)
print(nodes)
print(sorted(nodes))
if nodes==sorted(nodes):
return True
else:
return False
BM35 判断是不是完全二叉树
思路
- 如代码中的逻辑
代码
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return bool布尔型
#
class Solution:
def isCompleteTree(self , root: TreeNode) -> bool:
# write code here
if not root: return True
stack=[root]
while stack:
tmp=stack[0]
stack.pop(0)
if tmp.right:
if tmp.left:
stack.append(tmp.left)
stack.append(tmp.right)
else:
return False
else:
if tmp.left:
stack.append(tmp.left)
break
while stack:
tmp=stack[0]
stack.pop(0)
if tmp.left or tmp.right:
return False
return True
BM 62 斐波那契数列
思路
- 思路1:按照公式循环计算。
- 思路2:递归的方式,如果直接使用递归会超时,使用一个字典记录已经计算过的值。
代码
- 代码1
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param n int整型 # @return int整型 # class Solution: def Fibonacci(self , n: int) -> int: # write code here if n==1 or n==2: return 1 fib_1=1 fib_2=1 fib_3=0 for i in range(2,n): fib_3=fib_1+fib_2 fib_1=fib_2 fib_2=fib_3 return fib_3
- 代码2
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param n int整型 # @return int整型 # class Solution: def __init__(self) -> None: # 用一个字典记录F(n)有没有计算过 self.f = dict() self.f[1]=1 self.f[2]=1 def Fibonacci(self , n: int) -> int: # write code here if n==1 or n==2: return self.f[n] else: if n-1 not in self.f: self.f[n-1]=self.Fibonacci(n-1) if n-2 not in self.f: self.f[n-2]=self.Fibonacci(n-2) return self.f[n-1]+self.f[n-2]
BM42 用两个栈实现队列
思路
- push:只往栈里1append
- pop:
- 如果栈2中有元素,那么从栈2中pop
- 如果栈2中没有元素,那么将栈1中的所有元素pop出,append进栈2中,然后从栈2中pop
代码
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
# write code here
self.stack1.append(node)
return
def pop(self):
if len(self.stack2)==0:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
BM43 包含min函数的栈
思路
- 两个栈
代码
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack=[]
self.minvalue=[]
def push(self, node):
# write code here
self.stack.append(node)
if not self.minvalue:
self.minvalue.append(node)
else:
if node<=self.minvalue[-1]:
self.minvalue.append(node)
else:
self.minvalue.append(self.minvalue[-1])
def pop(self):
# write code here
self.stack.pop()
self.minvalue.pop()
def top(self):
# write code here
return self.stack[-1]
def min(self):
# write code here
return self.minvalue[-1]
BM63 跳台阶
思路
- 递归
- 直接递归会超时
- 记忆化搜索
- 到底什么是递归?什么是动态规划?
代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param number int整型
# @return int整型
#
class Solution:
def __init__(self) -> None:
# 用一个字典记录F(n)有没有计算过
self.f = dict()
self.f[1]=1
self.f[2]=2
def jumpFloor(self , number: int) -> int:
# write code here
if number in self.f:
return self.f[number]
else:
self.f[number-1]=self.f[number-1] if number-1 in self.f else self.jumpFloor(number-1)
self.f[number-2]=self.f[number-2] if number-2 in self.f else self.jumpFloor(number-2)
return self.f[number-1]+self.f[number-2]
BM64
思路
- 最开始利用递归,使用代码2,但是
内存超限
- 然后使用gpt生成的代码1,利用for循环,成功
- 两个代码的不同:我是逆着考虑,gpt是正着考虑,不过不用for循环
- 嗯嗯,gpt比我聪明。。。。
代码
- 代码1
class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: n = len(cost) dp = [0] * n dp[0], dp[1] = cost[0], cost[1] for i in range(2, n): dp[i] = min(dp[i-1], dp[i-2]) + cost[i] return min(dp[n-1], dp[n-2])
- 代码2
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param cost int整型一维数组 # @return int整型 # class Solution: def __init__(self) -> None: self.eco={} def minCostClimbingStairs(self , cost: List[int]) -> int: # write code here if len(cost)<=1: self.eco[len(cost)]=0 return self.eco[len(cost)] elif len(cost)==2: self.eco[len(cost)]=min(cost[0],cost[1]) return self.eco[len(cost)] else: self.eco[len(cost[:-2])]=self.eco[len(cost[:-2])] if len(cost[:-2]) in self.eco else self.minCostClimbingStairs(cost[:-2]) self.eco[len(cost[:-1])]=self.eco[len(cost[:-1])] if len(cost[:-1]) in self.eco else self.minCostClimbingStairs(cost[:-1]) return min(self.eco[len(cost[:-2])]+cost[-2],self.eco[len(cost[:-1])]+cost[-1])