3月17号:笔试复盘
第一道笔试题:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram
当时写这题的时候,没太看懂这个题目的意思,以为只是相邻的两个矩形找到最大值,那我可以通过前面不断叠加成一个新的列表,拿到新列表中的最大值的当前索引,再根据指针判断前后大小。
但后来当我看到[0,2,0]的时候我发现我想错了,因为面积还可以这样:
然后发现这题目的意思是求矩阵最大面积。。。(哭),终于看清了题目,也懂了思路:
按照上图所示,首先第一层是遍历当前列表,然后遍历到的值为当前矩阵的高,那么根据当前高,引用双指针right和left,从左走找到第一个比其小的列,往右同理,那么根据矩形面积公式,底*高 = (heights[right] - heights[left] - 1) * heights[i].最后在找到最大值。
所以代码为:
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
res = 0
n = len(heights)
for i in range(n):
left_i = i
right_i = i
while left_i >= 0 and heights[left_i] >= heights[i]:
left_i -= 1
while right_i < n and heights[right_i] >= heights[i]:
right_i += 1
res = max(res,(right_i - left_i - 1) * heights[i])
return res
但发现有超时,所以我们换一种思路,利用栈来解决,因为当我们找 i 左边第一个小于 heights[i] 如果 heights[i-1] >= heights[i] 其实就是和 heights[i-1] 左边第一个小于 heights[i-1] 一样。依次类推,右边同理。
def maximalRectangle( matrix):
if matrix == [] or matrix[0] == []:
return 0
ans = 0
height = [0] * (len(matrix[0]) + 1)
for row in matrix:
for i in range(len(row)):
height[i] = height[i] + 1 if row[i] == '1' else 0
stack = [-1]
for i in range(len(height)):
while height[i] < height[stack[-1]]:
index = stack.pop()
h = height[index]
w = i - stack[-1] - 1
ans = max(ans, h * w)
stack.append(i)
return ans
第二道笔试题:
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 “[1,2,3,null,null,4,5]”
提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
res = ''
if not root:
return res
node_pool = [root]
res = str(root.val)
while node_pool:
tmp = []
for node in node_pool:
if not node.left:
res += ',' + 'null'
else:
res += ',' + str(node.left.val)
tmp.append(node.left)
if not node.right:
res += ',' + 'null'
else:
res += ',' + str(node.right.val)
tmp.append(node.right)
node_pool = tmp
print(res)
return res
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if not data:
return None
str_set = data.split(',')
res = TreeNode(int(str_set[0]))
node_pool = [res]
ptr = 1
nums = 2
while ptr < len(str_set):
child_pool = []
child_set = str_set[ptr:ptr+nums]
for i, node in enumerate(node_pool):
if child_set[2*i] != 'null':
node.left = TreeNode(int(child_set[2*i]))
child_pool.append(node.left)
if child_set[2*i + 1] != 'null':
node.right = TreeNode(int(child_set[2*i+1]))
child_pool.append(node.right)
ptr += nums
nums = 2 * len(child_pool)
node_pool = child_pool
return res
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
当时有些测试用例没通过,现在大概看懂了,另外还有第三题是将二叉搜索树变平衡,我发现连题目都看不懂,现在看起来还是没啥感觉。。。先略过
面试大概范围:
- flask项目部署流程? gunicorn与gevent对flask项目进行部署总结
- 三次握手四次挥手以及一系列网络通信流程?网络通信面试题详细解答
- RNN的原理以及应用方面?文本分词与循环神经网络笔记
不过这部分内容我并没有写完,事后发现他应该是问seq2seq和attention
3月19日:链表的中间结点和
给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
"""
转换成数组是一种最直接的方式
"""
def middleNode(self,head:ListNode) -> ListNode:
a = [head]
while a[-1].next:
a.append(a[-1].next)
return a[len(a)//2]
class Solution:
"""
快慢指针的方式
"""
def middleNode(self, head: ListNode) -> ListNode:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
这个可以想到另一题:环形链表
class Solution(object):
def hasCycle(self, head):
slow = fast = head
while slow and fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False