LeetCode笔记:Biweekly Contest 111

  • [LeetCode笔记:Biweekly Contest 111](#LeetCode笔记:Biweekly Contest 111)
    • [1. 题目一](#1. 题目一)
      • [1. 解题思路](#1. 解题思路)
      • [2. 代码实现](#2. 代码实现)
    • [2. 题目二](#2. 题目二)
      • [1. 解题思路](#1. 解题思路)
      • [2. 代码实现](#2. 代码实现)
    • [3. 题目三](#3. 题目三)
      • [1. 解题思路](#1. 解题思路)
      • [2. 代码实现](#2. 代码实现)
    • [4. 题目四](#4. 题目四)
      • [1. 解题思路](#1. 解题思路)
      • [2. 代码实现](#2. 代码实现)

1. 题目一

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

1. 解题思路

这一题由于题目给出的整体数字不多,因此我偷了个懒,直接一个二重循环暴力求解了,倒是也没花太多功夫......

2. 代码实现

给出python代码实现如下:

python 复制代码
class Solution:
    def countPairs(self, nums: List[int], target: int) -> int:
        n = len(nums)
        cnt = 0
        for i in range(n-1):
            for j in range(i+1, n):
                if nums[i] + nums[j] < target:
                    cnt += 1
        return cnt

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

2. 题目二

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

1. 解题思路

这一题思路上使用贪婪算法即可。

我们从左往右遍历str1,然后将每一个字符依次匹配str2的字符,如果某一个字符可以通过变形获得str2上的某一个字符,那么就将其配对,然后考察下一个字符。

最后我们只需要看str2当中的字符是否都可以找到匹配即可。

2. 代码实现

给出python代码实现如下:

python 复制代码
class Solution:
    def canMakeSubsequence(self, str1: str, str2: str) -> bool:
        
        def move_cyclic(ch):
            return "a" if ch == "z" else chr(ord(ch)+1)
        
        idx, n = 0, len(str2)
        for ch in str1:
            if idx >= n:
                break
            if ch == str2[idx]:
                idx += 1
            elif move_cyclic(ch) == str2[idx]:
                idx += 1
        return idx == n

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

3. 题目三

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

1. 解题思路

这一题其实就是考察通过至少多少次操作可以使得整个数组变成一个非递减数组。

因此,我们采用一个动态规划的方法就可以快速地给出这道题的解答了。

2. 代码实现

给出python代码实现如下:

python 复制代码
class Solution:
    def minimumOperations(self, nums: List[int]) -> int:
        
        n = len(nums)
        
        @lru_cache(None)
        def dp(idx, pre_max):
            if idx == n:
                return 0
            if nums[idx] < pre_max:
                return 1 + dp(idx+1, pre_max)
            elif nums[idx] == pre_max:
                return dp(idx+1, nums[idx])
            else:
                return min(1 + dp(idx+1, pre_max), dp(idx+1, nums[idx]))
            
        return dp(0, 1)

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

4. 题目四

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

1. 解题思路

这一题形式上和做法上都和题目2801. Count Stepping Numbers in Range比较接近,就是要求范围内一些符合条件的数字的个数,就只要求低于两个边界值的符合条件的数字的个数然后相减即可。

对于题目2801,我们已经给了一个博客对其进行了解答(LeetCode笔记:Weekly Contest 356),这道题在形式上也差不多。

唯一的区别在于如何求这里的Beautiful Integer,其实这个问题也不大,我们只需要将每一位进行拆分,然后考察其对 k k k余数的加和即可。要满足目标条件,就需要首先加和为0,其次奇数位个数和偶数位相同即可。

剩下的就是实现了,也主要就是和题目2801一样,基本就是有些繁琐,难度还好,注意一下边界条件和分类讨论即可。

2. 代码实现

给出python代码实现如下:

python 复制代码
class Solution:
    
    @lru_cache(None)
    def count_beautiful_number(self, n, k):
        if n == 0:
            return 0
        
        digits = []
        while n != 0:
            digits.insert(0, n % 10)
            n = n // 10
        n = len(digits)
    
        @lru_cache(None)
        def dp(idx, delta, mod, allow_big, have_start):
            if n-idx < abs(delta):
                return 0
            elif idx >= n:
                return 1 if mod == 0 and delta == 0 and have_start else 0
            res = 0
            if allow_big:
                if have_start:
                    res += dp(idx+1, delta+1, mod, True, True)
                else:
                    res += dp(idx+1, delta, mod, True, False)
                for d in range(1, 10):
                    if d % 2 == 0:
                        res += dp(idx+1, delta+1, (mod+d*(10**(n-1-idx))) % k, True, True)
                    else:
                        res += dp(idx+1, delta-1, (mod+d*(10**(n-1-idx))) % k, True, True)
            else:
                if have_start:
                    res += dp(idx+1, delta+1, mod, digits[idx] > 0, True)
                else:
                    res += dp(idx+1, delta, mod, digits[idx] > 0, False)
                for d in range(1, digits[idx]):
                    if d % 2 == 0:
                        res += dp(idx+1, delta+1, (mod+d*(10**(n-1-idx))) % k, True, True)
                    else:
                        res += dp(idx+1, delta-1, (mod+d*(10**(n-1-idx))) % k, True, True)
                if digits[idx] > 0:
                    if digits[idx] % 2 == 0:
                        res += dp(idx+1, delta+1, (mod+digits[idx]*(10**(n-1-idx))) % k, False, True)
                    else:
                        res += dp(idx+1, delta-1, (mod+digits[idx]*(10**(n-1-idx))) % k, False, True)
            return res
        
        return dp(0, 0, 0, False, False)
    
    def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int:
        return self.count_beautiful_number(high, k) - self.count_beautiful_number(low-1, k)

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