0. 赛后总结
昨天本来身体有点不舒服,就借口颓废了一整天,除了看剧啥事没干,想着比赛就算了吧,结果晚上还是没能逃过罪恶感,还是参加了一下,本来觉得就这状态估计要挂,结果居然打出了历史最好成绩,全球157名,国内51名,真的是意外之喜。
虽说周六的比赛参加的人比较少有点水分,但是终究也是一件开心的事,希望今天也可以保持这个状态!!!
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题的本质就是设计一个计数器来记录大中小三种类型的车位总数和已经使用了的车位数。
不过,由于要求实现的只有进车的函数,而没有出车的函数,所以事实上我们甚至不需要记录当前停的车的数目,只需要暴力地做一个简单的倒计时计数器即可,因为车位永远只会被消耗,不会被补充回去。
2. 代码实现
给出python代码实现如下:
class ParkingSystem:
def __init__(self, big: int, medium: int, small: int):
self.car = [big, medium, small]
def addCar(self, carType: int) -> bool:
if self.car[carType-1] == 0:
return False
else:
self.car[carType-1] -= 1
return True
提交代码评测得到:耗时128ms,占用内存14.4MB。为当前最优策略。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题的思路其实挺简单,就是看每个人有没有三个时间间隔小于1小时。
那么,我们只需要将每个人出门的所有的时间分离开之后分别进行排序,然后,依次来看每个人第 i i i个时间和第 i + 2 i+2 i+2个时间之间的时间间隔是否小于1小时即可。
2. 代码实现
给出python代码实现如下:
class Solution:
def alertNames(self, keyName: List[str], keyTime: List[str]) -> List[str]:
def str2time(t):
h, m = t.split(":")
return 60 * int(h) + int(m)
cache = defaultdict(list)
for name, time in zip(keyName, keyTime):
cache[name].append(str2time(time))
ans = []
for name, timelist in cache.items():
n = len(timelist)
timelist = sorted(timelist)
for i in range(n-2):
if timelist[i+2] - timelist[i] <= 60:
ans.append(name)
break
return sorted(ans)
提交代码后评测得到:耗时708ms,占用内存37.4MB。为当前最优策略。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题的关键就是构建一个可行的填充方法,然后逐步实现。
我们构建的填充方法为:
- 考察第i行和第j列,如果
rowSum[i] < colSum[j]
,则将第i行除了第j个元素之外全部置零,第j个元素置为rowSum[i]
,而后我们更新colSum[j]
的和为colSum[j] - rowSum[i]
(因为已经填充了一个元素),反之亦然。 - 通过上述方式,我们可以成功的消除掉一行或者一列,将问题化简为一个 ( r o w − 1 , c o l ) (row-1,col) (row−1,col)的矩阵或者 ( r o w , c o l − 1 ) (row,col-1) (row,col−1)的矩阵,不停地重复上述过程,就能最终将矩阵化简为一个单行或者单列的矩阵填充问题,从而问题得以解决。
2. 代码实现
给出python代码实现如下:
class Solution:
def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]:
n, m = len(rowSum), len(colSum)
ans = [[0 for _ in range(m)] for _ in range(n)]
def dp(i, j, rowSum, colSum):
if i == n-1:
for jj in range(j, m):
ans[i][jj] = colSum[jj]
return
if j == m-1:
for ii in range(i, n):
ans[ii][j] = rowSum[ii]
return
if rowSum[i] <= colSum[j]:
colSum[j] -= rowSum[i]
ans[i][j] = rowSum[i]
for jj in range(j+1, m):
ans[i][jj] = 0
rowSum[i] = 0
dp(i+1, j, rowSum, colSum)
else:
rowSum[i] -= colSum[j]
ans[i][j] = colSum[j]
colSum[j] = 0
for ii in range(i+1, n):
ans[ii][j] = 0
dp(i, j+1, rowSum, colSum)
dp(0, 0, rowSum, colSum)
return ans
提交代码评测得到:耗时816ms,占用内存26.1MB。
当前最优算法耗时708ms,但是看了一下代码思路,应该是一样的。因此,这里就不再多做展开了。
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这一题思路其实不难,就是在每一次请求的时候找到对应可用的服务器即可。问题在于怎么找到对应的服务器。
目标服务器是从第i%k
个服务器开始第一个可用的服务器。
因此,我们需要维护一个有序的可用的服务器列表,在每一次请求到达时,我们首先需要先释放之前所有的已经使用完毕的服务器,而后在可用的服务器列表中获取第一个大于等于i%k
的服务器,最后将这个服务器加入到使用中的服务器列表当中,并且标明释放时间。
故,我们需要存储的数据包括以下三个部分:
- 一个计数器,记录每个服务器运行的服务数量;
- 一个可用服务器列表,为了保证查找的快速性,我们需要令其有序;
- 一个运行中服务器列表,同样,为了确保每一次都能释放最早运行完成的服务器,我们需要令其针对释放时间排序,不过,鉴于我们不需要完全排序,因此,我们使用小顶堆结构进行数据储存。
2. 代码实现
给出最终的python代码实现如下:
import bisect
import heapq
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
counter = defaultdict(int)
avaliable_servers = [i for i in range(k)]
wording_servers = []
for i, (at, lt) in enumerate(zip(arrival, load)):
while wording_servers != [] and wording_servers[0][0] <= at:
_, s = heapq.heappop(wording_servers)
bisect.insort(avaliable_servers, s)
if avaliable_servers == []:
continue
idx = bisect.bisect_left(avaliable_servers, i % k)
if idx == len(avaliable_servers):
server = avaliable_servers.pop(0)
else:
server = avaliable_servers.pop(idx)
counter[server] += 1
heapq.heappush(wording_servers, (at+lt, server))
counter = sorted(counter.items(), key=lambda x: x[1], reverse=True)
return [x[0] for x in counter if x[1] == counter[0][1]]
提交代码之后评测得到:耗时1728ms,占用内存38.3MB。
由于当前还没有足够的提交结果,因此,暂时不知道这一个方案在所有方案中的性能比较。