hashmap和hashset会自动排序,使用红黑树实现。
1. 数组中两个数的和为给定值
1
可以先对数组进行排序,然后使用双指针方法或者二分查找方法。这样做的时间复杂度为 O(NlogN),空间复杂度为 O(1)。(时间复杂度为什么不是logN平方?)
用 HashMap 存储数组元素和索引的映射,在访问到 nums[i] 时,判断 HashMap 中是否存在 target - nums[i],如果存在说明 target - nums[i] 所在的索引和 i 就是要找的两个数。该方法的时间复杂度为 O(N),空间复杂度为 O(N),使用空间来换取时间。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for (int i = 0; i < nums.size(); ++i) {
if (m.count(target - nums[i])) {
return {i, m[target - nums[i]]};
}
m[nums[i]] = i;
}
return {};
}
};
注意这里不需要两个for循环,不需要先把hashmap的数值先放进去,一边对比一边放就好了。
2. 判断数组是否含有重复元素
217
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int, int> m;
for (int i = 0; i < nums.size(); ++i) {
if (m.find(nums[i]) != m.end()) return true;
++m[nums[i]];
}
return false;
}
};
这里用了find 改成count也行
if (m.count(nums[i])) return true;
m[nums[i]]=i;
3. 最长和谐序列
594 和谐序列中最大数和最小数之差正好为 1,应该注意的是序列的元素不一定是数组的连续元素。
class Solution {
public:
int findLHS(vector<int>& nums) {
int res = 0;
map<int, int> m;
for (int num : nums) ++m[num];
for (auto a : m) {
if (m.count(a.first + 1)) {
res = max(res, m[a.first] + m[a.first + 1]);
}
}
return res;
}
};
这里的auto a:m到底是什么类型啊??? 不是map<int,int>::iterator类型啊
4. 最长连续序列
128 要求以 O(N) 的时间复杂度求解
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
hashset还是比较简单的 注意每次要删掉 这样不用重复再计算了
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int res = 0;
unordered_set<int> s(nums.begin(), nums.end());
for (int val : nums) {
if (!s.count(val)) continue;
s.erase(val);
int pre = val - 1, next = val + 1;
while (s.count(pre)) s.erase(pre--);
while (s.count(next)) s.erase(next++);
res = max(res, next - pre - 1);
}
return res;
}
};
hashmap的实现还是需要思考的 每次遇到重复的时候不要再计算了 然后每次边界都要更新
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int res = 0;
unordered_map<int, int> m;
for (int num : nums) {
if (m.count(num)) continue;
int left = m.count(num - 1) ? m[num - 1] : 0;
int right = m.count(num + 1) ? m[num + 1] : 0;
int sum = left + right + 1;
m[num] = sum;
res = max(res, sum);
m[num - left] = sum;
m[num + right] = sum;
}
return res;
}
};