代码随想录打卡第7天 454.四数相加II 383. 赎金信 15. 三数之和 第18题. 四数之和

454.四数相加II

题目链接:https://leetcode.cn/problems/4sum-ii/submissions/

算法核心:转化为去哈希表中查找元素的思路。
思路:
直观的想法是使用四层暴力循环,但是时间复杂度太高。可以想到,其实可以把它转化为元素查找的思路。
两两一组,1 2两个数组元素之和存入哈希表中,然后遍历3+4的时候,计算0减去3+4元素的和,记为target,去哈希表中查改元素是否存在。

代码:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {

    unordered_map<int,int> search;
    int len1=nums1.size();
    int len2 = nums2.size();
    int len3 = nums3.size();
    int len4 = nums4.size();
    int count = 0;
    for(int i=0;i<len1;i++)
    {
        for(int j=0;j<len2;j++)
        {
            int sum = nums1[i] + nums2[j];
            if(search.find(sum) == search.end())
            {
                search[sum] = 1;
            }
            else
            {
                search[sum] += 1;
            }
            
        }
    }
    for(int i=0;i<len1;i++)
    {
        for(int j=0;j<len2;j++)
        {
            int sum = nums3[i] + nums4[j];
            int target = 0 - sum;
            if(search.find(target) != search.end())
            {
                int target_count = search[target];
                count += target_count;
            }
            
        }
    }
    return count;

}

};

  1. 赎金信
    题目:https://leetcode.cn/problems/ransom-note/
    核心思路:查找一个元素是否在某个集合中。

将magazine的元素存入map,并计数,在map中查找ransomNote的元素,如果全部查到,返回true,否则false

代码:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<int, int> magazine_map;
int lenm = magazine.length();
int lenr = ransomNote.length();
for(int i=0;i<lenm;i++)
{
if(magazine_map.find(magazine[i]) == magazine_map.end())
{
magazine_map[magazine[i]] = 0;
}
magazine_map[magazine[i]] += 1;

    }
    for(int i=0;i<lenr;i++)
    {
         if(magazine_map.find(ransomNote[i]) != magazine_map.end() && magazine_map[ransomNote[i]]!=0)
         {
             magazine_map[ransomNote[i]] -= 1;
         }
         else
            return false;
    }
    return true;
}

};

  1. 三数之和
    题目链接:https://leetcode.cn/problems/3sum/submissions/
    算法核心:这里涉及到去重的操作,用哈希表比较复杂。结果要求去重,可以想到需要对数组进行排序。

思路:
i从头遍历,left指向剩下元素的左边,right指向剩下元素的右边,排序过后的数据,和的变化是有规律的,和大于0,right--,和小于0,left++。
重要的是两个指针去重的过程。

代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
//用三个指针解决
vector<vector<int>> result;
sort(nums.begin(), nums.end());
int len = nums.size();
for(int i=0;i<len-2;i++)
{
if(i>0&&nums[i]==nums[i-1])
continue;
int left = i+1;
int right = len-1;
while(left<right)
{
if((nums[i] + nums[left] + nums[right]) < 0)
{
left++;
}
else if((nums[i] + nums[left] + nums[right]) >0)
{
right--;
}
else
{
result.push_back(vector<int> {nums[i], nums[left],nums[right]});
left++;
right--;
while(left<right && left!=(i+1) &&nums[left]==nums[left-1])
left++;
while(left<right && right!=(len-1)&&nums[right]==nums[right+1])
right--;

            }
        }

       
    }
     return result;
}

};

第18题. 四数之和
题目链接:https://leetcode.cn/problems/4sum/submissions/
算法思想:同三数之和
注意和越界问题(暂未解决)

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int len = nums.size();
vector<vector<int> > result;
for(int i=0;i<len-3;i++)
{
if(i>0&&nums[i]==nums[i-1])
continue;
if(target>=0 && nums[i]>target)
break;
for(int j=i+1;j<len-2;j++)
{
if(j>i+1&&nums[j]==nums[j-1])
continue;
if (nums[j] + nums[i] > target && nums[j] + nums[i] >= 0) {
break;
}
int left = j+1;
int right = len-1;
while(left<right)
{
cout<<"i:"<<i<<" j"<<j <<"start: left:"<<left<<" right:"<<right<<endl;
if(nums[i] + nums[j] + nums[left] + nums[right] > target)
{
right--;

            }
            else if(nums[i] + nums[j] + nums[left] + nums[right] < target)
            {
                left++;
            }
            else{
    result.push_back(vector<int>{nums[i], nums[j], nums[left], nums[right]});
                left++;
                right--;
                // cout<<"left:"<<left<<" right:"<<right<<endl;
                while(left<right &&nums[left]==nums[left-1])
                    left++;
                while(left<right &&nums[right]==nums[right+1])
                    right--;
                // cout<<"end: left:"<<left<<" right:"<<right<<endl;

            }
            }
           
        }
    }
    return result;
}

};

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容