algo[2]
建北電資小社課
2023/10/27
- 225班
- 電子計算機研習社_學術長
- 綽號807
- 資讀講師
這我

複雜度
Complexity
- 評估用量
- 時間複雜度
- 空間複雜度
複雜度
飯粒
n
T
給 個整數(陣列a)
求這 個數的和
n
n
n
int sum=0;
for(int i=0;i<n;i++) sum+=a[i];
cout<<sum<<"\n";
O(n)
複雜度:
符號
\Theta
O
o
\Omega
\omega
上界==下界
上界 最大值(包含)
上界 最大值(不含)
下界 最小值(包含)
下界 最小值(不含)
飯粒
n
T
O(n)
給 個整數(陣列a)
求這 個數的和
n
n
n
int sum=0;
for(int i=0;i<n;i++) sum+=a[i];
cout<<sum<<"\n";
複雜度:
\Theta(n)
\Omega(n)
你可能會想問
乘法比加法慢,那複雜度是否相同?
- 由於兩者的計算時間都是常數,所以可記為
- 做n次加法和做n次乘法都是
O(n)
O(1)
O(c_1)
O(c_2)
O(1)
O(c_1 \times n)
O(c_2 \times n)
O(n)
你可能會想問
宣告sum 輸出sum 都需要時間,那這些時間需不需要算進去?
- 宣告sum 輸出sum 遠小於 計算
- 複雜度 取 成長性最快者
成長性
O(1)
O(log(n))
O(n)
O(n \times log(n))
O(n^2)
O(n!)
O(2^n)
O(n^3)
O(n^2 \times log(n))
O(n \times log^2(n))
成長性
O(log(n))
O(n)
O(n^2)
O(n!)
O(2^n)
O(n\times log(n))
時間限制: 1000 ms
記憶體量: 65536 MB
電腦每秒約 次運算
常見題目限制
10^9
複雜度範圍
複雜度 \times 常數 \le 10^9 \\
\because 常數不大 \\
\therefore 複雜度 \le 10^8
實際情況須依長數而定
時間複雜度範圍
實際情況須依長數而定
O(1)
O(log(n))
O(n)
O(n \times log(n))
O(n^2)
O(n!)
O(2^n)
\infty
10^{20}
10^8
10^7
10^4
28
12
空間複雜度範圍
- 題目限制較不一
資料型態 (複習)
資料型態 | 用途 | 記憶體大小 |
---|---|---|
int | 整數-2³¹~2³¹-1(約2*10⁹~-2*10⁹) | 4 bytes |
long long | 更大的整數 -2⁶³~2⁶³-1(約9*10¹⁸~-9*10¹⁸) | 8 bytes |
float | 浮點數 (可以有小數點的數字) | 4 bytes |
double | 更精確浮點數 (可以有小數點的數字) | 8bytes |
char | 字元 | 1 byte |
string | 字串 | 可變 |
記憶體/檔案單位
1 = 8 bits \\
1 KB = 1000 bytes \\
1 KiB = 1024 bytes \\
1 MB = 10^6 bytes \\
1 Mib = 2^{20} bytes \approx 10^6 \\
1 GB = 10^9 bytes \\
1 GiB = 2^{30} bytes \approx 10^9 \\
1 TB = 10^{12} bytes \\
1 TiB = 2^{40} bytes \approx 10^{12} \\
- 評估演算法速度、記憶體用量
- 找出適當演算法、資料結構
為什麼要學
STL能吃嗎?
- 寫好的資料結構
- 寫好的迭代器
標準樣板函式庫
Standard Template Library
好ㄟ
都幫我寫好了
- 了解複雜度
- 用
- 查cplusplus.com
那我要幹嘛
pair
- pair
- 前: first
- 後: second
配
宣告
pair<int,int> p;
first(int) | second(int) |
---|
取值
cin>>p.first;
cin>>p.second;
first | second |
---|
vector
- 不是向量
- 長度可變的陣列
vector
這東西顯然推爆吧
宣告
陣列
vector
int arr[5]={0};
vector<int> arr(5,0);
int arr[5];
vector<int> arr(5);
vector<int> arr;
空
輸出 arr 的大小 5
.size()
vector<int> arr(5,7);
cout<<arr.size()<<"\n";
arr 為空 輸出 1
.empty()
vector<int> arr;
cout<<arr.empty()<<"\n";
.push_back(要插入的)
[]
vector<int> arr;
arr.push_back(8);
arr.push_back(0);
arr.push_back(7);
[8]
[8,0]
[8,0,7]
[]
.pop_back()
arr.pop_back();
arr.pop_back();
arr.pop_back();
[8]
[8,0]
[8,0,7]
- 自動開兩倍長的陣列
- 將現有自動的複製過去
- 好ㄟ 容量夠了
push_back 容量不足
O(2n)
O(n)
複雜度:
.reserve()
- 為push_back預留容量
[]
cout<<arr.capacity()<<"\n";
[8,,]
[8,0,]
[8,0,7]
[,,]
.capacity()
- 取得容量空間大小
cout<<arr.capacity()<<"\n";
.swap(vector)
- 重置
[]
vector<int>().swap(arr);
cout<<arr.empty()<<"\n";
[8,0,7]
arr:
題單
太多了不想放ㄟ
iterator

敬請見諒😆
迭代

- 迭代器
- 寫好的~ 讓你便利遍歷
- 有些資料結構過於複雜
iterator
iterator

遍歷
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> arr(5);
for(vector<int>::iterator it=arr.begin();it!=arr.end();it++){
cin>>*it;
}
for(vector<int>::reverse_iterator it=arr.rbegin();it!=arr.rend();it++){
cout<<*it<<" ";
}
cout<<"\n";
}
便利遍歷
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> arr(5);
for(auto it=arr.begin();it!=arr.end();it++){
cin>>*it;
}
for(auto it=arr.rbegin();it!=arr.rend();it++){
cout<<*it<<" ";
}
cout<<"\n";
}
變例便利遍歷
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> arr(5);
for(int &i:arr){
cin>>i;
}
for(auto &i:arr){
cout<<i<<" ";
}
cout<<"\n";
}
stack


- 堆
- 放最上層
- 拿最上層
- Last-In First-Out
stack
- LIFO
.push()
- 放入最上層
stack<int> stk;
stk.push(20);
stk.push(10);
10
top()
top()
20
stk
宣告
.top()
- 最上層
- stack為空時,Segment Default
stk.top()+=2
cout<<stk.top()<<endl;
10
top()
20
stk
12
12
- 取得stack大小
.size()
5
stk
- 取得stack大小
.size()
5
stk
stk 為空 輸出 1
.empty()
stack<int> stk;
cout<<stk.empty()<<"\n";
queue

- 佇列
- 排隊顯然要先來先走吧!!!👀
- First-In First-Out
queue
- FIFO
\lt
\lt
\lt
\lt
\lt
\lt
宣告
queue<int> q;
q
.push()
q.push(8);
q.push(0);
q.push(7);
q
8
0
7
back
back
back
front
.front() .back()
q.front()--;
q.back()++;
cout<<q.front()<<","<<q.back()<<"\n";
q
8
0
7
back
front
7
8
7,8
.pop()
q.pop();
q.pop();
q.pop();
q
7
0
8
back
front
front
front
.size() .empty
cout<<q.size()<<"\n";
cout<<q.empty()<<"\n";
q
0
1
priority_queue

- 優先權佇列
- 優先者先出
- 預設大的在前
priority_queue
宣告
#include<bits/stdc++.h>
using namespace std;
int main(){
priority_queue<int,vector<int>,decltype([](int a,int b){return a<b;})> pq;
pq.push(5);
pq.push(7);
cout<<pq.top()<<endl;
}
不想用struct 那就用lambda

宣告
priority_queue<int> pq;
- 存int
- 有大到小
宣告
priority_queue<int,vector<int>,greater<int>> pq;
想由小到大
宣告
#include<bits/stdc++.h>
using namespace std;
struct comp{
bool operator()(int a,int b){
return a<b;
}
};
int main(){
priority_queue<int,vector<int>,comp> pq;
}
想自訂比較函示
這是有小到大有夠不值覺得啦啦啦~~~
宣告
- 蛤 什麼是 decltype
- 欸 我也不知道ㄟ

.push()
pq.push(0);
pq.push(8);
pq.push(7);
8
pq
7
0
.top()
pq.top()
8
pq
7
0
.pop()
pq.push(8);
pq.push(0);
pq.push(7);
8
pq
7
0
.size() .empty
cout<<pq.size()<<"\n";
cout<<pq.empty()<<"\n";
0
1
複雜度 整理
top()
push()
pop()
O(1)
O(log(n))
O(log(n))
list
- 存自己
- 下一位
- 上一位
鄰接串列
- STL的太難用了
- 我們自己寫吧
最後最後
- @cjtsai蠻推的
我亂寫的不要打我
今天蠻多例題都是資訊枝芽
演算法小社[2]
By 建中店自計算機研習社學術長807⁸⁰⁷
演算法小社[2]
- 379