文章目录
一、LeetCode-1. 两数之和
题目
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashMap;
hashMap[nums[0]] = 0;
for(int i=1; i<nums.size(); i++) {
auto it = hashMap.find(target-nums[i]);
if(it != hashMap.end()) {
return {i, it->second};
}
hashMap[nums[i]] = i;
}
return {};
}
};
思路
最简单的思路是嵌套两层for循环,然后提交代码,超时
可以利用哈希表将时间复杂度将为O(n)
对每一个 target
,我们可以分为 x
和 target - x
,通过遍历nums确定 x
,再在哈希表中查找 target - x
,若存在则返回value索引,否则将 x
加入哈希表中
复杂度
时间复杂度O(n),空间复杂度O(n)
二、LeetCode-349. 两个数组的交集
题目
代码
//HashTable
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
unordered_set<int> n1(nums1.begin(), nums1.end());
for(int i=0; i<nums2.size(); i++) {
if(n1.empty()) { //检查n1是否已经为空,若空则返回ans
return ans;
}
if(n1.count(nums2[i])) {
ans.push_back(nums2[i]);
n1.erase(nums2[i]);
}
}
return ans;
}
};
//双指针
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
int p = 0, q = 0;
int res;
vector<int> ans;
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
res = nums1[0] - 1;
while(p < nums1.size() && q < nums2.size()) {
if(nums1[p] == res) {
p++;
continue;
}
if(nums2[q] == res) {
q++;
continue;
}
if(nums1[p] > nums2[q]) {
q++;
}
else if(nums1[p] < nums2[q]) {
p++;
}
else {
ans.push_back(nums1[p++]);
res = nums2[q++];
}
}
return ans;
}
};
思路一(哈希表)
先将其中一个数组的元素用哈希表存储
再遍历另一个数组的元素,查找哈希表 n1
中是否存在该元素,若存在则push进 ans
中,并且将该元素从 n1
中删除
当 n1
为空之后,中断循环直接返回ans
思路二(双指针)
先对两个数组排序,使其保证有序性
再通过 p
和 q
同时遍历nums1和nums2
此时会出现三种情况:
p
所指的值与q
相等,则将值push进ans
并通过res
标记当前添加值- 若
p
的所指值与q
不同,则谁小谁向右移动一位- 若两指针所指的值与
res
相等,则当前指针向右移动一位
当某一指针遍历完某个对应数组时,结束循环返回ans
复杂度
思路一:时间复杂度O(m+n),空间复杂度O(m+n)
思路二:时间复杂度O(mlogm+nlogn),空间复杂度(logm+logn)
for (auto x : nums1)
注意代码:
for (auto x : nums1)
这里语句auto i : nums1的效果就是遍历容器nums1,一般当然是使用iteratorl来遍历,写法比这个复杂一点:
for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++)
for (vector<int>::iterator it = nums.begin(); it < nums.end(); it++)
摘自https://www.cnblogs.com/PiaYie/p/14977764.html
三、LeetCode-350. 两个数组的交集 II
题目
代码
//HashTable
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
unordered_map<int, int> n1;
for(int num : nums1) {
n1[num]++;
}
for(int num : nums2) {
if(n1.count(num)) {
ans.push_back(num);
n1[num]--;
if(n1[num] == 0) {
n1.erase(num);
}
}
}
return ans;
}
};
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
int p = 0, q = 0;
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
while(p < nums1.size() && q < nums2.size()) {
if(nums1[p] == nums2[q]) {
ans.push_back(nums1[p]);
p++;
q++;
} else {
nums1[p] < nums2[q] ? p++ : q++;
}
}
return ans;
}
};
思路一(哈希表)
使用哈希表 n1
记录nums1,key为nums1元素值,value为对应值出现的次数
当nums2中有元素在 n1
中,则将该元素push进 ans
中并减少其在 n1
中出现的次数,即 value-1
当value为0时,则删除该key
优化
若 nums1
的大小比 nums2
小,为了减小比较次数
-
可以交换
nums1
与nums2
,只需在函数最开始加上if (nums1.size() > nums2.size()) { return intersect(nums2, nums1); }
-
在遍历
nums2
最开始加上if (n1.empty()) { return ans; }
思路二(双指针)
这个思路与上一题思路有所简化
先对两个数组排序,使其保证有序性
再通过 p
和 q
同时遍历nums1和nums2
此时会出现两种情况:
p
所指的值与q
相等,则将值push进ans
- 若
p
的所指值与q
不同,则谁小谁向右移动一位
当某一指针遍历完某个对应数组时,结束循环返回ans
复杂度
思路一:时间复杂度O(m+n),空间复杂度O(n),优化后的空间复杂度O(min(m, n))
思路二:时间复杂度O(mlongm+nlogn),空间复杂度O(logm+logn)