LeetCode笔记:Weekly Contest 318

1. 题目一

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

1. 解题思路

这一题思路上很简单,就是用一个for循环按照题意逐一操作一下,然后重新排个序即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def applyOperations(self, nums: List[int]) -> List[int]:
        n = len(nums)
        for i in range(n-1):
            if nums[i] == nums[i+1]:
                nums[i] = nums[i] * 2
                nums[i+1] = 0
        res = [x for x in nums if x != 0] + [x for x in nums if x == 0]
        return res

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

2. 题目二

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

1. 解题思路

这一题我的思路就是维护一个滑动窗口,然后查看长度为k的滑动窗口之中的unique元素个数是否为k,如果为k,计算其和值然后返回最大值。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumSubarraySum(self, nums: List[int], k: int) -> int:
        n = len(nums)
        cnt = Counter(nums[:k])
        _sum = sum(nums[:k])
        res = 0 if len(cnt) < k else _sum
        for i in range(k, n):
            _sum += nums[i] - nums[i-k]
            cnt[nums[i]] += 1
            cnt[nums[i-k]] -= 1
            if cnt[nums[i-k]] == 0:
                cnt.pop(nums[i-k])
            if len(cnt) == k:
                res = max(res, _sum)
        return res

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

3. 题目三

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

1. 解题思路

这一题同样我的思路是使用一个滑动窗口来控制每一轮当中的候选人池。

而这个候选人池子本身,我们使用一个堆排数组进行数据存储,从而可以以 O ( 1 ) O(1) O(1)的时间复杂度获取每一轮被雇佣的worker。

2. 代码实现

给出python代码实现如下:

class Solution:
    def totalCost(self, costs: List[int], k: int, candidates: int) -> int:
        n = len(costs)
        q = []
        for i in range(candidates):
            heapq.heappush(q, (costs.pop(), n-1-i))
        for i in range(candidates):
            if costs == []:
                break
            heapq.heappush(q, (costs.pop(0), i))

        res = 0
        lb, rb = candidates, n-1-candidates
        for i in range(k):
            x, idx = heapq.heappop(q)
            res += x
            if costs == []:
                continue
            if idx < lb:
                heapq.heappush(q, (costs.pop(0), lb))
                lb += 1
            else:
                heapq.heappush(q, (costs.pop(), rb))
                rb -= 1
        return res

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

4. 题目四

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

1. 解题思路

这一题我一开始没有搞定,后来是看了大佬们的解答之后才找到的思路,从而搞定的。

整体思路上来说,一个比较显然的点就是,机器人的终点之间不会存在交叉,也就是说,如果两个机器人都往左走,那么更右侧的机器人抵达的终点也一定更靠右侧,这个构造方式是显然的,因为如果存在交叉,那我们将他们的终点互换即可,不会影响总的距离。

因此,我们首先将机器人与工厂进行排序,然后只需要考察每一个工厂当中分配几个机器人抵达即可,而这个问题就可以比较简单的划归为一个动态规划的问题了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimumTotalDistance(self, robot: List[int], factory: List[List[int]]) -> int:
        cnt = {k: v for k, v in factory}
        factory = sorted([x[0] for x in factory])     
        cnt = [cnt[x] for x in factory]
        robot = sorted(robot)
        n, m = len(robot), len(factory)
        
        distances = [[abs(r-f) for r in robot] for f in factory]
        costs = [[0] + list(accumulate(d)) for d in distances]
        
        @lru_cache(None)
        def dp(fid, pre):
            if pre == n:
                return 0
            if fid == m:
                return 0 if pre == n else math.inf
            return min(costs[fid][pre+i] - costs[fid][pre] + dp(fid+1, pre+i) for i in range(min(cnt[fid], n-pre) + 1))
        
        return dp(0, 0)

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

  • 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、付费专栏及课程。

余额充值