LeetCode笔记:Weekly Contest 358

  • LeetCode笔记:Weekly Contest 358
    • 1. 题目一
      • 1. 解题思路
      • 2. 代码实现
    • 2. 题目二
      • 1. 解题思路
      • 2. 代码实现
    • 3. 题目三
      • 1. 解题思路
      • 2. 代码实现
    • 4. 题目四
      • 1. 解题思路
      • 2. 代码实现
  • 比赛链接:https://leetcode.com/contest/weekly-contest-358

1. 题目一

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

  • 2815. Max Pair Sum in an Array

1. 解题思路

这一题在easy的题目里面显得多少有些复杂,不过整体思路也挺清晰,就是先按照数字最大的digit进行分组,然后找到所有包含两个以上的元素的组对其元素进行排序,然后找到最大的两个元素求和,最后返回这些求和的最大值即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxSum(self, nums: List[int]) -> int:
        
        def get_max_digit(num):
            res = 0
            while num != 0:
                res = max(res, num % 10)
                num = num // 10
            return res
        
        s = defaultdict(list)
        for num in nums:
            bisect.insort(s[get_max_digit(num)], num)
        
        res = -1
        for v in s.values():
            if len(v) > 1:
                res = max(res, v[-1] + v[-2])
        return res

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

2. 题目二

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

  • 2816. Double a Number Represented as a Linked List

1. 解题思路

这一题思路上同样还是挺清晰的,就是先把链表转换为数组,然后进行翻倍操作,最后将其恢复为链表即可。

其中链表的转换和恢复都是常规操作了,就不赘述了,剩下的就是翻倍的实现,这个其实也不复杂,记得记录一下进位即可。

2. 代码实现

给出python代码实现如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def doubleIt(self, head: Optional[ListNode]) -> Optional[ListNode]:
        nodes = []
        while head:
            nodes.append(head.val)
            head = head.next
        
        new_nodes = []
        remain = 0
        for v in nodes[::-1]:
            val = (v * 2 + remain) % 10
            remain = (v * 2 + remain) // 10
            new_nodes.insert(0, val)
        if remain != 0:
            new_nodes.insert(0, remain)
            
        new_nodes = [ListNode(val) for val in new_nodes]
        n = len(new_nodes)
        for i in range(n-1):
            new_nodes[i].next = new_nodes[i+1]
        return new_nodes[0]

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

3. 题目三

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

  • 2817. Minimum Absolute Difference Between Elements With Constraint

1. 解题思路

这一题说起来有点丢脸,因为一开始没有想到解题的思路,后来是看了别的大佬的解题思路之后才搞定的。

思路上来说,这道题其实还是比较直接的,就是一个反向的滑动窗口的维护。

我们从左往右移动中心元素,然后将窗口外的元素处理为一个有序数组,然后判断最小的差值。

然后,每次移动元素,我们只需要对应的修改窗口左右的边界元素即可对整个窗口进行维护。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minAbsoluteDifference(self, nums: List[int], x: int) -> int:
        n = len(nums)
        s = sorted(nums[x:])
        res = max(nums) - min(nums)
        for i, val in enumerate(nums):
            idx = bisect.bisect_left(s, val)
            if idx < len(s):
                res = min(res, abs(val - s[idx]))
            if idx > 0:
                res = min(res, abs(val - s[idx-1]))
            
            if i-x >= 0:
                bisect.insort(s, nums[i-x])
            if i+x < n:
                s.pop(bisect.bisect_left(s, nums[i+x]))
        return res

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

4. 题目四

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

  • 2818. Apply Operations to Maximize Score

1. 解题思路

这一题思路上其实还挺清晰的,就是分三步走。

首先,计算出所有元素的prime_score,然后对所有元素按照prime_score和index进行排序,从而,我们一次考察每一个元素,考察其加入时左右元素的边界即可得到要使得这个元素是prime_score的最大值是可以选择的子序列的个数。

最后,我们按照元素大小进行排序,然后选择前k个可以子序列即可。

2. 代码实现

给出python代码实现如下:

@lru_cache(None)
def get_primes():
    primes = []
    status = [0 for _ in range(10**5)]
    for i in range(2, 10**5):
        if status[i] != 0:
            continue
        primes.append(i)
        for j in range(i, 10**5, i):
            status[j] = 1
    return primes
        
PRIMES = get_primes()

@lru_cache(None)
def get_prime_score(num):
    score = 0
    for p in PRIMES:
        if num % p != 0:
            continue
        score += 1
        while num % p == 0:
            num = num // p
        if num == 1:
            break
    return score

class Solution:
    
    def maximumScore(self, nums: List[int], k: int) -> int:
        MOD = 10**9+7
        
        n = len(nums)
        nums = [(get_prime_score(num), idx, num) for idx, num in enumerate(nums)]
        nums = sorted(nums, key=lambda x: (x[0], -x[1]), reverse=True)

        s = []
        indexes = []
        for score, idx, num in nums:
            i = bisect.bisect_left(indexes, idx)
            l = idx+1 if i == 0 else idx-indexes[i-1]
            r = n - idx if i == len(indexes) else indexes[i]-idx
            indexes.insert(i, idx)
            cnt = l*r
            s.append((num, cnt))
        s = sorted(s, reverse=True)

        res = 1
        for num, cnt in s: 
            if cnt >= k:
                cnt = k
            res = (res * pow(num, cnt, MOD)) % MOD 
            k -= cnt
            if k == 0:
                break
        return res

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

你可能感兴趣的:(leetcode笔记,力扣周赛,358,leetcode,2815,leetcode,2816,leetcode,2817,leetcode,2818)