哈希表详解参考https://blog.csdn.net/moX980/article/details/107808608
Leetcode1
为了加速,可以使用哈希表存储,注意题目中说的不能用重复的数 哈希表存放的是<nums[i], i>
遍历数组,先判断后往哈希表存值
- 判断哈希表中是否有target-nums[i]这个数
- 没有 就将num[i]位置存放下标i
- 有 说明出答案了 答案就为 h[target - nums[i]] 和 i
class Solution {
public:
unordered_map<int, int> h;
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
for(int i = 0; i < nums.size(); i++){
if(h.find(target - nums[i]) == h.end()){
h[nums[i]] = i;
continue;
}
ret.push_back(h[target - nums[i]]);
ret.push_back(i);
break;
}
return ret;
}
};
Leetcode15
题目分析:
- 特判,对于数组长度 nn,如果数组为 nullnull 或者数组长度小于 33,返回 [][]。
- 对数组进行排序。
- 遍历排序后数组:
- 若 nums[i]>0nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 00,直接返回结果。
- 对于重复元素:跳过,避免出现重复解
- 令左指针 L=i+1L=i+1,右指针 R=n-1R=n−1,当 L<RL<R 时,执行循环:
- 当 nums[i]+nums[L]+nums[R]==0nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解
- 若和大于 00,说明 nums[R]nums[R] 太大,RR 左移
- 若和小于 00,说明 nums[L]nums[L] 太小,LL 右移
作者:wu_yan_zu
链接:https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/
来源:力扣(LeetCode)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> vec;
vector<vector<int>> ret;
for(int i = 0; i < nums.size(); i++){
if(nums[i] > 0) break;
if(i > 0 && nums[i] == nums[i - 1]) continue;
int l = i + 1, r = nums.size() - 1;
int temp = 0 - nums[i];
while(l < r){
//cout << l << " " << r << endl;
if(l == i) l++;
if(r == i) r--;
if(nums[l] + nums[r] == temp){
vec.push_back(nums[i]);
vec.push_back(nums[l]);
vec.push_back(nums[r]);
sort(vec.begin(), vec.end());
ret.push_back(vec);
vec.clear();
l++;
while(l < r && nums[l] == nums[l - 1]) l++;
r--;
while(l < r && nums[r] == nums[r + 1]) r--;
}else if(nums[l] + nums[r] < temp) {
l++;
}
else {
r--;
}
}
}
//set<vector<int>> s(ret.begin(), ret.end());
//ret.assign(s.begin(), s.end());
return ret;
}
};
Leetcode18
题目分析:与15题三数之和类似,多加一层循环即可 注意target不再是0 0是有特殊性质的
给出两种解法三层循环 + 哈希表 和 两层循环 + 双向指针
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
vector<int> vec;
vector<vector<int>> ret;
unordered_map<int, int> h;
for(int i = 0; i < nums.size(); i++){
h[nums[i]] = i;
}
for(int i = 0; i < nums.size(); i++){
if(nums[i] == 0) continue;
for(int j = i + 1; j < nums.size(); j++){
for(int k = j + 1; k < nums.size(); k++){
int temp = target - nums[i] - nums[j] - nums[k];
if(h.find(temp) != h.end() && h[temp] > k)
vec.push_back(nums[i]);
vec.push_back(nums[j]);
vec.push_back(nums[k]);
vec.push_back(nums[h[temp]]);
ret.push_back(vec);
vec.clear();
}
}
}
}
set<vector<int>> s(ret.begin(), ret.end());
ret.assign(s.begin(), s.end());
return ret;
}
};
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<int> vec;
vector<vector<int>> ret;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
//if(nums[i] > target) break; 不能有 三数之和的target0有特殊性
if(i > 0 && nums[i] == nums[i - 1]) continue;
for(int j = i + 1; j < nums.size(); j++){
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
int l = j + 1, r = nums.size() - 1;
/*优化!!!
if(l + 1 < nums.size()){
int min = nums[i] + nums[j] + nums[l] + nums[l + 1];
if(min > target) continue;
}
int max = nums[i] + nums[j] + nums[r] + nums[r - 1];
if(max < target) continue;
*/
int temp = target - nums[i] - nums[j];
while(l < r){
//cout << l << " " << r << endl;
if(l == i) l++;
if(r == i) r--;
if(nums[l] + nums[r] == temp){
vec.push_back(nums[i]);
vec.push_back(nums[j]);
vec.push_back(nums[l]);
vec.push_back(nums[r]);
sort(vec.begin(), vec.end());
ret.push_back(vec);
vec.clear();
l++;
while(l < r && nums[l] == nums[l - 1]) l++;
r--;
while(l < r && nums[r] == nums[r + 1]) r--;
}else if(nums[l] + nums[r] < temp) {
l++;
}
else {
r--;
}
}
}
}
//set<vector<int>> s(ret.begin(), ret.end());
//ret.assign(s.begin(), s.end());
return ret;
}
};