目錄
一、有關數組和動態數組的排序(sort函數)
?1.普通數組的排序
基本用法
降序排序
2.vector的排序
基本用法
降序排序
二、數組長度和一些vector的基本語法
1. 靜態數組長度計算?
?2. 安全獲取數組長度(C++17 起)?
?3.vector 基本語法?
3.1?聲明與初始化??
??3.2?常用操作?
3.3數組轉換成vector
三、列表初始化
?1. ??基礎概念??
2. ??常見場景??
3. ??底層原理??
4.return?時的列表初始化
????????4.1. ??直接返回列表??
????????4.2???對比傳統寫法??
5.特殊場景處理
????????5.1???返回空容器?
????????5.2???返回嵌套結構
6.注意事項
????????6.1類型匹配?????????
????????6.2?函數返回類型必須明確?
題目1----兩數之和
1.空模板解析
2.實際后臺運行版本
3.哈希表
3.1 unordered_map
1. ??核心特性??
2. ??常用函數(表格)??
?3. ??代碼用法示例?
3.2 unordered_set
1. ??核心特性??
2. ??常用函數(表格)??
3. ??代碼用法示例?
4.題解
一、有關數組和動態數組的排序(sort函數)
?1.普通數組的排序
基本用法
#include <algorithm> // 必須包含的頭文件int main() {int arr[] = {5, 3, 9, 1, 7};int n = sizeof(arr) / sizeof(arr[0]); // 計算數組長度// 默認升序排序(從小到大)std::sort(arr, arr + n); // 參數為指針范圍:[arr, arr + n)// 輸出結果:1 3 5 7 9return 0;
}
降序排序
#include <algorithm>
#include <functional> // 需要包含此頭文件以使用 greater<>int main() {int arr[] = {5, 3, 9, 1, 7};int n = sizeof(arr) / sizeof(arr[0]);// 使用 greater<int>() 降序排序std::sort(arr, arr + n, std::greater<int>());// 輸出結果:9 7 5 3 1return 0;
}
2.vector的排序
基本用法
#include <algorithm>
#include <vector>int main() {std::vector<int> vec = {5, 3, 9, 1, 7};// 默認升序排序std::sort(vec.begin(), vec.end()); // 參數為迭代器范圍// 輸出結果:1 3 5 7 9return 0;
}
降序排序
#include <algorithm>
#include <vector>
#include <functional>int main() {std::vector<int> vec = {5, 3, 9, 1, 7};// 降序排序std::sort(vec.begin(), vec.end(), std::greater<int>());// 輸出結果:9 7 5 3 1return 0;
}
二、數組長度和一些vector的基本語法
1. 靜態數組長度計算?
int arr[] = {3, 1, 4, 1, 5, 9};
int length = sizeof(arr) / sizeof(arr[0]); // 計算元素個數
?數組作為函數參數傳遞時會退化為指針,此時?sizeof(arr)
?返回指針大小而非數組大小
錯誤示例:
void func(int arr[]) {int len = sizeof(arr)/sizeof(arr[0]); // 錯誤!返回指針大小/元素大小的比值
}
?2. 安全獲取數組長度(C++17 起)?
#include <iterator>
int arr[] = {1, 2, 3};
int length = std::size(arr); // 直接獲取數組長度(需C++17及以上)
?3.vector 基本語法?
3.1?聲明與初始化??
語法 | 說明 | 示例 |
---|---|---|
??默認初始化?? | 創建空 vector | vector<int> v1; |
??列表初始化?? | 直接初始化元素 | vector<int> v2 = {1, 2, 3}; |
??指定大小和值?? | 創建含?n ?個?val ?的 vector | vector<int> v3(5, 10); // 5個10 |
??拷貝初始化?? | 復制另一個 vector | vector<int> v4(v3); |
??3.2?常用操作?
操作 | 語法 | 說明 |
---|---|---|
??添加元素?? | push_back(val) | 在末尾插入元素 |
??訪問元素?? | v[i] ?或?v.at(i) | 下標訪問(at() ?會檢查邊界) |
??獲取大小?? | v.size() | 返回元素個數 |
??判斷空?? | v.empty() | 返回是否為空 |
??清空元素?? | v.clear() | 移除所有元素 |
??調整大小?? | v.resize(n, val) | 調整大小為?n ,新增元素初始化為?val |
3.3數組轉換成vector
int arr[] = {5, 2, 8};
vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
三、列表初始化
?1. ??基礎概念??
列表初始化使用 ??花括號?{}
?? 初始化對象,是 C++11 引入的??統一初始化語法??,適用于所有類型。
2. ??常見場景??
場景 | 示例 | 等效傳統寫法 |
---|---|---|
??初始化變量?? | vector<int> v = {1, 2, 3}; | vector<int> v; v.push_back(1); ... |
??函數返回值?? | return {i, j}; | return vector<int>{i, j}; |
??構造函數參數?? | pair<int, string> p{5, "test"}; | pair<int, string> p(5, "test"); |
3. ??底層原理??
- 編譯器會嘗試將?
{}
?中的內容轉換為目標類型的?initializer_list
。 - 對?
vector
?來說,內部定義了接受?initializer_list
?的構造函數:
4.return
?時的列表初始化
????????4.1. ??直接返回列表??
vector<int> twoSum(...) {return {i, j}; // 隱式構造 vector<int> 對象
}
等效代碼:
vector<int> temp;
temp.push_back(i);
temp.push_back(j);
return temp;
????????4.2???對比傳統寫法??
寫法 | 性能 | 可讀性 |
---|---|---|
return {i, j}; | ? 更優(直接構造) | ? 簡潔 |
return vector<int>{i, j}; | ? 相同 | ? 冗余 |
vector<int> res; ... return res; | ? 可能拷貝 | ? 冗長 |
5.特殊場景處理
????????5.1???返回空容器?
return {}; // 返回空 vector,等效 return vector<int>();
????????5.2???返回嵌套結構
vector<pair<int, int>> func() {return {{1, 2}, {3, 4}}; // 列表初始化嵌套結構
}
6.注意事項
????????6.1類型匹配?????????
// 錯誤示例:列表元素類型不匹配
vector<string> v = {1, 2}; // int 無法隱式轉為 string
????????6.2?函數返回類型必須明確?
auto func() { // 錯誤:無法推導返回類型return {1, 2};
}
vector<int> func() { // 正確return {1, 2};
}
題目1----兩數之和
1.空模板解析
// 頭文件(通常在LeetCode平臺已隱式包含,但本地編譯需手動添加)
// #include <vector>
// using namespace std;// 定義解決方案類(LeetCode答題標準模板)
class Solution {
public: // 訪問權限修飾符,表示以下成員對外公開(LeetCode需要調用該函數)// 定義名為twoSum的成員函數// 參數說明:// vector<int>& nums → 整型向量的引用(避免拷貝整個數組)// int target → 整型目標值// 返回值:vector<int> → 包含兩個索引的向量vector<int> twoSum(vector<int>& nums, int target) {// 函數實現區(需補全)return {}; // 無解時返回空向量(題目保證有解時可省略)*/}/* 關鍵語法說明:1. vector<int>& → 引用傳遞參數,直接操作原數組(避免拷貝)2. nums.size() → 獲取向量元素數量(等效于數組長度)3. {i, j} → C++11統一初始化,等價于 vector<int>{i, j}};
2.實際后臺運行版本
#include <iostream>
#include <vector>
using namespace std;class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {for (int i = 0; i < nums.size(); ++i) {for (int j = i + 1; j < nums.size(); ++j) {if (nums[i] + nums[j] == target) {return {i, j};}}}return {}; // 實際題目保證有解,此句僅為編譯通過}
};// 測試用例
int main() {vector<int> nums = {2, 7, 11, 15};int target = 9;Solution sol;vector<int> res = sol.twoSum(nums, target);cout << "[" << res[0] << ", " << res[1] << "]" << endl; // 輸出 [0, 1]return 0;
}
3.哈希表
在 C++ 中,哈希表主要通過?unordered_map
(鍵值對)和?unordered_set
(唯一鍵集合)實現
特性 | unordered_map | unordered_set |
---|---|---|
??存儲內容?? | 鍵值對(key-value ) | 唯一值(value ) |
??查找依據?? | 鍵(key ) | 值本身(value ) |
??典型應用場景?? | 需要快速通過鍵訪問值的場景 | 需要快速判斷元素是否存在的場景 |
哈希表原理:?
哈希表實現:哈希表C++哈希表詳解(知識點+相關LeetCode題目)-CSDN博客
3.1 unordered_map
1. ??核心特性??
- 存儲鍵值對(
key-value
),鍵唯一 - 基于哈希表實現,查找時間復雜度平均為 ??O(1)??
- 無序存儲(元素順序與插入順序無關)
2. ??常用函數(表格)??
函數/操作 | 說明 | 時間復雜度 |
---|---|---|
unordered_map<K, V> map; | 初始化空哈希表 | O(1) |
map[key] = value; | 插入或修改鍵值對(若?key ?存在則覆蓋) | 平均 O(1) |
map.insert({key, value}); | 插入鍵值對(若?key ?存在則不插入) | 平均 O(1) |
map.find(key) | 返回指向鍵的迭代器(若不存在返回?end() ) | 平均 O(1) |
map.count(key) | 返回鍵存在的次數(0 或 1) | 平均 O(1) |
map.erase(key) | 刪除指定鍵的鍵值對 | 平均 O(1) |
map.size() | 返回元素個數 | O(1) |
map.empty() | 判斷哈希表是否為空 | O(1) |
?3. ??代碼用法示例?
#include <unordered_map>
#include <iostream>
using namespace std;int main() {// 初始化unordered_map<string, int> scores = {{"Alice", 90}, {"Bob", 85}};// 插入元素scores["Charlie"] = 88; // 方式1:operator[]scores.insert({"David", 95}); // 方式2:insert// 訪問元素cout << "Alice的分數: " << scores["Alice"] << endl; // 直接訪問if (scores.find("Eve") != scores.end()) { // 安全訪問cout << "Eve存在" << endl;}// 刪除元素scores.erase("Bob");// 遍歷for (const auto& pair : scores) {cout << pair.first << ": " << pair.second << endl;}return 0;
}
3.2 unordered_set
1. ??核心特性??
- 存儲唯一元素(無重復值)
- 基于哈希表實現,查找時間復雜度平均為 ??O(1)??
- 無序存儲
2. ??常用函數(表格)??
函數/操作 | 說明 | 時間復雜度 |
---|---|---|
unordered_set<T> set; | 初始化空集合 | O(1) |
set.insert(value); | 插入元素(若存在則不插入) | 平均 O(1) |
set.find(value) | 返回指向元素的迭代器(若不存在返回?end() ) | 平均 O(1) |
set.count(value) | 返回元素存在的次數(0 或 1) | 平均 O(1) |
set.erase(value) | 刪除元素 | 平均 O(1) |
set.size() | 返回元素個數 | O(1) |
set.empty() | 判斷集合是否為空 | O(1) |
3. ??代碼用法示例?
#include <unordered_set>
#include <iostream>
using namespace std;int main() {// 初始化unordered_set<int> primes = {2, 3, 5, 7};// 插入元素primes.insert(11);primes.insert({13, 17}); // 插入多個元素// 查詢元素if (primes.count(5) > 0) {cout << "5是質數" << endl;}// 刪除元素primes.erase(7);// 遍歷for (const auto& num : primes) {cout << num << " ";}return 0;
}
4.題解
class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {//兩個for循環復雜度也就 n方// for(int i=0;i<nums.size();i++)
// for(int j=i+1;j<nums.size();j++)
// {
// if(nums[i]+nums[j]==target) return {i,j};
// }//哈希表,注意題目里的可以按任意順序返回答案,其實有暗示的意思unordered_map<int,int> m;
//由于不知道這兩個數是那兩個數,一種方法是把數組全部先放到哈希表里,然后遍歷哈希表(麻煩)
// 可以每次往哈希表里插入的時候,就檢查一下,前面插入的數有沒有匹配的(檢查的復雜度為1)for(int i=0;i<nums.size();i++)
{if (m.find((target-nums[i]))!=m.end()) return {m[target-nums[i]],i};else{m[nums[i]]=i;}
}return {};}
};