LeetCode笔记:Biweekly Contest 63

1. 题目一

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

1. 解题思路

这一题思路挺直接的,我们直接对座位和学生位置进行排序,然后逐位取差值即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minMovesToSeat(self, seats: List[int], students: List[int]) -> int:
        seats = sorted(seats)
        students = sorted(students)
        return sum(abs(x-y) for x, y in zip(seats, students))

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

2. 题目二

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

1. 解题思路

这一题由于要求只能够取连续的元素中间的位置,因此,我们只需要统计连续的A和B的个数即可得到Alice以及Bob可做的操作数目。

然后我们比较这两个数的大小关系即可得到最终的胜负关系。

2. 代码实现

给出python代码实现如下:

class Solution:
    def winnerOfGame(self, colors: str) -> bool:
        
        def count(ch):
            pre = ""
            cnt = 0
            res = 0
            for c in colors:
                if c != pre:
                    if pre == ch and cnt > 2:
                        res += cnt - 2
                    pre = c
                    cnt = 1
                else:
                    cnt += 1
            if pre == ch and cnt > 2:
                res += cnt-2
            return res

        a, b = count("A"), count("B")
        return a > b

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

3. 题目三

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

1. 解题思路

这一题我们只需要考察每一个网络节点的活跃时间,然后求出其中最大的值就是网络空闲前的最后一刻,然后+1即是我们所需的答案。

而对于每一个节点的活跃时间的计算,我们首先计算出这个节点到中心节点的距离,然后他的信号发送会重复到第一次信号发送并传回的时间,即距离的两倍,由此我们可以找到最后一个信号发送的时间点,然后加上单次信号发送到传回的时间,即是这个节点活跃的时间。

2. 代码实现

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

class Solution:
    def networkBecomesIdle(self, edges: List[List[int]], patience: List[int]) -> int:
        n = len(patience)
        
        graph = defaultdict(list)
        for u, v in edges:
            graph[u].append(v)
            graph[v].append(u)

        distance = [0 for _ in range(n)]
        q = [(0, 0)]
        idx, m = 0, 1
        seen = {0}
        while idx < m:
            u, d = q[idx]
            distance[u] = d
            for v in graph[u]:
                if v not in seen:
                    q.append((v, d+1))
                    seen.add(v)
                    m += 1
            idx += 1
        
        def cal_last_time(d, p):
            if p == 0:
                return 0
            t = d * 2
            last = ((t-1) // p) * p
            return last + t
        return max(cal_last_time(d, p) for d, p in zip(distance, patience))+1

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

4. 题目四

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

1. 解题思路

这一题的做法我其实借鉴了网上其他大佬们的解题思路。

思路上而言,就是一个二分查找,首先找到可能的乘积的最大值与最小值,然后使用二分查找分别计算对于某一个数可以找到的乘积对的数目 f ( x ) f(x) f(x)

f ( x ) > = k f(x) >= k f(x)>=k f ( x − 1 ) < k f(x-1) < k f(x1)<k时,x即为我们最终所需要的解。

而对于 f ( x ) f(x) f(x)的计算,我们同样可以通过二分查找进行优化。

2. 代码实现

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

class Solution:
    def kthSmallestProduct(self, nums1: List[int], nums2: List[int], k: int) -> int:
        n, m = len(nums1), len(nums2)

        if n > m:
            return self.kthSmallestProduct(nums2, nums1, k)

        def get_interval():
            s = [nums1[0] * nums2[0], nums1[0] * nums2[-1], nums1[-1] * nums2[0], nums1[-1] * nums2[-1]]
            return min(s), max(s)

        def is_kth(val):
            cnt = 0
            for x in nums1:
                if x == 0:
                    cnt = cnt if val < 0 else cnt + m
                elif x < 0:
                    tgt = math.ceil(val / x)
                    cnt += m - bisect.bisect_left(nums2, tgt)
                else:
                    tgt = val // x
                    cnt += bisect.bisect_right(nums2, tgt)
                if cnt >= k:
                    return 1
            return -1


        i, j = get_interval()
        if is_kth(i) >= 0:
            return i
        while i < j-1:
            val = (i+j) // 2
            status = is_kth(val)
            if status == 1:
                j = val
            else:
                i = val
        return j

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值