# ========================25 合并两个排序的链表===================================
#答案的版本
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
cur = dum = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
cur.next, l1 = l1, l1.next
else:
cur.next, l2 = l2, l2.next
cur = cur.next
cur.next = l1 if l1 else l2
return dum.next
#我写的版本
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 == None:
return l2
if l2 == None:
return l1
ill = ListNode(0) #(1)
cur = ill #(2)
##(1)(2)处不能写成 ill = ListNode(0) cur = ListNode(0) 否则会报错。
while l1 and l2:
if l1.val <= l2.val:
cur.next = l1
l1 = l1.next
cur = cur.next
if l2.val < l1.val:
cur.next = l2
l2 = l2.next
cur = cur.next
if l1 == None:
cur.next = l2
if l2 == None:
cur.next = l1
return ill.next
# =============================================================================
# ===========09 两个栈实现队列===================================================
#这是答案
class CQueue:
def __init__(self):
self.A, self.B = [], []
def appendTail(self, value: int) -> None:
self.A.append(value)
def deleteHead(self) -> int:
if self.B:
return self.B.pop()
if not self.A:
return -1
while self.A:
self.B.append(self.A.pop())
return self.B.pop()
#这是我的版本,我也不知道为什么出错了....
class CQueue:
def __init__(self):
self.s1 = []
self.B = []
def appendTail(self, value: int) -> None:
self.s1.append(value)
def deleteHead(self) -> int:
if self.s1 == None:
return -1
if self.B:
return self.B.pop()
while self.s1 :
a = self.s1.pop()
self.B.append(a)
return self.B.pop()
#这是牛客网上的版本,同样的代码在力扣上就运行出错。我也不知道为什么
class Solution:
def __init__(self):
self.stack1,self.stack2=[],[]
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
# return xx
if self.stack2: #如果非空,则执行下面的操作
return self.stack2.pop()
elif not self.stack1: #如果是空的,则返回None
return None
else:
while self.stack1: #如果非空,则执行下面的操作
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
# =============================================================================
# =================57 II和为s的连续正整数序列=====================================
#滑动窗口一般是左闭右开区间。且开始时i = 1;j = 1;sum = 0
def findContinuousSequence(self, target: int) -> List[List[int]]:
i = 1 # 滑动窗口的左边界
j = 1 # 滑动窗口的右边界
sum = 0 # 滑动窗口中数字的和
res = []
while i <= target // 2: #注意一下,这里是<=而不是<
if sum < target:
# 右边界向右移动
sum += j
j += 1
elif sum > target:
# 左边界向右移动
sum -= i
i += 1
else:
# 记录结果
arr = list(range(i, j)) #注意一下,先记录数据然后sum再减少
res.append(arr)
# 左边界向右移动
sum -= i
i += 1
return res
# =============================================================================
# ========68-II二叉树的最近公共祖先****(不太明白算法实现)=============================
'''
最近公共祖先的定义: 设节点 rootroot 为节点 p, q的某公共祖先,
若其左子节点root.leftroot.left 和右子节点 root.rightroot.right 都不是 p,q 的公共祖先,
则称 rootroot 是 “最近的公共祖先”。
'''
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or root == p or root == q: #先考虑根节点的情况
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left:
return right
if not right:
return left
return root
# =============================================================================
# ==============68-I二叉搜索树的最近公共祖先=======================================
#可以用68-II的程序,也可以用下面的这个
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val < p.val and root.val < q.val: # p,q 都在 root 的右子树中
root = root.right # 遍历至右子节点
elif root.val > p.val and root.val > q.val: # p,q 都在 root 的左子树中
root = root.left # 遍历至左子节点
else: break
return root
# =============================================================================
# ===============39 数组中出现次数超过一半的数字====================================
#这是我写的代码
class Solution:
def majorityElement(self, nums: List[int]) -> int:
res = {}
temp = []
lenth = len(nums)
for i in nums:
if i in temp:
res[i] += 1
else:
res[i] = 1
temp.append(i)
for i in temp:
if res[i] > lenth // 2:
return i
# =============================================================================
# ===================32-II从上到下打印二叉树II====================================
#从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
'''
按层打印: 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。BFS 通常借助 队列 的先入先出特性来实现。
'''
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res, queue = [], collections.deque() #deque(双端队列)是一个数据结构。collections是一个模块
#res 是打印结果的列表 queue是储存每一层节点的队列
queue.append(root) #首先把根加进去
##初始化,queue是一个包含根节点的双端队列
while queue:
tmp = [] #创建一个临时的列表,保存当前层的节点
for _ in range(len(queue)):
# _表示占位符 不会打印出指标值,仅仅表示要循环range次
node = queue.popleft()
tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(tmp)
return res
# https://www.bilibili.com/video/BV1vQ4y1M7wv/ 这道题的视频讲解
# =============================================================================
# ============03 数组中重复的数字=================================================
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
res = {}
for i in nums:
if i in res:
res[i] += 1
else:
res[i] = 1
fanhui = []
for i in nums:
if res[i] >= 2:
return i
# =============================================================================
# ===============50 第一个只出现一次的字符=========================================
class Solution:
def firstUniqChar(self, s: str) -> str:
sNew = list(s)
if not sNew:
return ' '
res = {}
for i in sNew:
if i in res:
res[i] += 1
else:
res[i] = 1
for i in sNew:
if res[i] == 1:
return ''.join(i)
temp = []
for i in sNew:
if res[i] == 1:
temp.append(i)
if not temp:
return ' '
# =============================================================================
# ===================65 不用加减乘除做加法========================================
class Solution:
def add(self, a: int, b: int) -> int:
c = []
c.append(a)
c.append(b)
d = sum(c)
return d
# =============================================================================
# ==============57 和为s的两个数字===============================================
#答案
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
i, j = 0, len(nums) - 1
while i < j:
s = nums[i] + nums[j]
if s > target:
j -= 1
elif s < target:
i += 1
else:
return nums[i], nums[j]
return []
#我写的版本,但是会输出null,也不知道为什么
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
res = []
n = len(nums)
temp1 = []
temp2 = []
for k in range(n - 1):
for i in range(1,n):
sumN = nums[k] + nums[i]
res.append(sumN)
temp1 = k,i
temp1 = list(temp1)
temp2.append(temp1)
for i in range(n * (n - 1)// 2):
if res[i] == target:
a = temp2[i][0]
b = temp2[i][1]
return nums[a],nums[b]
# =============================================================================
# ==============62 圆圈中剩下的最后一个字==========================================
'''
模拟整个删除过程最直观,即构建一个长度为 nn 的链表,各节点值为对应的顺序索引;每轮删除第 mm 个
节点,直至链表长度为 1 时结束,返回最后剩余节点的值即可。
'''
#这是一道数学问题,我还没有看明白
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
x = 0
for i in range(2, n + 1):
x = (x + m) % i
return x
#=============================================================================
#==============21 调整数组顺序使得奇数位于偶数前面==================================
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
i, j = 0, len(nums) - 1
while i < j:
while i < j and nums[i] % 1 == 1: #奇数
i += 1
while i < j and nums[j] % 1 == 0: #偶数
j -= 1
nums[i], nums[j] = nums[j], nums[i]
return nums #这一行是和while并列的
# =============================================================================
# ==========52 两个链表的第一个公共节点============================================
#牛客网的版本.但是在力扣上运行错误,因为力扣上要求输出一个ListNode
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
p1 = headA
p2 = headB
if p1 == None or p2 == None:
return None
stack1 = []
stack2 = []
while p1:
stack1.append(p1)
p1 = p1.next
while p2:
stack2.append(p2)
p2 = p2.next
re = None
while stack1 and stack2:
s1jqnum = stack1.pop()
s2jqnum = stack2.pop()
if s1jqnum == s2jqnum:
return s1jqnum
#力扣上的版本
'''
a+(b-c)=b+(a-c)
超级聪明
'''
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
node1, node2 = headA, headB
while node1 != node2:
if node1:
node1 = node1.next
else:
node1 = headB
if node2:
node2 = node2.next
else:
node2 = headA
return node1
# =============================================================================
# ============46 连续子数组的最大和===============================================
#答案
#这个方法太奇妙了
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
for i in range(1, len(nums)):
nums[i] += max(nums[i - 1], 0)
return max(nums)
#我写的暴力计算,但是超出了时间限制
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
sumList = []
for i in range(len(nums)):
sumN = 0
for j in range(i,len(nums)):
sumN += nums[j]
sumList.append(sumN)
re = max(sumList)
return re
# =============================================================================