目錄
題目介紹:
哈希表法:
復雜度分析:
思路分析:
unordered_set?和?unordered_map的比較:
1. 核心區別
2. 使用場景
3. 在本題中的選擇
4. 性能對比
5. 成員函數差異
unordered_table.begin()函數是返回的鍵還是值,unordered_set.begin()函數返回的又是什么呢?
1.?unordered_map?的?begin()
2.?unordered_set?的?begin()
關鍵區別
題目介紹:
哈希表法:
#include <unordered_set>
#include <algorithm> // for max()class Solution {
public:int longestConsecutive(vector<int>& nums) {if (nums.empty()) return 0; // 處理空數組unordered_set<int> numSet(nums.begin(), nums.end()); // 存儲所有數字int maxLen = 0;for (int num : numSet) {// 只處理序列起點(num-1不在集合中)if (numSet.find(num - 1) == numSet.end()) {int currentNum = num;int currentLen = 1;// 擴展連續序列while (numSet.find(currentNum + 1) != numSet.end()) {currentNum++;currentLen++;}maxLen = std::max(maxLen, currentLen); // 更新最大長度}}return maxLen;}
};
復雜度分析:
時間復雜度:O(n),其中 n 為數組的長度。具體分析已在上面正文中給出。
空間復雜度:O(n)。哈希表存儲數組中所有的數需要 O(n) 的空間。
思路分析:
這題的思路就是先用哈希表unordered_set裝初始nums數組,不需要索引所以用unordered_set而不是unordered_table。
首先遍歷哈希表:
1.進入條件是必須所在num-1的位置不是連續的
2.這時候currentnum和currentlen初始化,currentnum指向num這個數,currentlen為1
3.然后while循環用來計算出在這之后有多少連續的整數:
4.如果下一個數字不再連續了,則記錄更新maxlen,接著下一輪的循環
5.如果num-1都是連續的,則直接下一輪,直到num-1斷了重新初始化(即第2步)
最后返回manlen值。
unordered_set
?和?unordered_map的比較:
unordered_set
?和?unordered_map
是 C++ STL 中的兩種哈希容器
1. 核心區別
特性 | unordered_set | unordered_map |
---|---|---|
存儲內容 | 僅存儲鍵(key) | 存儲鍵值對(key-value pairs) |
用途 | 快速判斷元素是否存在(去重、集合操作) | 通過鍵快速查找/訪問關聯的值(字典) |
元素訪問 | 直接通過鍵訪問 | 通過鍵訪問對應的值(map[key] ) |
內存占用 | 更低(僅存儲鍵) | 更高(需存儲鍵和值) |
是否允許重復鍵 | 不允許(自動去重) | 不允許重復鍵(但值可重復) |
2. 使用場景
-
unordered_set
-
檢測元素是否存在(如“是否包含數字 5”)。
-
去重(如統計唯一元素個數)。
-
集合運算(并集、交集等)。
示例:
unordered_set<int> s = {1, 2, 3}; if (s.find(2) != s.end()) { /* 2存在 */ }
-
-
unordered_map
-
建立鍵到值的映射(如“學生ID到成績”)。
-
需要記錄額外信息(如數字的出現次數)。
示例:
unordered_map<int, string> m = {{1, "Alice"}, {2, "Bob"}}; cout << m[1]; // 輸出 "Alice"
-
3. 在本題中的選擇
-
為什么用?
unordered_set
?
您只需要判斷數字是否存在,無需存儲額外信息(如索引)。unordered_set
?更節省內存且語義更直接。錯誤用法(原代碼):
unordered_map<int, int> hashtable; // 存儲了無用的索引 hashtable[nums[i]] = i; // 值(i)未被使用
正確用法:
unordered_set<int> numSet(nums.begin(), nums.end()); if (numSet.find(5) != numSet.end()) { /* 5存在 */ }
4. 性能對比
-
插入/查找時間復雜度:兩者均為平均?O(1)(最壞?O(n),哈希沖突時)。
-
空間效率:
unordered_set
?更優(無需存儲值)。
5. 成員函數差異
操作 | unordered_set | unordered_map |
---|---|---|
插入元素 | insert(key) | insert({key, value}) |
訪問元素 | 只能通過迭代器遍歷 | map[key] ?或?map.at(key) |
刪除元素 | erase(key) | erase(key) |
unordered_table.begin()函數是返回的鍵還是值,unordered_set.begin()函數返回的又是什么呢?
在 C++ 的?unordered_map
?和?unordered_set
?中,begin()
?函數返回的是?迭代器(iterator),但它們的解引用行為不同,具體取決于容器類型:
1.?unordered_map
?的?begin()
-
返回內容:返回指向第一個鍵值對(
std::pair<const Key, Value>
)的迭代器。 -
訪問鍵和值:
-
鍵:用?
it->first
?或?(*it).first
。 -
值:用?
it->second
?或?(*it).second
。
-
-
示例:
unordered_map<int, string> m = {{1, "Alice"}, {2, "Bob"}}; auto it = m.begin(); cout << it->first; // 輸出鍵:1 cout << it->second; // 輸出值:"Alice"
2.?unordered_set
?的?begin()
-
返回內容:返回指向第一個元素(鍵本身)的迭代器。
-
訪問元素:直接解引用迭代器(
*it
)。 -
示例:
unordered_set<int> s = {1, 2, 3}; auto it = s.begin(); cout << *it; // 輸出元素:1(鍵本身)
關鍵區別
容器 | begin() ?返回的迭代器解引用結果 | 訪問方式 |
---|---|---|
unordered_map | std::pair<const Key, Value> | it->first (鍵)it->second (值) |
unordered_set | 直接是鍵(Key ) | *it |
求三連~~~