71-75题:304/357/367/80/168

筅森魡賤 提交于 2020-02-03 08:21:45

304. 二维区域和检索 - 矩阵不可变

在这里插入图片描述
在这里插入图片描述

思路

1.暴力法。O(mn),超时

        sums = 0
        for i in range(row1,row2+1):
            for j in range(col1,col2+1):
                sums =sums+self.matrix[i][j]
        return sums

优化

1.题目要求多次求解,思路应该是每查一次将结果记录下来,之后再次计算在这些基础上再少量的加加减减。但想着不太好实现。
2.直接看官方题解,原来直接将结果全计算出来,然后简单计算得到。
思路是:|在这里插入图片描述在这里插入图片描述
sum(abcd)=sum(od)−sum(ob)−sum(oc)+sum(oa)

看懂了官方java的思路写的python

    def __init__(self, matrix: List[List[int]]):
        self.matrix = matrix

        if len(matrix) == 0 or len(matrix[0]) == 0 :
            return None
            
        m = len(matrix)
        n = len(matrix[0])
        sum_matrix = [[0 for i in range(n+1)] for j in range(m+1)]

        for i in range(1,m+1):
            for j in range(1,n+1):
                sum_matrix[i][j] = matrix[i-1][j-1] + sum_matrix[i-1][j]+sum_matrix[i][j-1] -sum_matrix[i-1][j-1]
        
        self.sum_matrix = sum_matrix
        print(sum_matrix)  

    def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
        return self.sum_matrix[row2+1][col2+1] + self.sum_matrix[row1][col1] -self.sum_matrix[row2+1][col1]-self.sum_matrix[row1][col2+1]

执行用时 :148 ms, 在所有 Python3 提交中击败了41.18%的用户

357. 计算各个位数不同的数字个数

在这里插入图片描述

思路

中等题,但是难度也就是简单,几分钟写出来。
数学题,一位数,有9个,两位数,有9*9个,三位数是二位数结果乘8。
然后前几项加和就是结果。另外大于10,直接返回一个定值,因为已经是所有重复的了。

    def countNumbersWithUniqueDigits(self, n: int) -> int:

        nums = [1,9]
        for i in range(2,11):
            nums.append(nums[i-1]*(11-i))

        if n>10:
            return sum(nums)
        else:
            return sum(nums[:n+1])

367. 有效的完全平方数

在这里插入图片描述

思路

二分法加优化上下限。

一个小的二分法优化:利用数字位数确定上下限,比如三四位数的平方根在[10,100),五六位数对应在[100,1000)。

n = len(str(num))

a = 10**int((n-1)//2)
b = a*10

n是位数,a,b是上下限。

        n = len(str(num))

        a = 10**int((n-1)//2)
        b = a*10

        while a<=b:
            i = (a+b)//2
            if i*i == num:
                return True
            elif i*i <num:
                a =1+i
            elif i*i >num:
                b = i-1
        return False

优化

官方题解的牛顿法

    def isPerfectSquare(self, num: int) -> bool:
        if num < 2:
            return True
        
        x = num // 2
        while x * x > num:
            x = (x + num // x) // 2
        return x * x == num

80. 删除排序数组中的重复项 II

在这里插入图片描述

思路

类似的I已经做过了,在I的基础上加上出现次数的计算。

    def removeDuplicates(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0

        start = nums[0] +1
        times = 0
        j = 0
        for i in range(len(nums)):
            if nums[i] == start :
                if times < 2:
                    times = times+1
                    nums[j] = nums[i]
                    j=j+1
                else:   
                    continue
            else:
                nums[j] = nums[i]
                start = nums[i]
                times = 1
                j = j + 1
        return j

执行用时 :52 ms, 在所有 Python3 提交中击败了93.87%的用户

和官方题解基本一致。

168. Excel表列名称

在这里插入图片描述

思路

和171题将excel列字母转为数字很像,这道题是数字转字母。

    def convertToTitle(self, n: int) -> str:
        strs = ""

        while n > 0:
            m = (n-1) % 26 + 1
            n= (n-1)//26
            strs =  chr(m +64) + strs
        return strs

1.注意1-26对应A-Z,而余数1-26对应的是1-25-0。为了让26对应上Z,需要(n-1) % 26 + 1

2.输出字符串,先输出的是26进制的个位,所以对应字母在最后面。所以
strs = chr(m +64) + strs

执行用时 :32 ms, 在所有 Python3 提交中击败了71.09%的用户

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!