日渐头秃的代码日记 -- 第313场周赛国庆居家隔离7天

88 阅读3分钟

这是我参与『掘金日新计划·10月更文挑战』的第1天。 今天的题目就突出一个:暴力

一、公因子的数目

给你两个正整数 a 和 b ,返回 a 和 b 的  因子的数目。

如果 x 可以同时整除 a 和 b ,则认为 x 是 a 和 b 的一个 公因子 。

 

示例 1:

输入: a = 12, b = 6
输出: 4
解释: 126 的公因子是 1236

示例 2:

输入: a = 25, b = 30
输出: 2
解释: 2530 的公因子是 15

 

提示:

  • 1 <= a, b <= 1000

解析

直接暴力枚举就行了,最大值才1000

代码

class Solution:
    def commonFactors(self, a: int, b: int) -> int:
        small = min(a, b)
        res = 0
        for i in range(1, small+1):
            if a % i == 0 and b % i == 0:
                res += 1
        return res

二、沙漏的最大总和

给你一个大小为 m x n 的整数矩阵 grid 。

按以下形式将矩阵的一部分定义为一个 沙漏 :

返回沙漏中元素的 最大 总和。

注意: 沙漏无法旋转且必须整个包含在矩阵中。

 

示例 1:

输入: grid = [[6,2,1,3],[4,2,1,5],[9,2,8,7],[4,1,2,9]]
输出: 30
解释: 上图中的单元格表示元素总和最大的沙漏:6 + 2 + 1 + 2 + 9 + 2 + 8 = 30

示例 2:

输入: grid = [[1,2,3],[4,5,6],[7,8,9]]
输出: 35
解释: 上图中的单元格表示元素总和最大的沙漏:1 + 2 + 3 + 5 + 7 + 8 + 9 = 35

 

提示:

  • m == grid.length
  • n == grid[i].length
  • 3 <= m, n <= 150
  • 0 <= grid[i][j] <= 10^6

解析

沙漏就是一个九宫格去掉左右两个格子就可以了,枚举出来所有的值就行,这个grid也不大

代码

class Solution:
    def maxSum(self, grid: List[List[int]]) -> int:
        m = len(grid)
        n = len(grid[0])
        s = 0
        for i in range(1, m-1):
            for j in range(1, n-1):
                t = grid[i][j] + grid[i-1][j] + grid[i+1][j] + grid[i-1][j-1] + grid[i-1][j+1] + grid[i+1][j-1] + grid[i+1][j+1]
                s = max(s, t)
        return s

三、最小XOR

给你两个正整数 num1 和 num2 ,找出满足下述条件的整数 x :

  • x 的置位数和 num2 相同,且
  • x XOR num1 的值 最小

注意 XOR 是按位异或运算。

返回整数 **x 。题目保证,对于生成的测试用例, x 是 唯一确定 的。

整数的 置位数 是其二进制表示中 1 的数目。

 

示例 1:

输入: num1 = 3, num2 = 5
输出: 3
解释:
num1 和 num2 的二进制表示分别是 0011 和 0101 。
整数 3 的置位数与 num2 相同,且 3 XOR 3 = 0 是最小的。

示例 2:

输入: num1 = 1, num2 = 12
输出: 3
解释:
num1 和 num2 的二进制表示分别是 0001 和 1100 。
整数 3 的置位数与 num2 相同,且 3 XOR 1 = 2 是最小的。

 

提示:

  • 1 <= num1, num2 <= 10^9

解析

数学题,求出num1和num2的置位数,如果两者的置位数相等,那么x就等于num1即可,这样可以让XOR的值为0。

如果num1的置位数比num2的置位数大,也就是有更多的1,这时候要想让XOR的值最小,那么就得让x和num1的二进制不相同的位尽量靠右,x的二进制保留num1高位的1,保留的数量是num2的置位数,其余的都是0即可。

反过来,num2的置位数比num1的置位数多出来m,那么x的二进制就是在原来num1的基础上,从右向左将m个0改成1。

代码

class Solution:
    def minimizeXor(self, num1: int, num2: int) -> int:
        x = '0' * 30
        zhi = str(bin(num2)).split('0b')[-1].count('1')
        n1 = ("%s" % str(bin(num1)).split('0b')[-1]).zfill(30)
        n1 = [m for m in n1]
        zhi_n1 = str(bin(num1)).split('0b')[-1].count('1')
        if zhi == zhi_n1:
            n1 = ''.join(n1)
            return int('0b%s'%n1, 2)
        if zhi_n1 > zhi:
            for index, x in enumerate(n1):
                if x == '1':
                    if zhi:
                        zhi -= 1
                    else:
                        n1[index] = '0'
                
            n1 = ''.join(n1)
            return int('0b%s'%n1, 2)
        else:
            g = zhi - zhi_n1
            for index, x in enumerate(n1[::-1]):
                if x == '0' and g:
                    n1[29-index] = '1'
                    g -= 1
            n1 = ''.join(n1)
            return int('0b%s'%n1, 2)

四、对字母串可执行的最大删除数

给你一个仅由小写英文字母组成的字符串 s 。在一步操作中,你可以:

  • 删除 整个字符串 s ,或者
  • 对于满足 1 <= i <= s.length / 2 的任意 i ,如果 s 中的  i 个字母和接下来的 i 个字母 相等 ,删除  i 个字母。

例如,如果 s = "ababc" ,那么在一步操作中,你可以删除 s 的前两个字母得到 "abc" ,因为 s 的前两个字母和接下来的两个字母都等于 "ab" 。

返回删除 s 所需的最大操作数。

 

示例 1:

输入: s = "abcabcdabc"
输出: 2
解释:
- 删除前 3 个字母("abc"),因为它们和接下来 3 个字母相等。现在,s = "abcdabc"。
- 删除全部字母。
一共用了 2 步操作,所以返回 2 。可以证明 2 是所需的最大操作数。
注意,在第二步操作中无法再次删除 "abc" ,因为 "abc" 的下一次出现并不是位于接下来的 3 个字母。

示例 2:

输入: s = "aaabaab"
输出: 4
解释:
- 删除第一个字母("a"),因为它和接下来的字母相等。现在,s = "aabaab"。
- 删除前 3 个字母("aab"),因为它们和接下来 3 个字母相等。现在,s = "aab"。 
- 删除第一个字母("a"),因为它和接下来的字母相等。现在,s = "ab"。
- 删除全部字母。
一共用了 4 步操作,所以返回 4 。可以证明 4 是所需的最大操作数。

示例 3:

输入: s = "aaaaa"
输出: 5
解释: 在每一步操作中,都可以仅删除 s 的第一个字母。

 

提示:

  • 1 <= s.length <= 4000
  • s 仅由小写英文字母组成

解析

很多大佬的解法都是lcp(最长公共前缀)+ DP,没遇到过类似的问题确实还挺难的,不过我发现了LC的执行漏洞,一句cache行天下了

代码

class Solution:
    @cache  # 没有这一行装饰器,会超时,有了它,秒杀
    def handle(self, s):
        os = copy.copy(s)
        maybe = []
        for i in range(1, len(os)//2+1):
            if os[:i] == os[i:i*2]:
                maybe.append(os[i:])
        if not maybe:
            return 1
        steps = []
        for m in maybe:
            step = self.handle(m) + 1
            steps.append(step)
        return max(steps)
        
    def deleteString(self, s: str) -> int:
        if len(set(s)) == 1:
            return len(s)
        if len(s) == 1:
            return 1
        res = self.handle(s)
        return res

image.png