前言

如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。

在力扣刷题时,「数学」是大家绕不过去的内容。事实上,力扣题库中标签为「数学」的题共有 208 道,仅次于 243 道的「动态规划」。

然而对比「动态规划」,力扣题库中「数学」所涉及到的知识则要少很多,因此本篇文章将针对题库中「数学」所涉及的基础必备知识进行讲解,希望对大家日后刷题有所帮助。

基础运算

在「基础运算」部分,我们将主要介绍「位运算」与「快速幂」两个知识点。这两种运算方法难度不大,但却非常常见,属于必知必会的内容。

位运算

在计算机的世界中,一切数字都是二进制的。类比于现实世界中我们所使用的十进制,二进制即为「逢二进一」的运算体系。

我们以 B、D 来分别标记二进制与十进制,例如 10D 表示十进制中的 10,而 10B 则表示二进制中的 10。

回顾十进制,10D=1∗101+0∗10010D=1*10^1+0*10^010D=1∗101+0∗100,123D=1∗102+2∗101+3∗100123D=1*10^2+2*10^1+3*10^0123D=1∗102+2∗101+3∗100。

类比十进制,进一步理解二进制:10B=1∗21+0∗20=2D10B=1*2^1+0*2^0=2D10B=1∗21+0∗20=2D,1011B=1∗23+0∗22+1∗21+1∗20=11D1011B=1*2^3+0*2^2+1*2^1+1*2^0=11D1011B=1∗23+0∗22+1∗21+1∗20=11D。

由此我们可以发现,十进制就是「逢十进一」,而二进制就是「逢二进一」。

在计算机的运算过程中,所有的数字都是用「二进制」表示的,其中数字的每一位称为一个 bit,其取值要么为 0,要么为 1。

「位运算」是「二进制」所特有的运算,共分为 6 类,如下表所示:

运算符 名称 规则
& 两个位均为1,结果为1
| 两个位均为0,结果为0
^ 异或 两个位相同则为0,不同则为1
取反 0变1,1变0
<< 左移 二进制下所有位同时向左移动,低位以0填充,高位越界后舍弃
>> 右移 二进制下所有位同时向右移动,无符号数高位补0,有符号数则视编译器而定

我们以 1011B、0101B 举例(均为无符号数):

  • 1011B & 0101B = 0001B
  • 1011B | 0101B = 1111B
  • 1011B ^ 0101B = 1110B
  • ~1011B = 0100B
  • 1011B << 2 = 101100B
  • 1011B >> 2 = 10B

想要彻底掌握位运算,还需了解原码、反码、补码等知识,但由于本文重点并不在此,因此不再详细展开。

快速幂

接下来开始介绍「快速幂」算法,该算法常用于快速指数运算。

举个例子,如果想要计算 2312^{31}231 的具体数值,最少需要计算多少次可以完成?

一个比较显然的答案是从 111 开始连乘 313131 个 222,这样肯定可以得到准确的答案,但是否有更快的方法?

答案显然是「有」,如果我们用二进制来表示 313131,则可以得到:
31D=11111B=1∗20+1∗21+1∗22+1∗23+1∗24=1+2+4+8+1631D=11111B=1*2^0+1*2^1+1*2^2+1*2^3+1*2^4=1+2+4+8+16 31D=11111B=1∗20+1∗21+1∗22+1∗23+1∗24=1+2+4+8+16

由此我们可以将 2312^{31}231 进行转化,得到:
231=21+2+4+8+16=21∗22∗24∗28∗2162^{31}=2^{1+2+4+8+16}=2^1*2^2*2^4*2^8*2^{16} 231=21+2+4+8+16=21∗22∗24∗28∗216

因此我们只需要求出 21,22,24,28,2162^1,2^2,2^4,2^8,2^{16}21,22,24,28,216,再将它们依次相乘,就可以得到 2312^{31}231。

与此同时,22=21∗21,24=22∗22,...,216=28∗282^2=2^1*2^1,2^4=2^2*2^2,...,2^{16}=2^8*2^822=21∗21,24=22∗22,...,216=28∗28,因此我们从 111 开始只需要计算 555 次即可求出 21,22,24,28,2162^1,2^2,2^4,2^8,2^{16}21,22,24,28,216。再将这几个数字依次乘起来,就得到了 2312^{31}231。

这种通过将指数转化为二进制,并以此来加快幂运算的方法就是快速幂。当计算 axa^xax(aaa 为任意实数)时,快速幂方法可以将原来的 O(x)O(x)O(x) 时间复杂度降低为 O(log(x))O(log(x))O(log(x)),从而大大加快指数运算。

此处建议大家再手动地用快速幂计算下 2142^{14}214 的值,可进一步加深对该算法的理解。

实现该算法所需代码并不长,大家可以手动实现,也可以参考下述代码:

// 计算 a ^ b
int poww (int a, int b) {int base = a, ans = 1;while (b) {if (b & 1) ans *= base;base *= base;b >>= 1;}return ans;
}

质数

讲解完「基础运算」部分后,我们开始正式进入「数论入门知识」,该部分内容主要围绕「质数」进行展开。

首先回顾「质数」的定义:

若一个正整数无法被除了 111 和它自身之外的任何自然数整除,则称该数为质数(或素数),否则称该正整数为合数。

根据上述定义,我们可以得知常见的质数有 222、333、555 等。另外,在整个自然数集合中,质数的数量并不多,分布也比较稀疏,对于一个足够大的整数 NNN,不超过 NNN 的质数大约有 N/ln(N)N/ln(N)N/ln(N) 个。

质数判定

常见的判定质数的方式是「试除法」,假设自然数 NNN 不是质数,则一定存在一对数 x,y(x≤y)x,y(x\leq y)x,y(x≤y),使得下述条件成立:
N=x∗y1<x≤N≤y<NN=x*y \\ 1< x\leq\sqrt N\leq y<N N=x∗y1<x≤N​≤y<N

因此我们可以在 [2,N][2,\sqrt N][2,N​] 的范围内枚举 xxx,判断 xxx 是否存在。

如果 xxx 存在,则 NNN 为合数;否则 NNN 为质数。该算法时间复杂度为 O(N)O(\sqrt N)O(N​),具体代码如下所示:

bool judgePrime(int n) {for (int i = 2; i * i <= n; i++) {if (n % i == 0) return false;}return true;
}

质数筛选

对于一个正整数 NNN,一次性求出 1~N1~N1~N 之间所有的质数,即为质数筛选。

显然根据上述「质数判定」的内容,我们可以通过枚举 1~N1~N1~N 的所有数,再依次使用「试除法」来判定其是否为质数,从而完成质数的筛选。但此种方法的时间复杂度过高,为 O(NN)O(N\sqrt N)O(NN​)。

此处将介绍经典的「Eratosthenes 筛法」,也被称为「埃式筛」。该算法基于一个基本判断:任意质数 xxx 的倍数(2x,3x,...2x,3x,...2x,3x,...)均不是质数。

根据该基本判断,我们得到如下算法过程:

  • 将 2~N2~N2~N 中所有数标记为 0
  • 从质数 222 开始从小到大遍历 2~N2~N2~N 中所有自然数
  • 如果遍历到一个标记为 0 的数 xxx,则将其 2~N2~N2~N 中 xxx 的所有倍数标记为 1

根据上述过程,不难发现如果一个数 xxx 的标记为 000,则代表这个数不是 2~(x−1)2~(x-1)2~(x−1) 中任何数的倍数,即 xxx 为质数。

接下来我们以 2~102~102~10 为例,具体过程如下所示,最终标记为橙色的数为质数:

「Eratosthenes 筛法」的时间复杂度为 O(Nlog(log(N)))O(Nlog(log(N)))O(Nlog(log(N))),并不是最快的素数筛法,但在绝大多数的「力扣数学题」中均以够用,且其实现代码较为简单,具体如下所示:

vector<int> primes, vis;
void get_primes(int n) {vis.resize(n + 1, 0);for(int i = 2; i <= n; i++) {if(vis[i] == 0) {primes.push_back(i);for(int j = i; j <= n; j += i) vis[j] = 1;}}
}

质因数分解

根据「唯一分解定理」,任何一个大于 111 的正整数都能唯一分解为有限个质数的乘积:
N=p1c1p2c2...pmcmN=p_1^{c_1}p_2^{c_2}...p_m^{c_m} N=p1c1​​p2c2​​...pmcm​​
其中 cic_ici​ 均为正整数,而 pip_ipi​ 均为质数,且满足 p1<p2<...<pmp_1<p_2<...<p_mp1​<p2​<...<pm​。

根据上述定理,我们只需要求出所有的 pi,cip_i,c_ipi​,ci​,即可完成对 NNN 的质因数分解。

那么如何求取 pi,cip_i, c_ipi​,ci​ 呢?首先我们考虑如何求 p1p_1p1​ 和 c1c_1c1​。

由于 p1<p2<...<pmp_1<p_2<...<p_mp1​<p2​<...<pm​,且 p1p_1p1​ 为质数,因此不难发现,p1p_1p1​ 是 NNN 所有因子中除 111 以外最小的数。

因此我们可以枚举 2~N2~\sqrt N2~N​ 中的所有数 xxx,如果 NNN 是 xxx 的倍数,则 xxx 为 p1p_1p1​。得到 p1p_1p1​ 后,我们可以令 NNN 不断除以 p1p_1p1​ 直至其不再为 p1p_1p1​ 的倍数,则 c1c_1c1​ 等于除以 p1p_1p1​ 的总次数。

得到 p1p_1p1​ 和 c1c_1c1​ 后,NNN 去除了所有的 p1p_1p1​,因此 NNN 变为 p2c2...pmcmp_2^{c_2}...p_m^{c_m}p2c2​​...pmcm​​。又由于 p1<p2p_1<p_2p1​<p2​,因此我们继续枚举 xxx,如果再次出现 NNN 是 xxx 倍数的情况,则 xxx 为 p2p_2p2​。

不断使用上述算法,直至循环结束。最后还需判断 NNN 是否为 111,如果 NNN 不为 111,则 pm=N,cm=1p_m=N,c_m=1pm​=N,cm​=1。

该算法的时间复杂度为 O(N)O(\sqrt N)O(N​),具体代码如下所示,大家可以配合代码对该算法进行理解:

void divide(int n) {vector<int> p, c;for (int i = 2; i * i <= n; i++) {if (n % i == 0) {p.push_back(i);int num = 0;while(n % i == 0) num++, n /= i;c.push_back(num);}}if (n > 1) {p.push_back(n);c.push_back(1);}
}

互质判定

最后我们介绍一下如何判断两个自然数互质。

首先介绍一下「最大公约数」的概念。如果自然数 ccc 同时是自然数 aaa 和 bbb 的约数,即 aaa 和 bbb 同时是 ccc 的倍数,则 ccc 为 aaa 和 bbb 的公约数。

「最大公约数」就是 aaa 和 bbb 的所有公约数中最大的那一个,通常记为 gcd(a,b)gcd(a,b)gcd(a,b)。

由此我们可以得到「互质」的判定条件,如果自然数 a,ba,ba,b 互质,则 gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1。

于是问题变为「如何求 gcd(a,b)gcd(a,b)gcd(a,b) ?」

此处需要引入「欧几里得算法」,如下所示:
∀a,b∈N,b≠0,gcd(a,b)=gcd(b,amodb)\forall a,b\in \mathbb{N},b\not=0,gcd(a,b)=gcd(b,a\ mod\ b) ∀a,b∈N,b​=0,gcd(a,b)=gcd(b,a mod b)

根据上述算法,可以得到如下代码,其时间复杂度为 O(log(a,b))O(log(a,b))O(log(a,b)):

int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);
}

另外,再介绍一个常见的定理 ——「裴蜀定理」:

  • 若 a,b,x,y,ma,b,x,y,ma,b,x,y,m 是整数,则 ax+by=max+by=max+by=m 有解当且仅当 mmm 是 gcd(a,b)gcd(a,b)gcd(a,b) 的倍数。

该定理有一个重要的推论:整数 a,ba,ba,b 互质的充要条件是存在整数 x,yx,yx,y 使 ax+by=1ax+by=1ax+by=1。

习题练习

50. Pow(x, n)

题目描述

实现 pow(x,n)pow(x, n)pow(x,n),即计算 xxx 的 nnn 次幂函数。

示例 1

输入: 2.00000, 10
输出: 1024.00000

示例 2

输入: 2.10000, 3
输出: 9.26100

示例 3

输入: 2.00000, -2
输出: 0.25000
解释: 2^(-2) = (1/2)^2 = 1/4 = 0.25

说明

  • -100.0 < x < 100.0
  • n 是 32 位有符号整数,其数值范围是 [−231,231−1][−2^{31}, 2^{31} − 1][−231,231−1]。

解题思路

此题是快速幂的模板题,主要有两个细节需要注意:

  1. nnn 可能为负数
  2. xxx 可能为 0

如果 nnn 为负数,则 xn=(1x)−nx^n=(\frac{1}{x})^{-n}xn=(x1​)−n,转换一下即可。另外,由于此处出现了 1x\frac{1}{x}x1​,因此需要对 x=0x=0x=0 的情况进行特判。

处理好上述两点后,即可使用快速幂的模板代码完成此题。

代码实现

class Solution {public:double myPow(double x, int n) {double ans = 1;if (x == 0) return 0;if (n < 0) {n = - (n + 1);x = 1 / x;ans = x;}while (n) {if (n & 1) ans *= x;x *= x;n >>= 1;}return ans;}
};

204. 计数质数

题目描述

统计所有小于非负整数 n 的质数的数量。

示例 1

输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7。

示例 2

输入:n = 0
输出:0

示例 3

输入:n = 1
输出:0

解题思路

此题为「质数筛选」的模板题,可以使用前文讲过的「Eratosthenes 筛法」通过此题,具体细节见代码。

代码实现

class Solution {public:vector<int> vis;int countPrimes(int n) {vis.resize(n, 0);int ans = 0;for (int i = 2; i < n; i++) {if (!vis[i]) {ans++;for (int j = i; j < n; j += i) vis[j] = 1;}}return ans;}
};

365. 水壶问题

题目描述

有两个容量分别为 x 升和 y 升的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z 升的水?

如果可以,最后请用以上水壶中的一或两个来盛放取得的 z 升水。

你允许:

  • 装满任意一个水壶
  • 清空任意一个水壶
  • 从一个水壶向另外一个水壶倒水,直到装满或者倒空

示例 1

输入: x = 3, y = 5, z = 4
输出: True

示例 2

输入: x = 2, y = 6, z = 5
输出: False

解题思路

观察题干中给定的三种操作,不难发现在整个过程中,两个桶都不可能同时有水且不满。

有了这个基本判断之后,我们可以发现「装满一个有水但不满的桶」是没有意义的。因为当前桶有水但不满,意味着另外一个桶要么为空,要么全满,因此如果把当前桶再变为满,则不如直接一开始就把当前桶加满。

与此同理,「清空一个有水但不满的桶」也是没有意义的,因为另一个桶非空即满。

所以我们不难发现,「装满任意一个水壶」只会让总水量增加 xxx 或 yyy,「清空任意一个水壶」只会让总水量减少 xxx 或 yyy,「从一个水壶向另一个水壶倒水」,总水量不变。

由此每次操作只会给总水量带来 xxx 或 yyy 的变化量,因此本题可以改写为:

  • 找到一对整数 a,ba,ba,b,使得 ax+by=zax+by=zax+by=z,且 z≤x+yz\leq x+yz≤x+y

根据「裴蜀定理」,只要 zzz 是 gcd(x,y)gcd(x,y)gcd(x,y) 的倍数,就一定存在一对整数 a,ba,ba,b 满足题意,由此本题得以顺利解决。

代码实现

class Solution {public:int gcd(int x, int y) {return y == 0 ? x : gcd(y, x%y);}bool canMeasureWater(int x, int y, int z) {int g = gcd(x, y);if (z == 0 || (g != 0 && z % g == 0)) {if (z > x + y) return 0;else return 1;}else return 0;}
};

LCP 14. 切分数组

题目描述

给定一个整数数组 nums,小李想将 nums 切割成若干个非空子数组,使得每个子数组最左边的数和最右边的数的最大公约数大于 1。为了减少他的工作量,请求出最少可以切成多少个子数组。

示例 1

输入:nums = [2,3,3,2,3,3]
输出:2
解释:最优切割为 [2,3,3,2] 和 [3,3]。第一个子数组头尾数字的最大公约数为 2,第二个子数组头尾数字的最大公约数为 3。

示例 2

输入:nums = [2,3,5,7]
输出:4
解释:只有一种可行的切割:[2], [3], [5], [7]

限制

  • 1≤nums.length≤1051\leq nums.length\leq 10^51≤nums.length≤105
  • 2≤nums[i]≤1062\leq nums[i]\leq 10^62≤nums[i]≤106

解题思路

将一个数组切分为多个子数组,此类型题目常见于「动态规划」算法,因此我们用「动态规划」算法来考虑此题。

定义 f[i]f[i]f[i] 表示仅考虑前 iii 个数,最少可以划分为多少个子数组。则我们可以得到如下转移方程:
f[i]=min(f[i],f[j]+1),满足gcd(nums[i],nums[j+1])>1f[i]=min(f[i], f[j]+1), 满足\ gcd(nums[i], nums[j+1])>1 f[i]=min(f[i],f[j]+1),满足 gcd(nums[i],nums[j+1])>1
注意 f[0]=0,f[i]=inf,i≥1f[0]=0,f[i]=inf,i\geq1f[0]=0,f[i]=inf,i≥1,infinfinf 表示一个很大的值。

然而,上述转移方程的时间复杂度为 O(n2log(n))O(n^2log(n))O(n2log(n))(考虑还需求解 gcdgcdgcd),因此该方法需要进一步优化。

回顾一下之前介绍过的「唯一分解定理」:任何一个大于 111 的正整数都能唯一分解为有限个质数的乘积:
N=p1c1p2c2...pmcmN=p_1^{c_1}p_2^{c_2}...p_m^{c_m} N=p1c1​​p2c2​​...pmcm​​
其中 cic_ici​ 均为正整数,而 pip_ipi​ 均为质数,且满足 p1<p2<...<pmp_1<p_2<...<p_mp1​<p2​<...<pm​。

由此我们可以发现,如果两个数 gcd(a,b)>1gcd(a, b)>1gcd(a,b)>1,则说明其唯一分解后存在相同的质数。因此我们从「质数分解」的角度入手,对上述「动态规划过程」进行进一步修改。

重新定义 f[N]f[N]f[N] 数组,以及 last,nowlast, nowlast,now 变量。依次遍历整个 numsnumsnums 数组,假设当前遍历到的位置为 i+1i+1i+1,则 f[j]f[j]f[j] 表示仅考虑前 iii 个位置,存在一个位置 pospospos 使得 nums[pos]nums[pos]nums[pos] 的值唯一分解后存在 jjj 这个质数,且数组 1~(pos−1)1~(pos-1)1~(pos−1) 最少切分的子数组个数最少。

lastlastlast 表示前 iii 个数最小切分的子数组个数,而 nownownow 表示前 i+1i+1i+1 个数的答案。因此假如 nums[i+1]=∏picinums[i+1]=\prod p_i^{c_i}nums[i+1]=∏pici​​,令 j=pij=p_ij=pi​,则如下图所示,我们可以用 f[j]+1f[j]+1f[j]+1 来更新 nownownow 的值。

具体更新公式如下:
now=min(now,f[pi]+1)f[pi]=min(f[pi],last)now=min(now, f[p_i]+1) \\ f[p_i]=min(f[p_i], last) now=min(now,f[pi​]+1)f[pi​]=min(f[pi​],last)

lastlastlast 和 nownownow 的初值分别为 000 和 111,每遍历完一个点,令 last=now,now=now+1last=now,now=now+1last=now,now=now+1。

遍历数组的过程中同时更新 f,last,nowf,last,nowf,last,now,最终答案为 now−1now-1now−1。

至此该问题转化为「如何对数组中每个数质数分解」。

之前我们「质数分解」的复杂度为 O(n)O(\sqrt n)O(n​),因此如果使用之前的「质数分解」方法,本题复杂度将变为 O(nn)O(n\sqrt n)O(nn​),无法通过。

所以我们需要对原先的质数分解算法进行优化,我们需要先求出 1~1061~10^61~106 中每个数 kkk 的最小质因子 prime[k]prime[k]prime[k],即可将「质数分解」的复杂度降为 log(n)log(n)log(n),具体过程如下:

  1. x=nums[i]x=nums[i]x=nums[i]
  2. prime[x]prime[x]prime[x] 为当前 xxx 的最小质因子
  3. x=x/prime[x]x=x/prime[x]x=x/prime[x]
  4. 如果 x=1x=1x=1 则退出,否则回到步骤 222

于是问题进一步转化为「如何求出 1~1061~10^61~106 中每个数 kkk 的最小质因子 prime[k]prime[k]prime[k]」。

考虑之前「Eratosthenes 筛法」的过程,每一个合数都会被其所有质数标记,即:

  • 若 kkk 为合数,则第一次标记 kkk 的质数即为 prime[k]prime[k]prime[k]
  • 若 kkk 为质数,则 prime[k]=kprime[k]=kprime[k]=k

至此我们成功完成了此题,最终复杂度为 O(nlog(n))O(nlog(n))O(nlog(n))。

代码实现

class Solution {public:vector<int> prime, f;void get_primes(int n) {prime.resize(n + 1, 0);for(int i = 2; i <= n; i++) {if(!prime[i]) {for(int j = i; j <= n; j += i) {if (!prime[j]) prime[j] = i;}}}}int splitArray(vector<int>& nums) {get_primes(1e6);f.resize(1e6, 1e6); // 初始化为极大值-infint last = 0, now = 1;for(int i = 0; i < nums.size(); i++) {// 唯一分解int v = nums[i];while(v > 1) {int p = prime[v];now = min(now, f[p] + 1);f[p] = min(f[p], last);while(v % p == 0) v /= p;}last = now, now = now + 1;}return now - 1;}
};

总结

本文的总体框架如下,重点主要在于「基础运算」与「质数」部分中各算法的理解与掌握。

本文所介绍的算法均为力扣题库「数学」部分所涉及的基础算法,希望大家能够留个印象,在日后刷题时能及时想起。

最后祝大家刷题愉快!

刷算法题必备的基础数论知识相关推荐

  1. 刷算法题常用的 JS 基础扫盲

    大厂技术  高级前端  Node进阶 点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 介绍 此篇属于前端算法入门系列的第一篇,主要介绍常用的数组方法.字符串方法.遍历方法.高阶函 ...

  2. 新手如何有效的刷算法题(LeetCode)

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 来源:五分钟学算法 前言 作为一名非科班出身的程序员,我是参加工作之后才开始接触算法,学 ...

  3. 牛客网刷算法题的输入输出(C++)

    内容简述 该篇文章将对牛客网刷题中关于输入输出的一些问题作一个总结.每年互联网公司的招聘都必不可少会有算法题,因此平时很多人都会去一些刷题网站进行刷题来学习.这里面用的比较多的刷题网站是leetcod ...

  4. 43. 盘点那些必问的数据结构算法题之二叉树基础

    盘点那些必问的数据结构算法题之二叉树基础 0 概述 1 定义 2 基本操作 1) 创建结点 2) BST 插入结点 3) BST 删除结点 4) BST 查找结点 5)BST 最小值结点和最大值结点 ...

  5. RSA算法原理——(2)RSA简介及基础数论知识

    上期为大家介绍了目前常见加密算法,相信阅读过的同学们对目前的加密算法也算是有了一个大概的了解.如果你对这些解密算法概念及特点还不是很清晰的话,昌昌非常推荐大家可以看看HTTPS的加密通信原理,因为HT ...

  6. 用Java刷算法题的常用数据结构(C++转Java)

    文章目录 一:前言 1:为何刷题从C++转java 2:如何上手呢? 二:输入 1:常规的输入 2:关于其他输入符在nextLine()之前用吃掉回车符的问题解决 3:常见输入之我们输入一串数到容器中 ...

  7. 靠刷算法题,真的可以刷进大厂吗?

    我一直不知道我在大家心目中的定位是什么,但我内心其实是把自己定义为一个『工具人』的. 可能是因为我自己本身就是程序员,所以更能理解程序员的不易吧. 所以,我尽量不写水文,只分享干货. 就是希望大家看了 ...

  8. 刷算法题需要的java语法_蓝桥杯java b组需要重点刷什么算法呢?

    我觉得这个问题我很适合回答.不过距离我最后一次参赛,已经有了三年,所以回答的内容重点可能有点偏(建议你,可以到网上找找最新的获奖选手赛后总结看看),但是我觉得应该对你有用. 我本科也在湖北,并且参加过 ...

  9. 字节跳动面试前端岗,刷算法题有救吗?

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来. 去年,有位学长参加秋招的时候,拿到了字节跳动.快手.阿里.美团--等等 ...

  10. 【c/c++】刷算法题时常用的函数手册 持续更新--

    在做算法题的时候,有时候为了高效的做题,我们会使用一些函数,但是常用的函数确实太多了,时不时的会忘记一些 于是我整理了一些常用的函数,方便自己查找和别人使用. 都是超链接,点击直接跳转到对应的内容. ...

最新文章

  1. java项目怎样强制删除手机缓存_Myeclipse清理项目缓存的几大方法
  2. 堆叠与M-LAG,为什么要从堆叠切换为M-LAG?
  3. 云端能力知几许?12人众测华为云企业级Kubernetes集群实力
  4. [云炬创业基础笔记]第二章创业者测试23
  5. C#多线程和异步(二)——Task和async/await详解
  6. C#多线程技术总结(异步)
  7. Div+CSS教程----DivCSS布局绝对定位和浮动
  8. Heart Rate Estimate
  9. Python——print()函数的学习笔记
  10. ubuntu下Chrome浏览器字体问题 字体发虚解决办法
  11. PHP file_get_contents与file_put_contents
  12. JavaScript高级程序设计 中文PDF下载
  13. 第6章 Stata方差分析
  14. 如何申请:悟空问答,达人,金V认证!
  15. IDE输入import语句自动消失
  16. 论文画图——eps格式的图
  17. mysql 设置双1_2020-10-15:mysql的双1设置是什么?
  18. 中兴付,为钱包赋予生命
  19. Armadillo配置
  20. 安卓app开发工具_手机APP是怎么开发的,需要学习哪些知识?

热门文章

  1. NO.109 禅道“红火”新年小礼,祝大家2014红红火火~~
  2. Linux双网卡bonding举例
  3. ISA2000资料大全(详细)
  4. Java中String类型,int类型,double类型相互转换
  5. java提取日志sql,通过Java程序抽取日志中的sql语句
  6. linux shell 学习时遇到的一些问题([: 11: y: unexpected operator)
  7. c++课程设计(水)
  8. cantor数表 and nyoj85有趣的数
  9. dude由于目标计算机,The Dude的教程
  10. ios浏览器微信支付回调页面_iOS微信系列,WKWebview加载H5进行微信支付返回浏览器解决方案!...