令人头秃的代码日记--第308场周赛迟到一个多小时通过3题

159 阅读4分钟

迟到了一个多小时,通过3题,还算ok,第四题看了,是真不会,打卡做饭去了。

一、和有限的最长子序列

给你一个长度为 n 的整数数组 nums ,和一个长度为 m 的整数数组 queries 。

返回一个长度为 m 的数组 **answer **,其中 **answer[i] **是 nums 中 元素之和小于等于 queries[i] 的 子序列 的 最大 长度  。

子序列 是由一个数组删除某些元素(也可以不删除)但不改变剩余元素顺序得到的一个数组。

 

示例 1:

输入: nums = [4,5,2,1], queries = [3,10,21]
输出: [2,3,4]
解释: queries 对应的 answer 如下:
- 子序列 [2,1] 的和小于或等于 3 。可以证明满足题目要求的子序列的最大长度是 2 ,所以 answer[0] = 2 。
- 子序列 [4,5,1] 的和小于或等于 10 。可以证明满足题目要求的子序列的最大长度是 3 ,所以 answer[1] = 3 。
- 子序列 [4,5,2,1] 的和小于或等于 21 。可以证明满足题目要求的子序列的最大长度是 4 ,所以 answer[2] = 4

示例 2:

输入: nums = [2,3,4,5], queries = [1]
输出: [0]
解释: 空子序列是唯一一个满足元素和小于或等于 1 的子序列,所以 answer[0] = 0

 

提示:

  • n == nums.length
  • m == queries.length
  • 1 <= n, m <= 1000
  • 1 <= nums[i], queries[i] <= 10^6

解析

乍一看好像很麻烦,但是一想,子序列改不改变顺序好像影响不大,只需要把原数组从小到大排序之后,求一个前缀和即可。

代码

from sortedcontainers import SortedList
class Solution:
    def answerQueries(self, nums: List[int], queries: List[int]) -> List[int]:
        nums = sorted(nums)
        pre_sum = []
        for index, n in enumerate(nums):
            if index == 0:
                pre_sum.append(n)
            else:
                pre_sum.append(pre_sum[-1] + n)
        pre_sum = SortedList(pre_sum)
        answers = []
        for m in queries:
            answers.append(pre_sum.bisect_right(m))
        print(answers)
        return(answers)

二、从字符串中移除星号

给你一个包含若干星号 * 的字符串 s 。

在一步操作中,你可以:

  • 选中 s 中的一个星号。
  • 移除星号 左侧 最近的那个 非星号 字符,并移除该星号自身。

返回移除 所有 星号之后的字符串

注意:

  • 生成的输入保证总是可以执行题面中描述的操作。
  • 可以证明结果字符串是唯一的。

 

示例 1:

输入: s = "leet**cod*e"
输出: "lecoe"
解释: 从左到右执行移除操作:
- 距离第 1 个星号最近的字符是 "leet**cod*e" 中的 't' ,s 变为 "lee*cod*e" 。
- 距离第 2 个星号最近的字符是 "lee*cod*e" 中的 'e' ,s 变为 "lecod*e" 。
- 距离第 3 个星号最近的字符是 "lecod*e" 中的 'd' ,s 变为 "lecoe" 。
不存在其他星号,返回 "lecoe"

示例 2:

输入: s = "erase*****"
输出: ""
解释: 整个字符串都会被移除,所以返回空字符串。

 

提示:

  • 1 <= s.length <= 10^5
  • s 由小写英文字母和星号 * 组成
  • s 可以执行上述操作

解析

一道基础的操作模拟类的题目,采用栈即可完成,非星号入栈,星号出栈

代码

class Solution:
    def removeStars(self, s: str) -> str:
        stack = []
        for x in s:
            if x != "*":
                stack.append(x)
            else:
                stack.pop()
        if stack:
            return "".join(i for i in stack)
        else:
            return ""

三、收集垃圾最少得时间

给你一个下标从 0 开始的字符串数组 garbage ,其中 garbage[i] 表示第 i 个房子的垃圾集合。garbage[i] 只包含字符 'M' ,'P' 和 'G' ,但可能包含多个相同字符,每个字符分别表示一单位的金属、纸和玻璃。垃圾车收拾  单位的任何一种垃圾都需要花费 1 分钟。

同时给你一个下标从 0 开始的整数数组 travel ,其中 travel[i] 是垃圾车从房子 i 行驶到房子 i + 1 需要的分钟数。

城市里总共有三辆垃圾车,分别收拾三种垃圾。每辆垃圾车都从房子 0 出发,按顺序 到达每一栋房子。但它们 不是必须 到达所有的房子。

任何时刻只有 一辆 垃圾车处在使用状态。当一辆垃圾车在行驶或者收拾垃圾的时候,另外两辆车 不能 做任何事情。

请你返回收拾完所有垃圾需要花费的 最少 总分钟数。

 

示例 1:

输入: garbage = ["G","P","GP","GG"], travel = [2,4,3]
输出: 21
解释:
收拾纸的垃圾车:
1. 从房子 0 行驶到房子 1
2. 收拾房子 1 的纸垃圾
3. 从房子 1 行驶到房子 2
4. 收拾房子 2 的纸垃圾
收拾纸的垃圾车总共花费 8 分钟收拾完所有的纸垃圾。
收拾玻璃的垃圾车:
1. 收拾房子 0 的玻璃垃圾
2. 从房子 0 行驶到房子 1
3. 从房子 1 行驶到房子 2
4. 收拾房子 2 的玻璃垃圾
5. 从房子 2 行驶到房子 3
6. 收拾房子 3 的玻璃垃圾
收拾玻璃的垃圾车总共花费 13 分钟收拾完所有的玻璃垃圾。
由于没有金属垃圾,收拾金属的垃圾车不需要花费任何时间。
所以总共花费 8 + 13 = 21 分钟收拾完所有垃圾。

示例 2:

输入: garbage = ["MMM","PGM","GP"], travel = [3,10]
输出: 37
解释:
收拾金属的垃圾车花费 7 分钟收拾完所有的金属垃圾。
收拾纸的垃圾车花费 15 分钟收拾完所有的纸垃圾。
收拾玻璃的垃圾车花费 15 分钟收拾完所有的玻璃垃圾。
总共花费 7 + 15 + 15 = 37 分钟收拾完所有的垃圾。

 

提示:

  • 2 <= garbage.length <= 10^5
  • garbage[i] 只包含字母 'M' ,'P' 和 'G' 。
  • 1 <= garbage[i].length <= 10
  • travel.length == garbage.length - 1
  • 1 <= travel[i] <= 100

解析

这些垃圾车也太不智能了,竟然不要求同时工作,两辆车在不同的房子门前各干各的,为什么不行呢

根据题目要求,因为不够智能,所以难度也降低了很多,每一种类型的垃圾车都要收完自己对应的垃圾,对应的垃圾出现的最远的房子在哪儿,他就得从第0个房子出发,走到最远的房子那儿。

因此总时间就是路上花费的时间,加上在对应房子那儿收自己类型垃圾的时间。

换言之,如果某个类型的垃圾没有出现,这个车就不用出发了。如果某个类型的垃圾一共出现了三次,则收垃圾这个动作就要花费三分钟,在数数路程花了多久,加起来就行了。

代码

class Solution:
    def garbageCollection(self, garbage: List[str], travel: List[int]) -> int:
        all_garbage = "".join(garbage)
        # 也可以使用 from collections import Counter
        m_counts = all_garbage.count("M")
        p_counts = all_garbage.count("P")
        g_counts = all_garbage.count("G")
        print(m_counts, p_counts, g_counts)
        last_m = -1
        last_p = -1
        last_g = -1
        for index, g in enumerate(garbage):
            if "M" in g:
                last_m = index
            if "G" in g:
                last_g = index
            if "P" in g:
                last_p = index
        print(last_m, last_p, last_g)
        step_m = 0
        step_p = 0
        step_g = 0
        if last_m > 0:
            step_m = sum(travel[:last_m]) + m_counts
        else:
            step_m = m_counts
        if last_p > 0:
            step_p = sum(travel[:last_p]) + p_counts
        else:
            step_p = p_counts
        if last_g > 0:
            step_g = sum(travel[:last_g]) + g_counts
        else:
            step_g = g_counts
        print(step_m, step_p, step_g)
        return step_m + step_p + step_g