Day7——四数相加||、赎金信、三数之和、四数之和

简介: Day7——四数相加||、赎金信、三数之和、四数之和

前言


今日文案:

许多事情看似不可能,但在敢为人先的勇敢和坚韧执着的发奋下,会变成可能,会变成事实。看追的事情就去做,追求就有期望,发奋就有可能。

一、四数相加||


题目来源:

力扣

暴力解法思路:


四数相加==0,知道一个结果,求出四个下标。我们最容易想到暴力解法,四个for循环嵌套来一个一个遍历,枚举,但时间复杂度就去到了恐怖的O(n^4),可以,但不好。

哈希解法思路:


我们要求的是一个结果值,好像和之前查找字符串是不是相等一样,我们只需要一个++,一个--,最后数组等于0就能说明完全契合,那相加==0,不就是相反数契合吗。那四个数组,我们只需要两两组合,找出他们的结果集,再哈希就可以解决这道题了,时间复杂度也回到了O(n^2),

代码如下:

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> map;
        int target=0,count=0;        
        for(int i=0;i<nums1.size();i++)            //循环遍历出每一个结果值
        {
            for(int j=0;j<nums1.size();j++)
            {
                map[nums2[j]+nums1[i]]++;
            }
        }
        for(int i=0;i<nums1.size();i++)
        {
            for(int j=0;j<nums1.size();j++)
            {
                target=0-(nums3[i]+nums4[j]);   //target-结果值就是我们要从上面结果值找的数
                if(map.find(target)!=map.end())    //查找
                count=count+map[target];            //因为里面可能不止一个符合的结果值
            }
        }
        return count;
    }
};

二、赎金信


题目来源:

力扣

解题思路:


我们要干嘛?我们要在一个集合里找元素的个数是否和另外一个集合的元素个数相等,还是字母,26个,我们只需要使用哈希数组结构就能轻松实现。

代码如下:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int hash[26]={0},a=1;
        for(int i=0;i<ransomNote.size();i++)
        {
            hash[ransomNote[i]-'a']++;
        }
         for(int i=0;i<magazine.size();i++)
        {
            hash[magazine[i]-'a']--;
        }
         for(int i=0;i<26;i++)
        {
            if(hash[i]>0)
            a=0;
        };
        if(a==0)
        return false;
        else
        return true;
    }
};

前面的博客有写过数组解法,就不多解释了。

三、三数之和


题目描述:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

题目来源:

力扣

解题思路:


可能有朋友看到这题,会马上想到四数相加||,这乍一看确实很像,但是仔细看看,好像又不一样了,我们这里的三元组是不重复的,而且i != j、i != k 且 j != k,要是要用哈希法的话,会很麻烦,具体我也不会。

我们在这里可以用一个双指针的思路。下面是一些比较重要的点,如图:

1dfddf8fc97a4748a37ac2459be57b5b.jpeg

细节的点我会在代码上标明:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());        //排序
        int i=0,left,right;
        vector<vector<int>> ans;
        for(i=0;i<nums.size();i++)
        {
            left=i+1;
            right=nums.size()-1;
            if(nums[i]>0)                    //最小值大于0,说明不可能再有和==0了
            return ans;
            if(i>0&&nums[i]==nums[i-1])    //如果后面的值等于前面那个,那个数的所有结果集都
            continue;                        //已经用过了,直接下一层循环
            while(right>left){    //这个条件是必要的
                if(nums[i]+nums[left]+nums[right]>0)
                {
                    right--;                            //值大就左移right拉小
                }
                else if(nums[i]+nums[left]+nums[right]<0)
                {
                    left++;                                //值大就右移left拉大
                }
                else if(nums[i]+nums[left]+nums[right]==0)
                {
                    ans.push_back(vector<int>{nums[i], nums[left], nums[right]});//保存
                    while(right>left&&nums[right]==nums[right-1])    //判断重复
                    {
                        right--;
                    }
                    while(right>left&&nums[left+1]==nums[left])
                    {
                        left++;
                    }
                    left++;                //指针收缩
                    right--;
                }
            }
        }
        return ans;
    }
};

四、四数之和:


题目描述:

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n

a、b、c 和 d 互不相同

nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

题目来源:

力扣

解题思路:


与上面的有点像,但是剪枝和查重部分,有出入,直接上代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());
        int k,left,right;
        for(k=0;k<nums.size();k++)
        {
            if(k>0&&nums[k]==nums[k-1])
            {
                continue;
            }
            if(nums[k]>=0&&nums[k]>target)
            {
                break;
            }
            for(int i=k+1;i<nums.size();i++)
            {
                if(nums[i]+nums[k]>=0&&nums[i]+nums[k]>target)
                {
                    break;
                }
                if(i>k+1&&nums[i]==nums[i-1])
                {
                    continue;
                }
                left=i+1;
                right=nums.size()-1;
                while(left<right)
                {
                    if((long)nums[i]+nums[k]+nums[left]+nums[right]>target)
                    {
                        right--;
                    }
                    else if((long)nums[i]+nums[k]+nums[left]+nums[right]<target)
                    {
                        left++;
                    }
                    else
                    {
                      ans.push_back(vector<int>{nums[i],nums[k],nums[left],nums[right]});
                        while(left<right&&nums[left+1]==nums[left])
                        left++;
                        while(left<right&&nums[right-1]==nums[right])
                        right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return ans;
    }
};

总结


继续每天进步一点点。

相关文章
|
存储 文件存储 对象存储
|
存储 关系型数据库 Linux
ceph分布式存储
ceph是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。Ceph项目最早起源于Sage就读博士期间的工作(最早的成果于2004年发表),并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。RedHat及OpenStack都可与Ceph整合以支持虚拟机镜像的后端存储。
645 0
|
存储 缓存 网络协议
深入理解Linux网络——内核是如何接收到网络包的
一、相关实际问题 RingBuffer是什么,为什么会丢包 网络相关的硬中断、软中断是什么 Linux里的ksoftirqd内核线程是干什么的 为什么网卡开启多队列能提升网络性能 tcpdump是如何工作的 iptable/netfilter是在哪一层实现的 tcpdump能否抓到被iptable封禁的包 网络接收过程中如何查看CPU开销 DPDK是什么
|
存储 Linux 编译器
Linux平台上DPDK入门指南:快速提升网络性能的利器
Linux平台上DPDK入门指南:快速提升网络性能的利器
|
存储 运维 Kubernetes
分布式开源存储架构Ceph概述
k8s的后端存储中ceph应用较为广泛,当前的存储市场仍然是由一些行业巨头垄断,但在开源市场还是有一些不错的分布式存储,其中包括了Ceph、Swift、sheepdog、glusterfs等
1580 0
|
存储 缓存 Kubernetes
Kuberntes云原生实战六 使用Rook搭建Ceph集群
Kuberntes云原生实战六 使用Rook搭建Ceph集群
749 0
|
存储 缓存 NoSQL
分布式对象存储设计原理
保存像图片、音视频这类大文件就是对象存储。不仅有很好的大文件读写性能,还可通过水平扩展实现近乎无限容量,并兼顾服务高可用、数据高可靠。
926 0
|
Web App开发 人工智能 编解码
声网:如何自研支撑百万用户的毫秒级实时音视频系统?
大规模实时音视频(RTC)是疫情时代火热的在线课堂、直播、电话会议等的技术基础,但对于多数工程师来说,自研 RTC 系统的架构设计在客户端、服务端、运维、测试和质量监控上仍存在很多难点。因此我们整理了 QCon 全球软件开发大会(2021)北京站上,声网 Agora 行业架构师董海冰分享的三部分内容:RTC(实时音视频)的基础概念、场景及特点分析;自研 RTC 的架构设计和难点;展望 RTC 未来,帮你扣开实时音视频系统架构设计的大门。以下为老师分享的正文。(下文以董海冰老师第一人称叙述)
1481 0
声网:如何自研支撑百万用户的毫秒级实时音视频系统?
|
存储 弹性计算 文件存储
带你读《对象存储实战指南》第一章对象存储概述1.3存储技术架构(二)
《对象存储实战指南》第一章对象存储概述1.3存储技术架构(二)
499 0
带你读《对象存储实战指南》第一章对象存储概述1.3存储技术架构(二)
|
存储 Kubernetes 块存储
Kubernetes存储系统-云原生存储Rook部署
Rook是基于的Ceph的分布式存储系统,可以使用kubectl命令部署,也可以使用Helm进行管理和部署。 Rook官网,https://rook.io 使用Helm部署Rook Operator,https://my.
5163 0