LeetCode Notes: Weekly Contest 220 Contest Record

0. Summary after the game

The result of this competition was a bit miserable, only 3 questions were made, and then only 229/3690 in China and 667/9606 in the world, both of which were only in the top 7%.

But the question this time should be relatively simple. After looking at it, the first big guy only took less than 10 minutes to get it done, and the last question I didn’t make was actually a DSU question. I also wrote a blog about this algorithm before ( Python notes: Introduction to the structure of DSU ), but I still didn't come up with it in the competition.

It's not that I have never thought of using DSU, but I still want to go wrong after all. I didn't think of the correct way to use it, which led to the failure of the last question. But let's talk about it later, alas. . .

1. Topic One

The link to the question given for question one is as follows:

1. Problem-solving ideas

This question is quite straightforward. The idea of ​​solving the problem is to remove the spaces and -characters first , and then divide it into groups of 3 numbers, knowing the last few digits for special treatment.

2. Code implementation

The python code is given as follows:

class Solution:
    def reformatNumber(self, number: str) -> str:
        number = number.replace("-", "").replace(" ", "")
        n = len(number)
        res = []
        idx = 0
        while idx < n-4:
            res.append(number[idx:idx+3])
            idx += 3
        if n - idx == 4:
            res.extend([number[idx:idx+2], number[idx+2:idx+4]])
        else:
            res.append(number[idx:])
        return "-".join(res)

After submitting the code for evaluation, it took 36ms and took up 14.1MB of memory.

The current optimal algorithm takes 28ms, but the idea is the same after looking at it, so I won't expand it too much here.

2. Topic 2

The link to the test questions for topic two is as follows:

1. Problem-solving ideas

The idea of ​​this question is actually quite clear, which is to maintain a sliding window to ensure that there are no duplicate elements in the window.

2. Code implementation

The python code is given as follows:

class Solution:
    def maximumUniqueSubarray(self, nums: List[int]) -> int:
        i, j, n = 0, 0, len(nums)
        counter = defaultdict(int)
        ans = 0
        score = 0
        while j < n:
            while i < j and counter[nums[j]] == 1:
                score -= nums[i]
                counter[nums[i]] -= 1
                i += 1
            while j < n and counter[nums[j]] == 0:
                score += nums[j]
                counter[nums[j]] += 1
                j += 1
            ans = max(ans, score)
        return ans

After submitting the code for evaluation, it took 1380ms and took up 28.4MB of memory.

The current optimal algorithm takes 792ms, but after looking at it, their algorithm ideas are the same as ours, so I won’t go into too much here.

3. Topic Three

The link to the test questions for topic three is as follows:

1. Problem-solving ideas

The idea of ​​this question is to use the dynamic programming algorithm.

His recurrence relationship is still very clear, and the recurrence relationship can be given as follows:

f ( i ) = n i + m a x ( f ( j ) )   ( i < j ≤ i + k ) f(i) = n_i + max(f(j)) \ (i< j \leq i+k) f(i)=ni+max(f(j)) (i<ji+k)

We tried to solve it directly and brutally, but the time complexity is O (N × K) O(N \times K)O ( N×K ) , it will lead to a timeout, but this question can actually refer to the last question of the last week’s bi-weekly competition. Using an ordered queue for processing, the time complexity can be reduced toO (N) O (N)O ( N ) , the specific algorithm description can refer to our last week's competition record (LeetCode notes: Biweekly Contest 41 competition record), the specific details will not be expanded here.

2. Code implementation

We directly give the python code implementation as follows:

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        n = len(nums)
        dp = [k for k in nums]
        q = [(nums[-1], n-1)]
        for i in range(n-2, -1, -1):
            while q != [] and q[-1][1] > i + k:
                q.pop()
            dp[i] += q[-1][0]
            while q != [] and q[0][0] < dp[i]:
                q.pop(0)
            q.insert(0, (dp[i], i))
        return dp[0]

After submitting the code for evaluation, it took 828ms and took up 27.8MB of memory.

The current optimal code implementation takes 704ms, but after looking at their ideas, they are exactly the same as ours, so I won’t do more here.

4. Topic Four

The link to the test question for question four is as follows:

1. Problem-solving ideas

It was really too hurt that I didn't do it during the competition. After the game, I looked at Awice's answer and found that I didn't do it. It was really too bad.

The idea of ​​this question is actually quite straightforward. Obviously because n can be as large as 1 0 5 10^5105 , so the required algorithm complexity must not exceedO (N 2) O(N^2)O ( N2 ), preferably onlyO (N) O(N)O ( N ) , then a straightforward idea is to use DSU (for the description of this part of the content, please refer to our previous blog:Python Notes: Introduction to the Structure of Concurrent Checksum (DSU)).

In fact, we also thought of it during the game, but the specific implementation was difficult, because in fact, it only allowed a limited number of edges to be used, and it wanted to return the smallest implementation among all the connected solutions of the two points. The maximum side length, and DSU can only reflect the aggregation relationship and some characteristics of the entire cluster, but cannot reflect the relationship of the smaller sets, so I did not think of it during the game. Of course, this follow-up can be bypassed in other ways. We will talk later.

Then another idea is to use dynamic programming to save all the historical calculation results in the cache to optimize the execution effect. This is my idea during the game, but the problem I encountered is how to store the state, and then you know, no If you don't look back at the South Wall, you can't die more miserable, alas. . .

Let's go back and talk about the correct way to use dsu.

If the problem is simplified to a specific query, in fact, we only need to use the side whose side length is less than the limit to construct the dsu. Therefore, we can simply use dsu to answer the question. However, the problem is that for each query, we have to build a dsu for the limit. This will be very complicated and will inevitably lead to timeout problems.

However, if we implement the sorting of the query to the limit, then we don't actually need to construct the dsu every time, as long as the global construction of a dsu structure can solve this problem .

2. Code implementation

We give the specific python code implementation as follows:

class DSU:
    def __init__(self, n):
        self.dsu = [i for i in range(n)]
    
    def find(self, x):
        if self.dsu[x] != x:
            self.dsu[x] = self.find(self.dsu[x])
        return self.dsu[x]
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            self.dsu[y] = x
        return

class Solution:
    def distanceLimitedPathsExist(self, n: int, edgeList: List[List[int]], queries: List[List[int]]) -> List[bool]:
        edges = sorted(edgeList, key=lambda x: x[2])
        queries = sorted([(idx, u, v, limit) for idx, (u, v, limit) in enumerate(queries)], key=lambda x: x[-1])
        m = len(edges)
        
        res = [False for _ in queries]
        i = 0
        dsu = DSU(n)
        for idx, u, v, limit in queries:
            while i < m and edges[i][2] < limit:
                p, q, _ = edges[i]
                dsu.union(p, q)
                i += 1
            res[idx] = (dsu.find(u) == dsu.find(v))
        return res

Submit code evaluation and get: It takes 2028ms and takes up 61.2MB of memory.

The current optimal code implementation takes 1812ms, but it is also implemented in the dsu method, so I won’t expand it too much here.

Guess you like

Origin blog.csdn.net/codename_cys/article/details/111464169