【Leetcode】数与位

题目汇总

能完成:7/168/172/191/263/326/405/461/492/507/693

要优化:231/258/400

不会做:50/372

基础操作总结

转二进制:bin(n).replace('0b','') #因为bin生成的二进制字符串会带有'0b'的前缀

基础数学知识

乘法在取模的意义下满足分配律 即: (a*b) % m = (a%m * b%m) % m

完全数:所有的真因子(即除了自身以外的约数)之和恰好等于它本身 32位内只有5位完全数{6, 28, 496, 8128, 33550336}

数根 :将一正整数的各个位数相加(即横向相加),若加完后的值大于10的话,则继续将各位数进行横向相加直到其值为个位数为止; 数根=对9取余的结果

优化思路
231

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false

进阶:不使用循环/递归

思路一:转二进制后判断是否有且仅有一个1 return n > 0 and bin(n).count('1') == 1

trick :**binary&(binary-1)**return n > 0 and (n & (n-1)) == 0

若只有1个1,则(binary-1)会出现退位,该位置的1消失,进行按位与操作只能得到0

若有2个及以上的1,则(binary-1)会出现退位,但高位的1仍保持不变,进行按位与操作不能得到0

258

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。

进阶:不使用循环或者递归,时间复杂度 O(1)

数学推导:1.写出某个整数的求和表示;

2.用添1的方法凑出各个位上的数字和;

3.观察发现10^i-1都是9的倍数,故该整数对9的取余结果即为所需返回值;

特殊情况:取余结果为0:1.该数为0,返回0;2.该数不为0,返回9;

python 复制代码
class Solution(object):
    def addDigits(self, num):
        """
        :type num: int
        :rtype: int
        """
        return ((num-1)%9)+1 if num else 0

        #除开0后还需要输出的范围[1,9],而对9取余结果范围[0,8],故需要+1
400

给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n位上的数字

分析:1-9:9 // 10-99:90x2 // 100-999:900x3 // 1000-9999:9000x4

|----|-----|-------|---------|-----------|-----|--------------------------|
| 数字 | 1-9 | 10-99 | 100-999 | 1000-9999 | ... | ------ |
| 长度 | 9 | 90x2 | 900x3 | 9000x4 | ... | 900000000x9(>2**31-1) |

假设 n = 11:

1.根据长度可以判断是在几位数的范围里; 9<11<9+90x2 两位数

2.减去前一区间的长度总和再与当前位数相除就可以得到当前区间的相对位置; (11-9)//2=1

3.与前一区间的终点值相加得到其绝对数值; 9+1=10

4.根据余数判断在数值的哪一位; (11-9)%2=0 '0'

余数为0对应绝对数值的最后一位;余数为i则对应下一数值的第i位;

假设数值为123456:

取第一位:123456//100000=1

取第二位:123456//10000=12%10=2

...取第n位:123456//10**(len-n)%10

python 复制代码
class Solution(object):
    def largestPalindrome(self, n):
        """
        :type n: int
        :rtype: int
        """
        a, b = 1, 9
        while n > a*b:
            n = n - a*b
            a, b = a+1, b*10
        m = n//a + 10**(a-1) -1            #a为位数        
        return (m+1)//10**(a-n%a)%10 if n%a else m%10
解题思路
50

实现 pow(x,n) ,即计算 x 的整数 n 次幂函数(即,x^n

思路:n^1=n;n^2=n^1 * n;n^3=n^2 * n... 因此只需要一次循环实现连乘即可;

处理指数为负:去掉负号进循环,返回时若是负数则返回1.0/out

优化点:若求n^2m = n^m * n^m,若求n^(2m+1) = n^m * n^m * n

python 复制代码
class Solution(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """

        return 1.0/self.poww(x,-n) if n < 0 else self.poww(x,n)   #处理符号
        
    def poww(self, x, n):                                         #处理正幂
        if n == 0: return 1.0
        else:
            m = self.poww(x, n//2)
            return m*m*x if n%2 else m*m
372

你的任务是计算 a^b1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。

分析:处理以数组形式给出的b = [m, n] ,令 f(a,x) = a^x % k

f(a, mn) = [ a^(m*10)*a^n ] % k = [ f(a,m*10) * f(a,n) ] % k,而f(a,m*10) = (a^m)^10 % k = f(a^m, 10)

通过观察发现需要需要编写一个计算f(i,j)的函数poww(i,j),其中j-[0,10],

当j=0时,结果为1;

当j=1时,结果为a^k;

当j-[2,10]时,结果为 f(j) = [ f(j-1) * f(1) ] % k 需要循环j-1次

python 复制代码
class Solution(object):
    def superPow(self, a, b):
        """
        :type a: int
        :type b: List[int]
        :rtype: int
        """
        if a == 1: return 1                                  #直接结束
    
        if len(b)==1: return self.poww(a,b[-1])              #不需要拆分b
        else:
            out1 = self.superPow(a,b[-1:])                   #fn
            out2 = self.poww(self.superPow(a,b[:-1]),10)     #fm*10
            return (out1 * out2) % 1337

    def poww(self, a, b):     #计算a^b % k
        if b==0: return 1
        elif b==1:return a % 1337
        else: 
            out = f1 = a % 1337
            for _ in range(b-1): out = (out * f1) % 1337   #b-1次循环
            return out

#测试用时较长,内存占用较多

优化点:在求幂时用快速幂 50

相关推荐
ChoSeitaku27 分钟前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
DdddJMs__13533 分钟前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
Fuxiao___36 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我41 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui12 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农2 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲2 小时前
浏览器是加载ES6模块的?
javascript·算法