文章目录
03. 数组中重复的数字 简单
题目链接
分析
题目难度为简单,最直白的方法就是开辟哈希表记录访问过的数字。
此题可以做到 O ( 1 ) O(1) O(1),利用题目中的信息,一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
假设n为5,按照题意给定一个没有重复数字的数组
index | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
data | 3 | 1 | 4 | 2 | 0 |
可以看到,数据本身是索引的一个置换(题目给的信息),数据本身也可以当索引来用
一个有重复数字的数组
index | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
data | 3 | 4 | 4 | 0 | 2 |
如果把数据当索引来用,一定会出现重复访问,要做的就是记录已经访问的数据。
code
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
for i in range(len(nums)):
# i是原索引,abs(nums[i])是数据,这里当作新索引来用
# 若出现重复访问,返回答案
if nums[abs(nums[i])] < 0:
return abs(nums[i])
else:
# 次数使用原数据的负数来表示,该数据已经被访问
nums[abs(nums[i])] = -1 * nums[abs(nums[i])]
# 到了这一步,重复数字是一定0
return 0
04. 二维数组中的查找
分析
没啥可讲的,想通了就通了
code
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
if not matrix or not matrix[0]:
return False
rowIndex, colIndex = 0, len(matrix[0])-1
while rowIndex < len(matrix) and colIndex >=0:
if matrix[rowIndex][colIndex] == target:
return True
elif matrix[rowIndex][colIndex] > target:
colIndex -= 1
else:
rowIndex += 1
return False
07. 重建二叉树
分析
给定前序遍历和中序遍历的结果能确定一颗唯一的二叉树。
关键在于能根据二叉树的前序遍历和中序遍历,确定左右子树的前序遍历和中序遍历。code时唯一要注意的就是何时递归结束。
code
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if not preorder:
return None
def zp_buildTree(preorder: list, pr_l, pr_r, inorder: list, in_l, in_r):
if pr_l > pr_r or in_l > in_r:
return None
root = TreeNode(preorder[pr_l]) # 构建根结点
root_index = inorder.index(preorder[pr_l]) # 找到根结点在中序的位置
L = root_index - in_l
R = in_r - root_index # 左右子树的长度
root.left = zp_buildTree(preorder, pr_l+1, pr_l+L, inorder, in_l, root_index-1)
root.right = zp_buildTree(preorder, pr_l+L+1, pr_r, inorder, root_index+1, in_r)
return root
return zp_buildTree(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1)
08:二叉树的下一个节点
牛客
分析
这里题目要求是中序遍历(左中右)的下一个节点。
不用关系p是否有左子树,中序遍历中,p的左子树一定都在p前面
给定节点p,若p有右子树,p在中序遍历中的下一个节点就是自己右子树中序遍历结果的第一个节点。
若p没有右子树,那么p右两种可能:
1,p是某棵子树的左子树,p在中序遍历中的下一个节点就是自己的父节点
2,p是某棵子树的右子树,这就要一直向上寻找p的父节点,祖父节点等等(广义上都是父节点)。何时截止,直到当前这个父节点表示的子树是某棵树的左子树,那么下一个父节点就是p在中序遍历中的下一个节点。
使用非递归算法中序遍历遍历一遍二叉树,这个过程就很清楚了。
code
class Solution:
def GetNext(self, p):
# write code here
if p.right:
p = p.right
while p.left:
p = p.left
return p
while p.next and p.next.right == p:
p = p.next
return p.next
09-1. 用两个栈实现队列
分析
这里的栈,只支持栈尾 push 和 pop,python的列表虽然有pop(0)这个功能,但这里不能用。
code
class CQueue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def appendTail(self, value: int) -> None:
self.stack1.append(value)
def deleteHead(self) -> int:
if not self.stack1 and not self.stack2:
return -1
elif self.stack2:
return self.stack2.pop()
else:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop