LeetCode笔记:Weekly Contest 322

Posted Espresso Macchiato

tags:

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

1. 题目一

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

1. 解题思路

这一题思路非常直接,就是分割字符串之后然后按照题意比对每两个相邻单词的词头和词尾字符即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def isCircularSentence(self, sentence: str) -> bool:
        words = sentence.split()
        n = len(words)
        words.append(words[0])
        for i in range(n):
            if words[i][-1] != words[i+1][0]:
                return False
        return True

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

2. 题目二

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

1. 解题思路

这一题要想要成功分割,就一定是排序之后首尾组合,因此,我们只需要排序之后依次取出头尾元素,比较其和值是否相同,然后取其积相加即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def dividePlayers(self, skill: List[int]) -> int:
        chemistry = 0
        skill = sorted(skill)
        n, s = len(skill), skill[0] + skill[-1]
        for i in range(n//2):
            if skill[i] + skill[n-1-i] != s:
                return -1
            chemistry += skill[i] * skill[n-1-i]
        return chemistry

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

3. 题目三

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

1. 解题思路

这一题思路上其实就是找到所有与1和n相连的节点与边,然后找到其中的最小值即可。

这个做法其实可以有挺多的,这里我简单地使用一个DSU的解法来对其进行实现,即通过DSU快速地找到所有与1与n连通的节点,然后记录所有的边当中的最小值。

2. 代码实现

给出python代码实现如下:

class DSU:
    def __init__(self, n):
        self.root = [i for i in range(n+1)]
        self.vals = [math.inf for _ in range(n+1)]
        
    def find(self, k):
        if self.root[k] != k:
            self.root[k], d = self.find(self.root[k])
        return self.root[k], self.vals[self.root[k]]
    
    def union(self, a, b, d):
        x, d1 = self.find(a)
        y, d2 = self.find(b)
        if x != y:
            self.root[y] = x
            self.vals[x] = min(d1, d2, d)
        else:
            self.vals[x] = min(d1, d)
        return
    
    def get_distance(self, a, b):
        x, d1 = self.find(a)
        y, d2 = self.find(b)
        if x == y:
            return d1
        else:
            return -1

class Solution:
    def minScore(self, n: int, roads: List[List[int]]) -> int:
        dsu = DSU(n)
        for u, v, d in roads:
            dsu.union(u, v, d)
        return dsu.get_distance(1, n)

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

4. 题目四

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

1. 解题思路

这一题思路上来说就是找到所有的连接的节点组,然后看每一个组合能够分割以及分割所能够构成的最大的层数。然后,我们将每一个节点组的层数相加即可得到最终的答案。

其中,关于如何获取相连的节点组,我们可以使用DSU进行实现。而关于第二个问题,如何获得每一个相连接的节点组能否分层以及分层的最大数目,我们可以通过遍历组内每一个节点作为起始点的情况下的分层情况。

而具体的分层方法,我们可以通过使用bfs的方法进行实现。

2. 代码实现

给出python代码实现如下:

class DSU:
    def __init__(self, n):
        self.root = [i for i in range(n)]
        
    def find(self, k):
        if self.root[k] != k:
            self.root[k] = self.find(self.root[k])
        return self.root[k]
    
    def union(self, a, b):
        x = self.find(a)
        y = self.find(b)
        if x != y:
            self.root[y] = x
        return
    
class Solution:
    def magnificentSets(self, n: int, edges: List[List[int]]) -> int:
        dsu = DSU(n)
        adj = defaultdict(list)
        for u, v in edges:
            adj[u-1].append(v-1)
            adj[v-1].append(u-1)
            dsu.union(u-1, v-1)
            
        cnt = defaultdict(int)
        for u in range(n):
            depth = defaultdict(int)
            s = [u]
            depth[u] = 1
            while s:
                v = s.pop(0)
                for w in adj[v]:
                    if w not in depth:
                        depth[w] = depth[v] + 1
                        s.append(w)
                    elif abs(depth[w] - depth[v]) != 1:
                        return -1
            u = dsu.find(u)
            cnt[u] = max(cnt[u], max(depth.values()))
        
        return sum(cnt.values())

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

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

LeetCode笔记:Weekly Contest 317

LeetCode笔记:Weekly Contest 288

LeetCode笔记:Weekly Contest 299

LeetCode笔记:Weekly Contest 307

LeetCode笔记:Weekly Contest 325

LeetCode笔记:Weekly Contest 314