Leetcode——数论

62.不同路径

方法:组合数学
思路与算法 C m + n − 2 m − 1 = ( m + n − 2 ) ! ( n − 1 ) ! ( m − 1 ) ! C_{m + n - 2}^{m - 1} =\frac{(m + n - 2)!}{(n - 1)!(m - 1)!} Cm+n2m1=(n1)!(m1)!(m+n2)!
注意事项:在计算过程中,中间值的大小可能会超过int所表示的范围,因此我们要把结果定义为long long

172.阶乘后的零

方法:分解质因数
思路与算法 n ! n! n!尾零的数量即 n ! n! n!中因子为10的个数。而 10 = 2 × 5 10 = 2 \times 5 10=2×5,因此转换为求解 n ! n! n!中质因子2的个数和质因子5的个数的较小值。由于质因子5的个数不会大于质因子2的个数,因此我们仅考虑质因子为5的个数。 n ! n! n!中质因子5的个数等于区间 [ 1 , n ] [1,n] [1,n]中每个数的质因子5的个数之和,因此通过遍历 [ 1 , n ] [1,n] [1,n]所有5的倍数求得。

204.筛质数

最全的三种筛质数方法及筛质数应用

  1. 暴力筛法
  2. 埃氏筛法
  3. 线性筛法

263.丑数
264.丑数II

思路和算法:多路归并。

丑数的定义是质因子只包含2,3,5的正整数。可按照丑数的定义把丑数集合S分为三大类;

  1. 集合S1:包含质因子2的丑数,即 1 × 2 , 2 × 2 , 3 × 2 , 4 × 2 , 5 × 2 , ⋅ ⋅ ⋅ 1\times 2,2\times 2,3\times 2,4\times2,5\times 2,\cdot\cdot\cdot 1×2,2×2,3×2,4×2,5×2,
  2. 集合S2:包含质因子3的丑数,即 1 × 3 , 2 × 3 , 3 × 3 , 4 × 3 , 5 × 3 , ⋅ ⋅ ⋅ 1\times 3,2\times 3,3\times 3,4\times3,5\times 3,\cdot\cdot\cdot 1×3,2×3,3×3,4×3,5×3,
  3. 集合S3:包含质因子5的丑数,即 1 × 5 , 2 × 5 , 3 × 5 , 4 × 5 , 5 × 5 , ⋅ ⋅ ⋅ 1\times 5,2\times 5,3\times 5,4\times5,5\times 5,\cdot\cdot\cdot 1×5,2×5,3×5,4×5,5×5,

集合S1S2S3的并集就是集合S。需要注意的是,集合S1S2S3有重复的元素。

通过观察集合S1S2S3不难发现,集合S1是集合S中所有的元素乘以2得到、S2集合S中所有的元素乘以3得到,S3集合S中所有的元素乘以5得到。于是可以一边构造集合S的同时利用集合S构造集合S1S2S3

具体做法如下:

  1. 初始时,指针i,j,k同时指向集合S的最小值1
  2. 用指针i,j,k所指的元素生成集合S1S2S3的元素,即S[i] × 2 \times 2 ×2,S[i] × 3 \times 3 ×3,S[i] × 5 \times 5 ×5
  3. 寻找上述生成的三个数中的最小值,并把最小值加入到集合S
  4. 更新最小值的所关联的指针,更新方式:++。值得注意的是可能有多个最小值,应该一起更新。

319.灯泡开关

最后亮着的灯满足该条件:它有奇数个约数。又因为有奇数个约数的数字是完全平方数,因此问题转换为在区间[1,n]中求解完全平方数的个数。


357.统计各位数字都不同的数字个数

就是一个简单排列问题。


365.水壶问题


这道题目很重要,一方面字节和今日头条都考察过它,另一方面它可以用深度优先搜索来做。

思路和算法

  1. 深度优先搜索
  2. 数学

深度优先搜索

记两个水壶为XY,xy分别是这两个水壶的体积。把某一时刻XY里的水量认为是一种状态,每次只能对其做如下更改:

  1. X里的水装满
  2. Y里的水装满
  3. X里的水倒掉
  4. Y里的水倒掉
  5. X里的水倒向Y
  6. Y里的水倒向X

初始状态XY水量均为0,遍历所有可能的状态,直到遍历完所有的状态。若某一时刻XY中的其中一个水量等于target或两水壶总水量等于target,则返回true

为了避免无限递归,利用哈希表记录每一个状态。注意,这里的状态是用两个数字描述,是一个对组pair。然而标准库中并未定义对组的哈希函数,因此需要定义对组的哈希函数。这涉及到了lambda表达式和decltype知识点。

在具体实现时,并未使用递归函数,而是使用栈 + 循环达到深度优先搜索的目的。

数学

记号同上。把XY认为是一个独立的系统。该系统与外界进行交互,每次交互只有四种操作:

  1. 向该系统中添加x升水
  2. 从该系统中拿走x升水
  3. 向该系统中添加y升水
  4. 从该系统中拿走y升水

注意,系统内部两个水壶之间水的交换不属于系统与外界的交互。

从系统的角度来看,问题等价于向系统中添加ax升水和向系统中添加by升水,系统中的总水量是否会等于target

用数学语言描述,是否存在a,b,使得 a × x + b × y = t a r g e t a\times x + b \times y = target a×x+b×y=target成立。

依据裴蜀定理,若targetx,y的最大公约数的倍数,那么一定存在a,b,使得 a × x + b × y = t a r g e t a\times x + b \times y = target a×x+b×y=target成立。

因此,问题进一步转换为求解xy的最大公约数。最大公约数的求解方法如下;

int gcd(int a,int b){
    return b ? gcd(b, a % b) : a;// a和b的最大公约数等于b和a % b的最大公约数
}

是不是只要满足target能被gcd(x,y)就可以了呢?当然是不行的。target必须小于等于x + y且大于等于0。


372.超级次方


这道题目是快速幂。

最近刷题有一个体会,知道用哪种方法来做,可就是不会用。就比如这道题目,知道使用快速幂,但是不知道如何使用快速幂。

最开始的代码是这样的:

int superPow(int a, vector<int>& b) {
        // a^b % 1337
        // 可以使用快速幂
        // 预处理a^0 - a^9
        vector<int> pow(11,1);
        for(int i = 1;i < 11;++ i){
            pow[i] = (long long)pow[i - 1] * a % N;
            cout << pow[i] << " ";
        }

        int res = 1;
        for(int i = b.size() - 1;i >= 0;-- i){
            res = (long long)res * pow[b[i]] % N;
            if(i > 0) res = (long long)res * pow[10] % N;
        }

        return res;
    }

这么写的原因是我以为 a 10 × b + c = a b × a c × a 10 a^{10 \times b + c} = a^b \times a^c \times a^{10} a10×b+c=ab×ac×a10,还是太想当然了。

实际上, a 10 × b + c = a c × ( a 10 ) b a^{10 \times b + c} = a^c \times (a^{10})^b a10×b+c=ac×(a10)b,在每遍历完b中的一个数字时,要及时更新a


400.第N位数字

算法步骤如下:

  1. 确定大区间,即确定即第n位上的数字所属的整数是几位数
  2. 在大区间中确定偏移量,即确定第n位数字所属整数在大区间的位置
  3. 确定整数内偏移量。若偏移量为0,则返回最低位;否则返回第n位(从左到右排列)。

441.排列硬币

1. 暴力解法

从第 1 1 1行开始模拟硬币排列过程,直到剩余硬币个数小于当前行所需的硬币个数为止。

int res = 1;
for(; res < n;++ res){
    n -= res;
}
return res - 1;
1.1 复杂度
  1. 时间复杂度:阶梯最后一行行数满足等差数列求和公式: ( x + 1 ) × x 2 ≤ n \frac{(x + 1) \times x}{2} \leq n 2(x+1)×xn,且 x x x最大,所以时间复杂度是 O ( 2 n ) O(\sqrt{2n}) O(2n )
  2. 空间复杂度: O ( 1 ) O(1) O(1)

2. 二分查找

不难看出,排列硬币阶梯状的行数构成了公差为 1 1 1的等差数列,由等差数列的求和公式 S n = n × a 1 + n × ( n − 1 ) 2 × d S_n = n \times a_1 + \frac{n \times (n - 1)}{2}\times d Sn=n×a1+2n×(n1)×d可得,题目的等差数列满足:
( x + 1 ) × x 2 ≤ n \frac{(x + 1) \times x}{2} \leq n 2(x+1)×xn

于是问题转换为求解最大的 x x x,可以使用二分查找的算法。

2.1 复杂度
  1. 时间复杂度: O ( log ⁡ n ) O(\log{n}) O(logn)
  2. 空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值