LeetCode 新的开始day1
嗨嗨嗨。。。一个期末加春节,直接给我干颓废了,导致算法之旅被打乱,现在也是准备另起灶炉,好好学习一下了(虽然因为服务外包比赛这两个月挺消耗精力的,不够我还是打算抽点时间来算法这边散散心,然后也是有节奏的刷起来)
也是看到大佬提供的刷题路线,感觉很是适合咱,那有什么说的呢,干就完了,然后也打算每周六总结一次。
首先来到的是数学题路线(基础很重要好吧)
这里就说说今天遇到的两个重要的知识点
首先的话,就是辗转相除法求最大公因子
2427. 公因子的数目
给你两个正整数 a
和 b
,返回 a
和 b
的 公 因子的数目。
如果 x
可以同时整除 a
和 b
,则认为 x
是 a
和 b
的一个 公因子 。
示例 1:
输入:a = 12, b = 6
输出:4
解释:12 和 6 的公因子是 1、2、3、6 。
示例 2:
输入:a = 25, b = 30
输出:2
解释:25 和 30 的公因子是 1、5 。
class Solution {
public int commonFactors(int a, int b) {
int ant=0;
int c=gcd(a,b);
for(int i=1;i<=c;i++){
if(a%i==0&&b%i==0) ant++;
}
return ant;
}
public int gcd(int a,int b){
while(b!=0){
a%=b;
a^=b;
b^=a;
a^=b;
}
return a;
}
}
我的理解的话,首先基础公式---------->gcd(a,b)=gcd(a-b,b)。 gcd(a,0)=0.
所以我们可以想到能不能把gcd(a,b)往gcd(x,0)上靠呢,从而得到a,b的最大公因子为x。
我们可以设 a=k*b+c,所以c=a%b, gcd(a,b)—>gcd(a%b,b)。这里取余就是更上面的减法一样,不过相对于是每次减去了k个b,gcd(a,b)==gcd(b,a)是明显的,所以我们取余后交换保证a一直大于b就能一直将ab缩小,然后变为gcd(x,0)
接下来就是一个中等(力扣)的数学题
372. 超级次方
你的任务是计算 ab
对 1337
取模,a
是一个正整数,b
是一个非常大的正整数且会以数组形式给出。
示例 1:
输入:a = 2, b = [3]
输出:8
示例 2:
输入:a = 2, b = [1,0]
输出:1024
示例 3:
输入:a = 1, b = [4,3,3,8,5,2]
输出:1
示例 4:
输入:a = 2147483647, b = [2,0,0]
输出:1198
class Solution {
public final static int MOD = 1337;
public int superPow(int a, int[] b) {
return sp(a, b, b.length - 1);
}
public int quick_mul(int x, int n) {
x %= MOD;
if (n == 0) {
return 1;
} else if (n % 2 == 1) {
return quick_mul(x, n - 1) * x % MOD;
} else {
int temp = quick_mul(x, n / 2) % MOD;
return temp * temp % MOD;
}
}
public int sp(int a, int[] b, int len) {
if (len == -1) return 1;
return quick_mul(sp(a, b, len - 1), 10) * quick_mul(a, b[len]) % MOD;//len下标指向最小位,-1即为个位移向百位
}
}
这个题因为b数组长度是有达到两千的,所以肯定是不能直接调用数学库中的power函数,需要我们手写一个更加快速的方法,即快速幂。
这里暂时就不细说了,就像你求5的十次方,对于计算机来说,(55555)^2肯定比十个五相乘更快
而(25 * 25 * 5)^2显然更快,因为他们的计算次数分别为,9,5,4。
所以得到计算最优解
a^n=
{ n=0,a^n=1;
n%2==1,a^n=a^n-1*a;
n%2==0, a^n=a^n/2 * a^n/2;
}