日常系列LeetCode《5·数学篇》

Posted 常某某的好奇心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日常系列LeetCode《5·数学篇》相关的知识,希望对你有一定的参考价值。

数据规模->时间复杂度

<=10^4 😮(n^2)
<=10^7:o(nlogn)
<=10^8:o(n)
10^8<=:o(logn),o(1)

总结:
1.数学相关直接模拟算法
2.基本运算–加减乘除
3.数字转换–数字反转等
4.数学性质–质数、直线等

lc 7 :https://leetcode.cn/problems/reverse-integer/
提示:
-2^31 <= x <= 2^31 - 1

#方案一:溢前判断
class Solution:
    def reverse(self, x: int) -> int:
        #o(1)
        res=0
        #o(n)
        y=abs(x)
        while y!=0:
            p=y%10  #顺序取个位
            y=y//10 #更新
            #先验
            if res>(2**31-1)//10 or(res==(2**31-1)//10 and p>7):return 0
            if res<(-2**31)//10 or(res==(-2**31)//10 and p<-8):return 0
            #
            res=res*10+p
        return res if x>0 else -res

#方案二:溢后判断
class Solution:
    def reverse(self, x: int) -> int:
        #o(1)
        res=0
        #o(n)
        y=abs(x)
        while y!=0:
            p=y%10  #顺序取个位
            y=y//10 #更新
            #后验
            new_res=res*10+p
            if new_res >2**31-1 or new_res<-2**31:return 0
            #
            res=new_res
        return res if x>0 else -res

lc 9 :https://leetcode.cn/problems/remove-9/
提示:
1 <= n <= 8 * 10^8
2.你能不将整数转为字符串来解决这个问题吗?

class Solution:
    def isPalindrome(self, x: int) -> bool:
        #o(1)
        if x==0:return True
        if x<0 or x%10==0:return False #排除:负数或末位为0
        #o(n)
        #反转一半
        res=0
        y=x
        while res<y:
            p=y%10
            y//=10
            res=res*10+p
        #比较(分奇/偶个位数)
        return  res==y or res//10==y #注:退出循环的条件

lc 989 :https://leetcode.cn/problems/add-to-array-form-of-integer/
提示:
1 <= num.length <= 10^4
0 <= num[i] <= 9
num 不包含任何前导零,除了零本身
1 <= k <= 10^4

class Solution:
    def addToArrayForm(self, num: List[int], k: int) -> List[int]:
        #o(n)
        n1=len(num)-1
        res=[]
        #o(n)
        carry=0
        while n1>=0 or k!=0:
            #
            x=num[n1] if n1>=0 else 0
            y=k%10 if k!=0 else 0
            #
            n1-=1
            k//=10
            res.append((x+y+carry)%10)
            carry=(x+y+carry)//10
        #
        if carry==1:res.append(1)
        return res[::-1]#逆序

lc 66 :https://leetcode.cn/problems/plus-one/
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        #o(n)
        for i in range(len(digits)-1,-1,-1):
            digits[i]+=1
            if digits[i]!=10:
                return digits
            else: digits[i]=0
        #o(1)
        if digits[0]==0:
            res=[0]*(len(digits)+1)
            res[0]=1
            return res

lc 415 :https://leetcode.cn/problems/add-strings/
提示:
1 <= num1.length, num2.length <= 10^4
num1 和num2 都只包含数字 0-9
num1 和num2 都不包含任何前导零

class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        #o(1)
        l1=len(num1)-1
        l2=len(num2)-1
        carry=0
        res=''
        #o(n)
        while l1>=0 or l2>=0:
            x=ord(num1[l1])-ord('0') if l1>=0 else 0
            y=ord(num2[l2])-ord('0') if l2>=0 else 0
            #
            s_um=x+y+carry
            res+=str(s_um%10)
            carry=s_um//10
            #
            l1,l2=l1-1,l2-1
        #
        if carry==1:res+=str(1)
        #
        return res[::-1]         

lc 67 【剑指 002】:https://leetcode.cn/problems/add-binary/
提示:
每个字符串仅由字符 ‘0’ 或 ‘1’ 组成。
1 <= a.length, b.length <= 10^4
字符串如果不是 “0” ,就都不含前导零。

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        #o(1)
        l1=len(a)-1
        l2=len(b)-1
        carry=0
        res=''
        #o(n)
        while l1>=0 or l2>=0:
            x=ord(a[l1])-ord('0') if l1>=0 else 0
            y=ord(b[l2])-ord('0') if l2>=0 else 0
            #
            s_um=x+y+carry
            res+=str(s_um%2)#二进制
            carry=s_um//2
            #
            l1,l2=l1-1,l2-1
        #
        if carry==1:res+=str(1)
        #
        return res[::-1]  

lc 2 【top100】:https://leetcode.cn/problems/add-two-numbers/
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        #新链表
        dummy=ListNode()
        curr=dummy
        #
        carry=0
        while l1 or l2:
            x=l1.val if l1 else 0
            y=l2.val if l2 else 0
            total=x+y+carry
            #属性
            curr.next=ListNode(total%10)
            curr=curr.next 
            carry=total//10   
            #注意条件
            if l1:l1=l1.next
            if l2:l2=l2.next
        #
        if carry==1:curr.next=ListNode(1)
        #
        return dummy.next

lc 43 :https://leetcode.cn/problems/multiply-strings/
提示:
1 <= num1.length, num2.length <= 200
num1 和 num2 只能由数字组成。
num1 和 num2 都不包含任何前导零,除了数字0本身。

class Solution:
    def multiply(self, num1: str, num2: str) -> str:
        #
        if num1=="0" or num2=="0":return '0'
        #o(m+n)
        l1,l2=len(num1),len(num2)
        res=[0]*(l1+l2)#key:所需最多位
        for i in range(l2-1,-1,-1):
            y=int(num2[i])
            for j in range(l1-1,-1,-1):
                x=int(num1[j])
                total=res[i+j+1]+x*y #key:对应个位相加
                res[i+j+1]=total%10 #key:对应取个位
                res[i+j] +=total//10 #key对应十位相加
        #
        index = 1 if res[0] == 0 else 0
        #
        return ''.join(str(x) for x in res[index:])

lc 204 :https://leetcode.cn/problems/count-primes/
提示:
0 <= n <= 5 * 10^6

#方案一:暴力解法(o(n^2))
#方案二:埃氏筛
class Solution:
    def countPrimes(self, n: int) -> int:
        #o(n)
        not_prime=[False]*n
        num=0
        #o(nlog(logn))
        for x in range(2,n):
            if not_prime[x]:continue
            num+=1
            #如果×是质数,那么2x、3x、4x...肯定不是质数
            for j in range(x+x,n,x):
                not_prime[j]=True
        #
        return num

lc 233 【剑指 43】:https://leetcode.cn/problems/number-of-digit-one/
提示:
0 <= n <= 10^9

#方案一:暴力超时
#方案二:找规律:(n//10*i)*i-min(max(n%10-i+1,0),i)
class Solution:
    def countDigitOne(self, n: int) -> int:
        #o(1)
        num=0
        #o(logn)
        i=1
        while i<=n:
            num +=(n//(10*i))*i+min(max(n%(10*i)-i+1,0),i)
            i*=10
        #
        return num

lc 1232 :https://leetcode.cn/problems/check-if-it-is-a-straight-line/
提示:
2 <= coordinates.length <= 1000
coordinates[i].length == 2
-10^4 <= coordinates[i][0], coordinates[i][1] <= 10^4
coordinates 中不含重复的点

class Solution:
    def checkStraightLine(self, coordinates: List[List[int]]) -> bool:
        #o(n)
        for i in range(2,len(coordinates)):
            deltaY=coordinates[1][1]-coordinates[0][1]
            deltaX=coordinates[1][0]-coordinates[0][0]
            
            deltaYi=coordinates[i][1]-coordinates[0][1]
            deltaXi=coordinates[i][0]-coordinates[0][0]
            #key
            if deltaY*deltaXi !=deltaX*deltaYi:return False
        #
        return True

以上是关于日常系列LeetCode《5·数学篇》的主要内容,如果未能解决你的问题,请参考以下文章

日常系列LeetCode《9·哈希查找篇》

日常系列LeetCode《10·栈和队列篇》

日常系列LeetCode《4·字符串篇》

日常系列LeetCode《13·综合应用1篇》

日常系列LeetCode《12·滑动窗口篇》

日常系列LeetCode《6·位运算篇》