LeetCode笔记:Weekly Contest 212 比赛记录

0. 赛后总结

这一次的比赛整体还算OK,虽然最后一题还是没能搞定,但终究也算是一次触底反弹吧,搞定了三题,国内排名165,世界排名520,算是一个比较满意的成绩了。

坦率地说最近从心理到生理都遇到了各种问题,这个虽然算不上是什么特别优秀的结果,但于我也终究多少是一个安慰了,也算是一整片黑夜中朦朦胧胧的一点光亮了。

唉,人生啊。。。

1. 题目一

给出题目一的试题链接如下:

1. 解题思路

这一题没啥好多说的,按照题目的意思计算出来每一次按键的时间,然后找到其中最大的一次操作输出其所按的按键即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def slowestKey(self, releaseTimes: List[int], keysPressed: str) -> str:
        n = len(releaseTimes)
        rt = [(releaseTimes[i], keysPressed[i]) if i == 0 else (releaseTimes[i]-releaseTimes[i-1], keysPressed[i]) for i in range(n)]
        return max(rt)[1]

提交代码评测得到:耗时60ms,占用内存14.3MB。

当前最优的方案耗时36ms,但是思路来说是完全相同的,这里就不过多展开了。

2. 题目二

给出题目二的试题链接如下:

1. 解题思路

这一题从思路上来说也同样没有什么弯弯绕绕,同样就是取出每一个query所对应的子序列,然后判断它是否是一个等差数列。

2. 代码实现

给出python代码实现如下:

class Solution:
    def checkArithmeticSubarrays(self, nums: List[int], l: List[int], r: List[int]) -> List[bool]:
        def is_arithmetic(arr):
            n = len(arr)
            return all(arr[i+1] - arr[i] == arr[1] - arr[0] for i in range(n-1))
        
        ans = []
        for ll, rr in zip(l, r):
            ans.append(is_arithmetic(sorted(nums[ll: rr+1])))
        return ans

提交代码评测得到:耗时200ms,占用内存14.4MB。

当前最优的代码实现耗时168ms,但是同样从思路上来说是完全一致的,因此这里就不再过多展开了。

3. 题目三

给出题目三的试题链接如下:

1. 解题思路

这一题的模式在leetcode当中已经出现过很多次了,整体的思路就是一个dfs的遍历方式。

但是,由于一个点可以有多条路径走到,我们采用扩张的方式不断地向外走:

  • 每次走到一个点时,将其临近的点中没有走过的点加入到待走队列当中;
  • 都从已走过的点当中找到临近点当中所需能量最小的点来作为下一个要走的点。

为了确保每次走的点都是能量所需最少的点,我们对队列维持一个堆结构,从而确保每一次每一次走的点都是能量最小的点。

2. 代码实现

给出python代码实现如下:

import heapq
class Solution:
    def minimumEffortPath(self, heights: List[List[int]]) -> int:
        n = len(heights)
        m = len(heights[0])
        dp = [[0 for _ in range(m)] for _ in range(n)]
        q = [(0,0,0)]
        have_seen = set()
        while q:
            c, i, j = heapq.heappop(q)
            if (i, j) in have_seen:
                continue
            else:
                have_seen.add((i, j))
            if i == n-1 and j == m-1:
                return c
            if i-1 >= 0 and (i-1, j) not in have_seen:
                heapq.heappush(q, (max(c, abs(heights[i][j] - heights[i-1][j])), i-1, j))
            if i+1 < n and (i+1, j) not in have_seen:
                heapq.heappush(q, (max(c, abs(heights[i][j] - heights[i+1][j])), i+1, j))
            if j-1 >= 0 and (i, j-1) not in have_seen:
                heapq.heappush(q, (max(c, abs(heights[i][j] - heights[i][j-1])), i, j-1))
            if j+1 < m and (i, j+1) not in have_seen:
                heapq.heappush(q, (max(c, abs(heights[i][j] - heights[i][j+1])), i, j+1))
        return 0

提交代码评测得到:耗时620ms,占用内存16.5MB,为当前最优代码实现。

4. 题目四

给出题目四的试题链接如下:

1. 解题思路

这一题比赛的时候其实感觉还好,思路还算是挺清楚的,可惜没有搞出来,赛后也是遇到了一堆的问题,主要就是相同大小的值的秩的处理上,先是遇到了一些bug,后面修复之后又遇到了超时问题,虽然最终是搞定了,但是整个代码就显得比较繁琐。

但是总体来说,这一题的思路还是比较清晰的,看了一下头几名的几位大佬们的思路,没细看他们的代码(因为也都挺多挺复杂的),感觉应该是没有什么特别简单的方法了。

下面,给出我们的思路如下:

  1. 取出矩阵中所有的元素及其坐标,并对其进行排序;
  2. 记录每一行每一列中当前最大的秩(初始化为0);
  3. 依次取出1中得到的序列中的每一个元素,则他的秩就是其所在行和列中最大的秩加上一,并同步更新改行以及该列中当前最大的秩;
  4. 重复上述步骤即可得到最终的秩的表格。

但是,这里需要注意的是:相同大小的值需要同时取出进行处理,因为他们之间会相互影响,导致其秩的选择不能仅看其单一坐标所处的行和列,具体规则包括:

  1. 如果有两个点的行或者列相同,则这两个点必须的秩必须相同,因此,我们需要对其取更大的那个值;
  2. 如果两个点行和列都不相同,且不会通过任何其他点进行关联,则他们的秩可以不同。

有关这部分的代码实现,最后我们是采用了dsu的方式进行实现,总算是没有再导致超时情况,但是不清楚是否会有更好的解决方案。

2. 代码实现

给出我们最终的python代码实现如下:

class DSU:
    def __init__(self, n, nums):
        self.dsu = [i for i in range(n)]
        self.val = [v for v in nums]
        
    def find(self, x):
        if self.dsu[x] == x:
            return x
        self.dsu[x] = self.find(self.dsu[x])
        return self.dsu[x]
    
    def union(self, x, y):
        xr = self.find(x)
        yr = self.find(y)
        self.dsu[yr] = xr
        self.val[xr] = max(self.val[xr], self.val[yr])
        return
    
    def getval(self, x):
        return self.val[self.find(x)]
    
class Solution:
    def matrixRankTransform(self, matrix: List[List[int]]) -> List[List[int]]:
        n = len(matrix)
        m = len(matrix[0])
        rank = [[0 for _ in range(m)] for _ in range(n)]
        elems = [[matrix[i][j], i, j] for i in range(n) for j in range(m)]
        elems = sorted(elems)
        
        i = 0
        N = len(elems)
        rows = [0 for _ in range(n)]
        cols = [0 for _ in range(m)]
        while i < N:
            flag = elems[i][0]
            candidates = []
            while i < N and elems[i][0] == flag:
                e, r, c = elems[i]
                candidates.append([max(rows[r], cols[c])+1, r, c])
                i += 1
            M = len(candidates)

            def update_candidates(candidates):
                n = len(candidates)
                status = [False for _ in range(n)]
                dsu = DSU(n, [x[0] for x in candidates])
                row_batch = defaultdict(list)
                col_batch = defaultdict(list)
                for i in range(n):
                    row_batch[candidates[i][1]].append(i)
                    col_batch[candidates[i][2]].append(i)
                for batch in row_batch.values():
                    for i in range(len(batch)-1):
                        dsu.union(batch[i], batch[i+1])
                for batch in col_batch.values():
                    for i in range(len(batch)-1):
                        dsu.union(batch[i], batch[i+1])       
                for i in range(n):
                    candidates[i][0] = dsu.getval(i)
                return candidates

            if len(candidates) > 1:
                candidates = update_candidates(candidates)
            
            for r, ii, jj in candidates:
                rank[ii][jj] = r
                rows[ii] = r
                cols[jj] = r
        return rank

提交代码评测得到:耗时1880ms,占用内存56MB。

当前还没有足够的提交记录,因此暂时不知道其他有没有更好的解题方案,如果后续读者有兴趣的话,可以自行去leetcode上面去看一下,过段时间应该就会有其他的方案可以查询了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值