目录
LeetCode1 easy
方法1:暴力
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
for(int i=0;i<nums.size();i++)
{
for(int j=i+1;j<nums.size();j++)
{
if(nums[i]+nums[j]==target)
{
res.push_back(i);
res.push_back(j);
break;
}
}
}
return res;
}
};
方法2:哈希表
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map; //查找表
vector<int> res; //存放结果
for(int i=0;i<nums.size();i++)
{
int sub=target-nums[i];
if(map.count(sub)) //在map中找target-nums[i]
{ //找到了
res.push_back(map[sub]); //sub在map中,map[sub]为sub的索引
res.push_back(i);
break;
}
else //没有找到,将nums[i]加入到map
{
map[nums[i]]=i;
}
}
return res;
}
};
LeetCode15 medium
方法1:排序之后,固定一个数,然后对撞指针
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
int size = nums.size();
if (size < 3) return {}; // 特判
vector<vector<int> >res; // 保存结果(所有不重复的三元组)
std::sort(nums.begin(), nums.end());// 排序(默认递增)
for (int i = 0; i < size; i++) // 固定第一个数,转化为求两数之和
{
if (nums[i] > 0) return res; // 第一个数大于 0,后面都是递增正数,不可能相加为零了
// 去重:如果此数已经选取过,跳过
if (i > 0 && nums[i] == nums[i-1]) continue;
// 双指针在nums[i]后面的区间中寻找和为0-nums[i]的另外两个数
int left = i + 1;
int right = size - 1;
while (left < right)
{
if (nums[left] + nums[right] > -nums[i])
right--; // 两数之和太大,右指针左移
else if (nums[left] + nums[right] < -nums[i])
left++; // 两数之和太小,左指针右移
else
{
// 找到一个和为零的三元组,添加到结果中,左右指针内缩,继续寻找
res.push_back(vector<int>{nums[i], nums[left], nums[right]});
left++;
right--;
// 去重:第二个数和第三个数也不重复选取
// 例如:[-4,1,1,1,2,3,3,3], i=0, left=1, right=5
while (left < right && nums[left] == nums[left-1]) left++;
while (left < right && nums[right] == nums[right+1]) right--;
}
}
}
return res;
}
};
LeetCode18 medium
class Solution{
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<vector<int> > res;
if(nums.size()<4)
return res;
int a,b,c,d,_size=nums.size();
for(a=0;a<=_size-4;a++){
if(a>0&&nums[a]==nums[a-1]) continue; //确保nums[a] 改变了
for(b=a+1;b<=_size-3;b++){
if(b>a+1&&nums[b]==nums[b-1])continue; //确保nums[b] 改变了
c=b+1,d=_size-1;
while(c<d){
if(nums[a]+nums[b]+nums[c]+nums[d]<target)
c++;
else if(nums[a]+nums[b]+nums[c]+nums[d]>target)
d--;
else{
res.push_back({nums[a],nums[b],nums[c],nums[d]});
while(c<d&&nums[c+1]==nums[c]) //确保nums[c] 改变了
c++;
while(c<d&&nums[d-1]==nums[d]) //确保nums[d] 改变了
d--;
c++;
d--;
}
}
}
}
return res;
}
};
LeetCode16 medium
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
assert(nums.size() >= 3);
sort(nums.begin(), nums.end());
int N = nums.size();
int res = 0;
int minDelta = INT_MAX;
for (int i = 0; i < N - 2; i++) {
int j = i + 1;
int k = N - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
auto delta = abs(target - sum);
if (delta < minDelta) {
minDelta = delta;
res = sum;
}
if (sum < target) {
j++;
} else {
k--;
}
}
}
return res;
}
};