
文章目錄
- 前言
- 一、刷提前的準備
- 1、編程語言
- 2、編程環境
- 3、測驗用例
- 二、推薦的書
- 1、LeetCode零基礎指南
- 2、演算法導論
- 三、零基礎如何刷LeetCode
- 1、水題
- 2、多維思考
- 3、舉一反三
- 4、參加九日集訓
- 四、如何學習演算法
- 1、系統整理
- 2、解題劃級
- 五、零基礎演算法十題入門
- 1、求1+2+…+n
- 2、遞回乘法
- 3、斐波那契數
- 4、n 的第 k 個因子
- 5、統計平方和三元組的數目
- 6、找出陣列的最大公約數
- 7、最大三角形面積
- 8、陣列異或操作
- 9、整數的各位積和之差
- 10、統計位數為偶數的數字
- 六、如何總結
- 七、演算法專欄推薦
- 八、配套贈送福利
前言
??你為什么要刷題!如果你只是因為想找到一份好的作業而來刷題,那我勸你放棄這個念頭!因為,你堅持不了!任何帶有功利性的行為,在沒有得到應有的回報之前,都不能很好的堅持下來,刷題應該成為一種習慣,有了習慣就會有自驅力,養成習慣以后你就會愛上它,本文就來教你如何愛上刷題,
<iframe id="4S7zPz64-1638746456127" src="https://player.bilibili.com/player.html?aid=592162487" allowfullscreen="true" data-mediaembed="bilibili"></iframe>
點擊地址觀看完整版
一、刷提前的準備
1、編程語言
??首先是編程語言,推薦學習 C語言, 因為C語言陪我度過了我的青春,讓我的青春不留遺憾!當然,我是認真的,原因就是情懷,有情懷,才能有動力繼續做下去,每當敲出這個符號->的時候,你是否有一絲悸動,這是C程式員的崢嶸歲月!
2、編程環境
??其次是編程環境,可以直接用 LeetCode 官方提供的環境,這樣就躲過了安裝環境的復雜步驟,很多人可能是被環境的配置所勸退的,這就太可惜了,
??所謂,工欲善其事,必先利其器,環境整好了,也就成功了一半!
??如下圖所示:
??藍色框 代表選擇的語言;
??紅色框 代表編碼框;
??橙色框 代表測驗用例框;
??黃色框 代表本地除錯按鈕;
??綠色框 代表提交按鈕;

3、測驗用例
??第三點,就是一定要學會寫測驗用例,當你答案錯誤的時候,千萬不要著急,也不要急著找大神來看代碼為什么錯了,很多人一旦錯誤就把代碼貼到群里讓大家一起看,這樣只能把別人的能力不斷變強,自己則會越來越弱,
??根據題目的條件,造一些合適的資料,如果執行結果和官方的不一致,再去查代碼錯誤的原因,就會更加有方向,

二、推薦的書
1、LeetCode零基礎指南
??我推薦一開始不要看書,對于程式員來說,實踐才是最重要的,你在敲代碼的時候一定是在電腦邊,所以可以網上找一些演算法資料會比看書更有用,比如下面這個專欄就是為力扣零基礎的玩家量身訂做的:
??這個專欄主要講解了一些 LeetCode 刷題時的一些難點和要點,主要分為以下幾個章節,并且會持續補充一些有關于方法論的文章,文章有試讀,可以簡單先看一看試讀文章,
2、演算法導論
??很多人問這本書,這本書太過深奧,初學者我不太推薦去看,
三、零基礎如何刷LeetCode
1、水題
??一開始千萬不要急著學演算法,就按照自己十幾年的經驗,找 100 道水題水一水,什么是水題,就是 通過的人多,并且 標簽為簡單 的題,這種題一定夠水,類似問題一起刷,多練習,多思考,多總結,多復盤,馬山就能湊夠 100 道了,

2、多維思考
??一個題水過了以后,千萬不要驕傲,想想其它辦法,用多種方法把它過掉它,鍛煉你的多路思維,比如一個問題你可能是通過暴力列舉的方法過掉的,它的時間復雜度可能是 O ( n 2 ) O(n^2) O(n2),可以試著用 二分查找 轉換成 O ( n l o g 2 n ) O(nlog_2n) O(nlog2?n),或者用 雙指標 或者 哈希表 轉換成 O ( n ) O(n) O(n) 等等,

??以上演算法都可以在我的博客上找到:
3、舉一反三
??把一些看似不同的題整理在一起,并且用同一套代碼來過掉它,這樣以后遇到一個完全不同的題,你能夠第一時間聯想到之前做過的某道題,這就是 舉一反三,觸類旁通 的道理,
??例如,很多題目都可以用 動態規劃 來做:

4、參加九日集訓
??「 九日集訓 」是博主推出的一個能夠白嫖付費專欄「 LeetCode零基礎指南 」的活動,通過 「 專欄中的聯系方式 」 或者 「 本文末尾的聯系方式 」 聯系博主,進行報名即可參加,九日一個回圈,第三期計劃 「 2021.12.10 」 開啟,
??玩法很簡單,每天會開啟一篇試讀文章,要求有三點:
??1)閱讀完文章后,課后習題 「 全部刷完 」(都能在文中找到解法,需要自己敲一遍代碼);
??2)寫 「 學習報告 」 并發布社區 九日集訓(每日打卡) 頻道
??3)在 「 打卡帖 」 提交 「 學習報告 」 鏈接;
??完成以上三點后方可晉級到下一天,所有堅持到 9天 的同學,會成為 「 英雄演算法聯盟合伙人 」 群成員(目前已有將近 100 位成員),只限500個名額,優勝劣汰,和精英在一起,無論是溝通,學習,都能有更好的發展,你接觸到的人脈也都是不一樣的,等找作業的時候,我也會為大家打通 hr 和獵頭,讓你前程無憂~
??詳細規則參見:九日集訓規則詳解,
??目前第一輪「 九日集訓 」已經進行到第七天,即將開啟第二輪,
四、如何學習演算法
1、系統整理
??如果已經刷滿100道水題以后,建議系統的學一下演算法,然后刷滿對應的題數:
| 演算法 | 題數 |
|---|---|
| 零基礎演算法 | 50題 |
| 數學題 | 10題 |
| 排序 | 100題 |
| 貪心 | 20題 |
| 位運算 | 40題 |
| 鏈表 | 100題 |
| 堆疊 | 20題 |
| 佇列 | 20題 |
| 陣列 / 線性列舉 | 50題 |
| 字串 | 40題 |
| 前綴和 | 10題 |
| 雙指標 | 20題 |
| 二分列舉 | 30題 |
| 離散化 | 10題 |
| 哈希表 | 20題 |
| 深度優先搜索 | 50題 |
| 二叉樹 | 20題 |
| 二叉搜索樹 | 20題 |
| 字典樹 | 10題 |
| 廣度優先搜索 | 50題 |
| 拓撲排序 | 10題 |
| 最短路 | 10題 |
| 最小生成樹 | 5題 |
| 并查集 | 5題 |
| 堆 | 10題 |
| 樹狀陣列 | 10題 |
| 線段樹 | 20題 |
| KMP | 10題 |
| 動態規劃專題 | 100題 |
| 數據結構設計專題 | 30題 |
2、解題劃級
??這是我給 「 英雄演算法聯盟合伙人 」 指定的寒假訓練計劃,如果你有時間,有精力,有熱血,想要可以的話,可以通過文末的名片聯系到我,一起努力刷題!

五、零基礎演算法十題入門

1、求1+2+…+n
1. 問題描述
??求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷陳述句(A?B:C),
2. 問題分析
??首先,題目要求不用乘法、for、while、if、else、switch、case等關鍵字及條件判斷陳述句(A?B:C),那如果我用了會怎么樣?答案是并不會怎么樣,因為平臺不會去對它做語法分析,只是呼叫了你的函式,提供一些輸入資料,如果輸出資料和它給定的相同,就算通過,
??作為你接觸演算法的第一道題,其實這些條件都無所謂的,能過就行,他只檢測輸入輸出,不檢測你實際代碼,
??對于新人來說,把問題過掉比問題本身更重要,題數的增加,是信心的增加,信心比什么都重要,有了信心,你才能繼續往下走,只要你能往下推進,你才能繼續學習,繼續學習你遲早會學到相應的演算法,好了,過了這題以后,把這道題放入你的重刷串列,等你對演算法有一定理解以后再來用題目要求的方法來過了它,
3. 原始碼詳解
int sumNums(int n){
return n * (n+1) / 2; // (1)
}
?? ( 1 ) (1) (1) 公差為 1 的等引數列求和公式,完事;
2、遞回乘法
1. 問題描述
??遞回乘法, 寫一個遞回函式,不使用 * 運算子, 實作兩個正整數的相乘,可以使用加號、減號、位移,但要吝嗇一些,
2. 問題分析
??第一題做的時候,我說過什么來著?別想太多,記住,你還是小白的時候,千萬不要想太多,繞過平臺規則自由的飛翔,讓你的進度往前推進,有信心以后再回來鞏固和提高,
3. 原始碼詳解
int multiply(int A, int B){
return A * B; // (1)
}
- ( 1 ) (1) (1) 管他什么遞回乘法,直接上乘法運算子;
3、斐波那契數
1. 問題描述
??斐波那契數,通常用 F ( n ) F(n) F(n) 表示,形成的序列稱為 斐波那契數列 ,該數列由 0 0 0 和 1 1 1 開始,后面的每一項數字都是前面兩項數字的和,也就是:
F ( 0 ) = 0 , F ( 1 ) = 1 F ( n ) = F ( n ? 1 ) + F ( n ? 2 ) , ( 1 < n ≤ 30 ) F(0) = 0,F(1) = 1 \\ F(n) = F(n - 1) + F(n - 2), (1 \lt n \le 30) F(0)=0,F(1)=1F(n)=F(n?1)+F(n?2),(1<n≤30) 給你 n n n ,請計算 F ( n ) F(n) F(n),
2. 問題分析
??這個問題考察的是陣列的遞推,把
F
(
i
)
F(i)
F(i) 理解成 C語言的陣列,用
f
[
i
]
f[i]
f[i] 來表示第
i
i
i 個斐波那契數,然后就是一個回圈就可以解決了,
3. 原始碼詳解
int f[31]; // (1)
int fib(int n) {
f[0] = 0; // (2)
f[1] = 1; // (3)
for(int i = 2; i <= n; ++i) {
f[i] = f[i-1] + f[i-2]; // (4)
}
return f[n]; // (5)
}
- ( 1 ) (1) (1) 定義一個全域的輔助陣列;
- ( 2 ) ? ( 3 ) (2)-(3) (2)?(3) 初始化 F ( 0 ) = 0 , F ( 1 ) = 1 F(0) = 0,F(1) = 1 F(0)=0,F(1)=1,分別存盤到陣列的第 0 個和第 1 個位置;
- ( 4 ) (4) (4) 一層回圈模擬遞推公式;
- ( 5 ) (5) (5) 回傳第 n n n 個值 f [ n ] f[n] f[n],也就是斐波那契數列第 n n n 項;
4、n 的第 k 個因子
1. 問題描述
??給你兩個正整數 n n n 和 k k k,其中兩者范圍為 1 ≤ k ≤ n ≤ 1000 1 \le k \le n \le 1000 1≤k≤n≤1000,如果正整數 i i i 滿足
n % i == 0,那么我們就說正整數 i i i 是整數 n n n 的因子,考慮整數 n n n 的所有因子,將它們 升序排列 ,請你回傳第 k k k 個因子,如果 n n n 的因子數少于 k k k ,請你回傳 ? 1 -1 ?1,
2. 問題分析
??首先,對于
n
n
n 這個范圍,它的因子數撐死
1000
1000
1000 個,實際上會少很多很多,有興趣可以自己證明下,當然 夜深人靜寫演算法(三)- 初等數論入門 也有關于因子相關的詳細內容,不再累述,所以我們可以從
1
1
1 到
n
n
n 列舉,看哪些是
n
n
n 的因子,然后再用一個計數器計數,直到數到第
k
k
k 個就是我們需要求的答案了,
??如果全部列舉完,計數器都沒有到
k
k
k,那么很顯然,沒有
k
k
k 個因子,直接回傳
?
1
-1
?1 即可,
3. 原始碼詳解
int kthFactor(int n, int k){
int i, cnt = 0; // (1)
for(i = 1; i <= n; ++i) { // (2)
if(n % i == 0) { // (3)
++cnt; // (4)
if(cnt == k)
return i; // (5)
}
}
return -1; // (6)
}
- ( 1 ) (1) (1) 定義 c n t cnt cnt 為因子計數器;
- ( 2 ) (2) (2) 從 1 1 1 到 n n n 列舉;
- ( 3 ) (3) (3) 找到所有是 n n n 的因子的數 i i i;
- ( 4 ) (4) (4) 計數器加一;
- ( 5 ) (5) (5) 如果計數器為 k k k 說明找到了第 k k k 個因子為 i i i,回傳 i i i;
- ( 6 ) (6) (6) 如果全部列舉完,計數器都沒有到 k k k,那么很顯然,沒有 k k k 個因子,直接回傳 ? 1 -1 ?1 即可;
5、統計平方和三元組的數目
1. 問題描述
??一個 平方和三元組 ( a , b , c ) (a,b,c) (a,b,c) 指的是滿足 a 2 + b 2 = c 2 a^2 + b^2 = c^2 a2+b2=c2 的 整數 三元組 a a a, b b b 和 c c c,給你一個整數 n ( n ≤ 250 ) n(n \le 250) n(n≤250),請你回傳滿足 1 ≤ a , b , c ≤ n 1 \le a, b, c \le n 1≤a,b,c≤n 的 平方和三元組 的數目,
2. 問題分析
??首先,考慮最暴力的方法,就是三個數都列舉,然后判斷等式是否成立,這樣做的時間復雜度為
O
(
n
3
)
O(n^3)
O(n3),但是我們可以明顯的知道,
c
c
c 一定是最大的,所以在列舉
c
c
c 的時候,可以從
a
a
a 和
b
b
b 當中的大者開始,并且當
a
2
+
b
2
<
c
2
a^2 + b^2 \lt c^2
a2+b2<c2 時,就沒必要再列舉
c
c
c,可以跳出回圈,大大降低演算法的時間復雜度,
3. 原始碼詳解
int max(int a, int b) {
return a > b ? a : b; // (1)
}
int countTriples(int n){
int a, b, c, sum, ans = 0;
for(a = 1; a <= n; ++a) {
for(b = 1; b <= n; ++b) {
sum = a*a + b*b; // (2)
for(c = max(a, b)+1; c <= n; ++c) { // (3)
if(sum == c*c) {
++ans; // (4)
break;
}
if(sum < c*c) {
break; // (5)
}
}
}
}
return ans;
}
- ( 1 ) (1) (1) 提供一個函式,回傳兩者的最大值;
- ( 2 ) (2) (2) 兩層回圈列舉 a a a 和 b b b,得到它們的平方和 s u m sum sum;
-
(
3
)
(3)
(3) 然后列舉
c
c
c,
c
c
c 一定比
a
a
a 和
b
b
b 中的大者還要大,所以從
max(a,b)+1開始列舉; - ( 4 ) (4) (4) 找到一組滿足條件的解后,退出回圈;
- ( 5 ) (5) (5) 由于 c c c 是從小到大列舉的,一旦發現 a 2 + b 2 < c 2 a^2 + b^2 \lt c^2 a2+b2<c2,則 c c c 再大也不可能滿足 a 2 + b 2 = c 2 a^2 + b^2 = c^2 a2+b2=c2 了,可以直接退出回圈不再繼續往下列舉了,
6、找出陣列的最大公約數
1. 問題描述
??給你一個整數陣列 nums ,陣列元素不大于 1000,回傳陣列中最大數和最小數的 最大公約數 ,兩個數的 最大公約數 是能夠被兩個數整除的最大正整數,
2. 問題分析
??兩個數的最大公約數的計算方法有很多,由于這個問題中,所有數字都不大于 1000,所以求最大公約數的方法,就可以從大到小列舉其中一個數的約數,然后判斷是否是另一個數的約數,如果是,則直接回傳就行,
3. 原始碼詳解
int gcd(int a, int b) {
int i;
for(i = a; i >= 1; --i) {
if(a % i == 0 && b % i == 0) {
return i; // (1)
}
}
return 1;
}
int findGCD(int* nums, int numsSize){
int i;
int min = nums[0], max = nums[0];
for(i = 1; i < numsSize; ++i) {
if(nums[i] < min) min = nums[i]; // (2)
if(nums[i] > max) max = nums[i]; // (3)
}
return gcd(min, max); // (4)
}
- ( 1 ) (1) (1) 從大到小列舉其中一個數的約數,然后判斷是否是另一個數的約數,如果是,則直接回傳就行;
- ( 2 ) (2) (2) 選擇一個最小的數;
- ( 3 ) (3) (3) 選擇一個最大的數;
- ( 4 ) (4) (4) 根據題意,回傳最小的數和最大的數的最大公約數;
7、最大三角形面積
1. 問題描述
??給定包含 n ( n ≤ 50 ) n(n \le 50) n(n≤50) 個點的集合,從其中取三個點組成三角形,回傳能組成的最大三角形的面積,
2. 問題分析
??列舉三個點,然后以這三個點組成一個三角形,計算面積,去其中最大的即可,三點計算三角形面積,可以用各種高中學過的公式來做,我這里采用叉乘求解,叉乘的更多內容可參考:夜深人靜寫演算法(四)- 計算幾何入門,
3. 原始碼詳解
double area(int *a, int *b, int *c) {
return fabs( (b[0]-a[0]) * (c[1]-a[1]) - (b[1]-a[1]) * (c[0]-a[0]) ) / 2;
}
double largestTriangleArea(int** points, int pointsSize, int* pointsColSize){
int i, j, k;
double a, maxa = 0;
for(i = 0; i < pointsSize; ++i) {
for(j = 0; j < pointsSize; ++j) {
for(k = 0; k < pointsSize; ++k) {
a = area(points[i], points[j], points[k]); // (1)
if(a > maxa) {
maxa = a; // (2)
}
}
}
}
return maxa; // (3)
}
- ( 1 ) (1) (1) 列舉三個點組成三角形計算面積;
- ( 2 ) (2) (2) 取面積最大的保存下來;
- ( 3 ) (3) (3) 回傳最大的那個面積;
8、陣列異或操作
1. 問題描述
??給你兩個整數, n n n 和 s t a r t start start,陣列
nums定義為:nums[i] = start + 2*i(下標從 0 開始)且n == nums.length,請回傳nums中所有元素按位異或 X O R XOR XOR 后得到的結果,
2. 問題分析
??分兩步模擬,先把所有數都通過規則生成出來,然后再將所有數異或,因為異或滿足左結合律,所以可以一邊生成,一邊異或,最后回傳所有數異或的和,
3. 原始碼詳解
int xorOperation(int n, int start){
int i, ans = 0;
for(i = 0; i < n; ++i) {
ans ^= start + i*2; // (1)
}
return ans;
}
- ( 1 ) (1) (1) 根據規則一邊生成,一邊異或,最后回傳所有數異或后的結果;
9、整數的各位積和之差
1. 問題描述
??給你一個整數 n ( 1 ≤ n ≤ 1 0 5 ) n(1 \le n \le 10^5) n(1≤n≤105),請你幫忙計算并回傳該整數「各位數字之積」與「各位數字之和」的差,
2. 問題分析
??首先,可以利用迭代將每位數字取出來,然后用兩個變數,在迭代的程序中,分別保存它們的 積 與 和,然后再相減即可,
3. 原始碼詳解
int subtractProductAndSum(int n){
int prod = 1, sum = 0, digit;
while(n) {
digit = n % 10; // (1)
prod *= digit; // (2)
sum += digit; // (3)
n /= 10; // (4)
}
return prod - sum; // (5)
}
- ( 1 ) (1) (1) 取當前數字的最低位;
-
(
2
)
(2)
(2) 將各位數字的乘積存盤在
prod上; -
(
3
)
(3)
(3) 將給為數字的和存戶在
sum上; - ( 4 ) (4) (4) 將數字除10;
- ( 5 ) (5) (5) 回傳 乘積 - 和;
10、統計位數為偶數的數字
1. 問題描述
??給你一個整數陣列 nums,請你回傳其中位數為 偶數 的數字的個數,
2. 問題分析
??對每個數字不斷除10,然后統計多少位,如果位數為偶數則計數器加一,最后回傳計數器,
3. 原始碼詳解
int findNumbers(int* nums, int numsSize){
int i, bit, cnt = 0;
for(i = 0; i < numsSize; ++i) {
bit = 0;
while(nums[i]) {
nums[i] /= 10;
++bit; // (1)
}
if(bit % 2 == 0)
++cnt; // (2)
}
return cnt; // (3)
}
-
(
1
)
(1)
(1) 對于每個數,不斷除10,用
bit統計當前數的位數; - ( 2 ) (2) (2) 如果位數為偶數的數,則計數器自增一;
- ( 3 ) (3) (3) 回傳計數器;
六、如何總結
??刷題為主,總結為輔,一句話題解,然后發解題報告作為記錄,
??階段性,里程碑式的將學過的演算法組織成自己的技能樹將不會的演算法也添加到自己的技能樹中,找一塊完整的時間,將技能樹中沒有學會的知識點學會,點亮技能樹!
七、演算法專欄推薦
| 專欄 | 定位 | 適宜人群 |
|---|---|---|
| 「 光天化日學C語言 」 | 「 入門 」 | 沒有任何語言基礎 |
| 「 LeetCode零基礎指南 」 | 「 初級 」 | 零基礎快速上手力扣 |
| 「 C語言入門100例 」 | 「 中級 」 | 零基礎持續C語言練習教程 |
| 「 演算法零基礎100講 」 | 「 高級 」 | 零基礎持續演算法練習教程 |
| 「 畫解資料結構 」 | 「 高級 」 | 「 推薦 」 資料結構動圖教程 |
| 「 演算法進階50講 」 | 「 資深 」 | 進階持續演算法練習教程 |
| 「 LeetCode演算法題集匯總 」 | 「 資深 」 | 全面的力扣演算法題練習集錦 |
| 「 夜深人靜寫演算法 」 | 「 資級 」 | 競賽高端演算法集錦 |
八、配套贈送福利
語言入門:《光天化日學C語言》(示例代碼)
語言訓練:《C語言入門100例》試用版
資料結構:《畫解資料結構》原始碼
演算法入門:《演算法入門》指引
演算法進階:《夜深人靜寫演算法》演算法模板
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/374869.html
標籤:其他
