Leetcode题解 - 中等难度(1311、LCP 3、1306、1282、1296、1297)

1311. 获取你好友已观看的视频 - BFS

在这里插入图片描述
思路:
找到第level层的好友,是一层一层寻找所以使用BFS,然后再计数就行了

"""
BFS
"""
from collections import defaultdict, Counter
class Solution:
    def watchedVideosByFriends(self, watchedVideos, friends, id: int, level: int):
        mat = defaultdict(list)
        # 先建图
        for ind, num in enumerate(friends):
            mat[ind] += num
        Q, vis = [(id, 0)], {id}
        # BFS找level层的朋友是谁
        while len(Q) != 0:
            node, deepth = Q.pop(0)
            if deepth == level:
                Q = [i[0] for i in Q] + [node]
                break
            for i in mat[node]:
                if i not in vis:
                    vis.add(i)
                    Q.append((i, deepth+1))
        res = []
        for i in Q:
            res += watchedVideos[i]
        r = sorted(Counter(res).items(), key=lambda x: (x[1], x[0]))
        return [i[0] for i in r]

LCP 3. 机器人大冒险

在这里插入图片描述
思路:
第一反映应该是模拟,当然没有这么简单,就超时了。

那么转去判断是否能够到达障碍处,这样需要判断的最多也只有1k+。
如果能够到达某处,必然是走了x轮,y步之后的结果,那么去除掉x轮走过的路,只判断这y步能否走的即可。

class Solution:
    def robot(self, command: str, obstacles, x: int, y: int) -> bool:
        tx, ty, res = 0, 0, []
        # 记录一次command能到达的位置,如果能走到某处,去除掉x轮之后的位置必定在这里面。
        for i in command:
            if i == 'R':
                tx += 1
            if i == 'U':
                ty += 1
            res.append([tx, ty])
        res.append([0, 0])
        sorted(res)
        # 判断是否能走到终点,gl表示走的轮数
        gl = min(x // tx, y // ty)
        if [x - gl * tx, y - gl * ty] not in res:
            return False
        for ox, oy in obstacles:
            # 走几轮可以到这?
            l = min(ox // tx, oy // ty)
            # 障碍物的轮数大于目标的,那么肯定碰不到
            if l > gl:
                continue
            # 轮数相同但是在目标位置后面也碰不着
            if l == gl:
                if res.index([ox - l * tx, oy - l * ty]) > res.index([x - gl * tx, y - gl * ty]):
                    continue
            if [ox - l * tx, oy - l * ty] in res:
                return False
        return True

1306. 跳跃游戏 III - DFS

在这里插入图片描述
思路:
因为都到某个下标后都有两条路可以走 -> 想到使用DFS的模板

class Solution:
    def canReach(self, arr, start: int) -> bool:
        vis = set()
        def DFS(node, res):
            if not arr[node]:
                return True
            for i in [-1, 1]:
                tnode = node + i * arr[node]
                if judge(tnode) and tnode not in vis:
                    vis.add(tnode)
                    if DFS(tnode, res + [tnode]):
                        return True
                    vis.remove(tnode)
            return False

        # 判断是否出界
        def judge(num):
            if -1 < num < len(arr):
                return True
            return False
        return DFS(start, [start])

1282. 用户分组

在这里插入图片描述
思路:
相同组大小的先放到一起,然后再根据组大小进行切割。

from collections import defaultdict
class Solution:
    def groupThePeople(self, groupSizes):
        res = defaultdict(list)
        r = []
        # 组大小相同的放在一起
        for ind, group in enumerate(groupSizes):
            res[group].append(ind)
        # 根据组的大小进行切割
        for k, v in res.items():
            r += [v[i-k:i] for i in range(1, len(v)+1) if i % k == 0]
        return sorted(r, key=lambda x:len(x))

1296. 划分数组为连续数字的集合

在这里插入图片描述

"""
通过频率来判断是否可以划分
"""
from collections import Counter
class Solution:
    def isPossibleDivide(self, nums, k: int) -> bool:
        # d记录所有数字出现频率
        d = Counter(nums)
        if len(nums) % k:
            return False
        for i in sorted(nums):
            if d[i] <= 0:
                continue
            for j in range(k):
                if i+j not in d or d[i+j] <= 0:
                    return False
                d[i+j] -= 1
        return True

1297. 子串的最大出现次数 - 滑动窗口

在这里插入图片描述
思路:
滑动窗口,窗口大小为minSize。maxSize完全就是一个迷惑项,因为但是maxSize长度的子串出现的地方,minSize长度子串必然出现,反之却不是。

from collections import Counter
class Solution:
    def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
        res = []
        # 先把符合条件的全部搜集起来
        for i in range(0, len(s)-minSize+1):
            ts = s[i:i+minSize]
            if len(set(ts)) > maxLetters:
                continue
            else:
                res.append(ts)
        if not res:
            return 0
        # 返回出现次数最多的
        return sorted(Counter(res).items(), key=lambda x:x[1], reverse=True)[0][1]
posted @ 2020-02-26 09:53  但是我拒绝  阅读(433)  评论(1编辑  收藏  举报