LeetCode笔记:Weekly Contest 285

Posted Espresso Macchiato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Weekly Contest 285相关的知识,希望对你有一定的参考价值。

1. 题目一

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

1. 解题思路

这一题可以直接按照题意的来,不过可能会有点繁琐,因为要考虑相同字符,因此我这边是分了两步走了,先把重复字符全部干掉了,然后就只要比较一下前后元素就行了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countHillValley(self, nums: List[int]) -> int:
        s = []
        for x in nums:
            if s == [] or s[-1] != x:
                s.append(x)
        n = len(s)
        res = [i for i in range(1, n-1) if (s[i-1]<s[i] and s[i]>s[i+1]) or (s[i-1]>s[i] and s[i]<s[i+1])]
        return len(res)

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

2. 题目二

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

1. 解题思路

这一题首先,最左端的全部向左走的车是一定不会撞车的,因此我们可以一次性全部干掉,然后考察剩余的车。

此时,我们只需要进行分类讨论即可:

  • 如果此时遇到了右行的车子,那么它本身不会产生撞击,除非遇到S或者L的车子,因此我们只需要记录下其数目即可;
  • 如果此时遇到了S的车子,那么它本身不会贡献撞击,除非它之前有向右行驶的车子,此时向右的车子有几辆就会产生几次撞击,且发生了撞击之后,右行的车子总数归零;
  • 如果此时遇到了左行的车子,那么需要考察此前右行车子的数目,由于确定左边一定有车,所以他一定会产生一次撞击,后面就是看如果有右行的车子,那么还会产生一次额外的撞击,此时同样的右行的车子数就会被归零了。

综上,我们即可获得全部的撞击次数。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countCollisions(self, directions: str) -> int:
        directions = directions.lstrip("L")
        res = 0
        rcnt = 0
        for ori in directions:
            if ori == "S":
                res += rcnt
                rcnt = 0
            elif ori == "L":
                res += rcnt + 1
                rcnt = 0
            else:
                rcnt += 1
        return res

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

3. 题目三

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

1. 解题思路

这一题思路其实也简单,就是一个简单的动态规划即可。

考察每一个环数上面Bob要不要去拿分,如果要拿分,那么就至少需要刚好比Alice获得的点数多一个,然后继续考察下一个环数即可。

唯一稍微特殊一点的就是,在返回时需要同时返回出当前的选择就是了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumBobPoints(self, numArrows: int, aliceArrows: List[int]) -> List[int]:
        n = len(aliceArrows)
        
        @lru_cache(None)
        def dp(idx, k):
            if idx == n-1:
                return (0, [k]) if k <= aliceArrows[n-1] else (n-1, [k])
            if k <= aliceArrows[idx]:
                score, res = dp(idx+1, k)
                return score, [0] + res
            else:
                score1, res1 = dp(idx+1, k)
                score2, res2 = dp(idx+1, k-aliceArrows[idx]-1)
                if score1 >= score2+idx:
                    return score1, [0] + res1
                else:
                    return score2+idx, [aliceArrows[idx]+1] + res2
               
        score, res = dp(0, numArrows)
        return res

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

4. 题目四

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

1. 解题思路

这一题其实只要按照题意对每一个query进行一下检查就行,我们直接将所有的连续字符进行合并,然后记录下数目,然后维护一个有序数组即可快速地得到最大连续子串的长度。

而对于每一个query的操作,我们只需要对对应的连续子串进行拆分或者合并即可。

难度其实并不大,不过就是比较繁琐,还有几种边界条件需要注意一下即可,这里就不多说了,建议大家自己写一下就行了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def longestRepeating(self, s: str, queryCharacters: str, queryIndices: List[int]) -> List[int]:
        pre = ""
        cnt = 0
        n = len(s)
        seq = []
        nums = []
        for i, ch in enumerate(s):
            if ch == pre:
                cnt += 1
            else:
                if pre != "":
                    nums.append(cnt)
                    seq.append((i-1, pre, cnt))
                pre = ch
                cnt = 1
        seq.append((n-1, pre, cnt))
        nums.append(cnt)
        nums = sorted(nums)
        
        def query(idx, ch):
            nonlocal nums, seq
            loc = bisect.bisect_left(seq, (idx, "", 0))
            ed, ch0, cnt = seq[loc]
            
            if ch0 != ch and seq[loc][0] == idx:
                if cnt == 1:
                    seq[loc] = (idx, ch, 1)
                else:
                    seq[loc] = (ed-1, ch0, cnt-1)
                    seq.insert(loc+1, (idx, ch, 1))
                    nums.pop(bisect.bisect_left(nums, cnt))
                    bisect.insort(nums, cnt-1)
                    bisect.insort(nums, 1)
                    loc = loc + 1
            elif ch0 != ch and seq[loc][0] != idx:
                bg = 0 if loc == 0 else seq[loc-1][0]+1
                ed, ch0, cnt = seq[loc]
                if bg != idx:
                    seq.pop(loc)
                    seq.insert(loc, (ed, ch0, ed-idx))
                    seq.insert(loc, (idx, ch, 1))
                    seq.insert(loc, (idx-1, ch0, idx-bg))
                    nums.pop(bisect.bisect_left(nums, cnt))
                    bisect.insort(nums, ed-idx)
                    bisect.insort(nums, idx-bg)
                    bisect.insort(nums, 1)
                    loc = loc + 1
                else:
                    seq.pop(loc)
                    seq.insert(loc, (ed, ch0, ed-idx))
                    seq.insert(loc, (idx, ch, 1))
                    nums.pop(bisect.bisect_left(nums, cnt))
                    bisect.insort(nums, ed-idx)
                    bisect.insort(nums, 1)

            if loc + 1 < len(seq) and seq[loc+1][1] == ch:
                ed, _, cnt = seq[loc+1]
                seq.pop(loc+1)
                seq[loc] = (ed, ch, cnt+1)
                nums.pop(bisect.bisect_left(nums, cnt))
                nums.pop(bisect.bisect_left(nums, 1))
                bisect.insort(nums, cnt+1)
            if loc - 1 >= 0 and seq[loc-1][1] == ch:
                bg = seq[loc-2][0] + 1 if loc-2 >= 0 else 0
                _, _, cnt = seq[loc-1]
                ed, _, cnt2 = seq[loc]
                seq.pop(loc)
                seq[loc-1] = (ed, ch, ed-bg+1)
                nums.pop(bisect.bisect_left(nums, cnt))
                nums.pop(bisect.bisect_left(nums, cnt2))
                bisect.insort(nums, ed-bg+1)

            return nums[-1]
                
        k = len(queryIndices)
        return [query(queryIndices[i], queryCharacters[i]) for i in range(k)]

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

以上是关于LeetCode笔记:Weekly Contest 285的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode笔记:Weekly Contest 317

LeetCode笔记:Weekly Contest 288

LeetCode笔记:Weekly Contest 299

LeetCode笔记:Weekly Contest 307

LeetCode笔记:Weekly Contest 325

LeetCode笔记:Weekly Contest 314