vector&deque

什麼是STL?

STL(標準模板庫,Standard Template Library) 是 C++ 提供的一套高效、通用、可重用的資料結構和演算法庫

容器(Containers) 儲存數據的結構

演算法(Algorithms)操作數據的方法

迭代器

(Iterators)

存取容器元素的方式

什麼是STL?

容器(Containers) 儲存數據的結構

順序容器 :

  • 元素時關注順序,即元素的排列方式與插入順序一致。

  • 底層實現通常為陣列或鏈表,適合順序存取或 高效插入刪除的場景。

list

vector 

deque

list、vector、deque差異

1.vector 適合高效隨機存取的場景(如動態數據處理):

是一個大書架,你可以快速找到第 n 本書(O(1)),但如果要在中間插入一本新書,你可能需要移動所有後面的書(O(N))。

 

2.list 適合從兩端插入/刪除的場景(如滑動窗口算法):

list 是一串串起來的鑰匙,你不能直接找到第 n 個鑰匙(O(N)),但要插入或刪除某個鑰匙只需要解開或連接鑰匙圈(O(1))。

 

3. deque 適合頻繁插入/刪除的場景(如鏈表操作):

一組可以從兩邊取書的書架,你可以快速從頭尾添加或刪(O(1)),但中間的書仍然難以插入(O(N))。

vector

宣告與初始化

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v1;  // 空的 vector
    vector<int> v2(5);  // 容量為 5,元素預設為 0
    vector<int> v3(5, 100);  // 容量為 5,每個元素都初始化為 100
    vector<int> v4 = {1, 2, 3, 4, 5};  // 列表初始化
}

vector 的特點

1.連續記憶體 → 像陣列一樣透過索引[]存取元素

vector<int> v = {1, 2, 3, 4, 5};  // 列表初始化
cout << v[2] << endl;  // 取得索引 2 的元素(輸出 3)

2.動態擴展 → 容量會自動擴大,無需手動管理記憶體

3.高效的尾部操作 →插入、刪除尾部元素不需花太多時間

4.不適合頻繁插入/刪除 → 若在中間或開頭插入/刪除,需移動元素,花費時間長

v.push_back(6);  // {1, 2, 3, 4, 5, 6} // 新增元素
v.pop_back();  // {1, 2, 3, 4, 5} // 刪除尾部元素
v.insert(v.begin() + 1, 10);  //在索引 1 位置插入 10 {1, 10, 2, 3, 4}
v.erase(v.begin() + 2);  // // 刪除索引 2 的元素 {1, 10, 3, 4}

5.支持 STL 演算法 → 可與 sort(), find(), accumulate() 等一起使用

vector 的基本操作

操作 函式
新增元素(尾部) push_back(x)
刪除尾部元素 pop_back()
插入元素 insert(it, x)
刪除指定位置的元素 erase(it)
清空整個 vector clear()
獲取元素數量 size()
獲取最大容量 capacity()
存取元素 v[i], at(i)
#include <iostream>
#include <vector>
using namespace std;
int main() {
    // 宣告與初始化
    vector<int> v = {10, 20, 30, 40, 50};

    // 新增元素(尾部)
    v.push_back(60); // 10, 20, 30, 40, 50, 60
    
    // 刪除尾部元素
    v.pop_back(); // 10, 20, 30, 40, 50

    // 在索引 2 插入 25
    v.insert(v.begin() + 2, 25); // 10, 20, 30, 40, 50
    
    // 刪除索引 3 的元素
    v.erase(v.begin() + 3); // 10, 20, 30, 40, 50

    // 取得 `size()` 和 `capacity()`
    cout  << v.size() << v.capacity() << endl; // 5 10

    // 存取元素
    cout << v[2] << v.at(2) << endl; // 25 25

    // 清空 `vector`
    v.clear();
    cout << v.size() << v.capacity() << endl;
}
#include <iostream>
#include <vector>
using namespace std;

// 判斷短積木能否貼合在長積木的某個位置
bool canAttach(const vector<int>& longBlock, const vector<int>& shortBlock, int start) {
    int M = shortBlock.size();
    for (int i = 0; i < M; i++) {
        if (abs(longBlock[start + i] - shortBlock[i]) > 3) {
            return false;  // 不能對接
        }
    }
    return true; // 成功對接
}

int main() {
    int N, M;
    cin >> N;

    vector<int> longBlock(2 * N + 1);
    for (int i = 0; i < 2 * N + 1; i++) {
        cin >> longBlock[i];
    }

    cin >> M;
    vector<int> shortBlock(2 * M - 1);
    for (int i = 0; i < 2 * M - 1; i++) {
        cin >> shortBlock[i];
    }

    // 嘗試對齊的起始位置範圍
    for (int start = 0; start <= (2 * N - 2 * M + 1); start++) {
        if (canAttach(longBlock, shortBlock, start)) {
            cout << "YES" << endl;
            return 0;
        }
    }

    cout << "NO" << endl;
    return 0;
}

deque

基本操作

#include <iostream>
#include <deque>
using namespace std;

int main() {
    deque<int> dq; // 宣告一個空的雙端佇列

    // 插入元素
    dq.push_back(10);  // [10]
    dq.push_front(20); // [20, 10]
    dq.push_back(30);  // [20, 10, 30]

    // 訪問元素
    cout << "第一個元素: " << dq.front() << endl; // 20
    cout << "最後一個元素: " << dq.back() << endl; // 30
    cout << "第二個元素: " << dq[1] << endl; // 10 

    // 3. 刪除元素
    dq.pop_front(); // [10, 30]
    dq.pop_back();  // [10]

    // 4. 判斷是否為空
    if (dq.empty()) {
        cout << "Deque 是空的" << endl;
    } else {
        cout << "Deque 長度: " << dq.size() << endl;
    }

    return 0;
}
#include <iostream>
#include <vector>
#include <deque>
using namespace std;

vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    deque<int> dq;  // 儲存元素索引
    vector<int> res; // 存最大值結果

    for (int i = 0; i < nums.size(); i++) {
        // 1. 移除超出範圍的索引
        if (!dq.empty() && dq.front() < i - k + 1) {
            dq.pop_front();
        }

        // 2. 移除比當前元素小的索引
        while (!dq.empty() && nums[dq.back()] < nums[i]) {
            dq.pop_back();
        }

        // 3. 加入當前索引
        dq.push_back(i);

        // 4. 記錄最大值(窗口滿足 `k` 時)
        if (i >= k - 1) {
            res.push_back(nums[dq.front()]);
        }
    }

    return res;
}

int main() {
    vector<int> nums = {1, 3, -1, -3, 5, 3, 6, 7};  // 輸入數組
    int k = 3;  // 窗口大小

    vector<int> result = maxSlidingWindow(nums, k);

    // 輸出結果
    for (int i = 0; i < result.size(); i++) {
    	cout << result[i] << " ";
    }
    return 0;
}

小練習

nums = {1, 3, -1, -3, 5, 3, 6, 7},k = 3

  • 使用 deque 儲存窗口內最大值的索引,確保隊首永遠是最大值。
  • deque 是一種雙端佇列,允許在兩端插入/刪除
  • vector 更適合頻繁 push_front() 操作
  • list 更適合隨機存取
  • 常用於 滑動視窗、BFS 搜索等場景

deque 作用

kahoot

vector&deque

By phoebe tsai

vector&deque

  • 176