代码随想录day6 | 1. 两数之和 454.四数相加II 383.赎金信 15.三数之和 18.四数之和

news2024/12/23 18:34:54

文章目录

    • 1. 两数之和
    • 2. 四数相加II
    • 3. 赎金信
    • 4. 三数之和
    • 5. 四数之和

1. 两数之和

1. 两数之和
虽然是LeetCode第一题,但是还是挺难的!
在这里插入图片描述
模拟一下:
在这里插入图片描述

在这里插入图片描述

class Solution
{
public:
    vector<int> twoSum(vector<int> &nums, int tar)
    {
        unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); i++)
        {
            auto iter = m.find(tar - nums[i]);
            if (iter != m.end())
            {
                return {iter->second, i};
            }
            else
            {
                m.insert({nums[i], i});
            }
        }
        return {};
    }
};

1、为啥想到用哈西法?

因为我们在遍历nums数组的时候,我们要存放之前已经遍历过的元素(方便查询),若之前遍历过,那么就找到了一对数,满足要求。

2、为啥想到用map?

因为set只能存放key,但是我们这里还想要知道元素对应的下标,所以选取map,因为要查询效率更高,所以选取unordered_map。

2. 四数相加II

454.四数相加II
暴力解法就是4层for循环。
采用两两分组,这样循环的话,优化到了O(N2),这样和上一题的解法就差不多了。
定义一个unordered_map,key放a和b两数之和,value放a和b两数之和出现的次数,再遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。

class Solution
{
public:
    int fourSumCount(vector<int> &A, vector<int> &B, vector<int> &C, vector<int> &D)
    {
        unordered_map<int, int> map; // key存a+b值 val存a+b出现的次数
        for (int a : A)
        {
            for (int b : B)
            {
                map[a + b]++;
            }
        }
        int count = 0;
        for (int c : C)
        {
            for (int d : D)
            {
                if (map.find(0 - (c + d)) != map.end())
                {
                    count += map[0 - (c + d)];
                }
            }
        }
        return count;
    }
};

3. 赎金信

很像,242.有效的字母异位词

class Solution
{
public:
    bool canConstruct(string ransomNote, string magazine)
    {
        if (ransomNote.size() > magazine.size())
            return false;
        int hash[26] = {0}; // 题目给出都是小写字母
        for (int i = 0; i < magazine.size(); i++)
        {
            hash[magazine[i] - 'a']++;
        }
        for (int i = 0; i < ransomNote.size(); i++)
        {
            hash[ransomNote[i] - 'a']--;
            if (hash[ransomNote[i] - 'a'] < 0)
            {
                return false;
            }
        }
        return true;
    }
};

4. 三数之和

15.三数之和

利用双指针法

class Solution
{
public:
    vector<vector<int>> threeSum(vector<int> &nums)
    {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        for (int i = 0; i < nums.size(); i++)
        {
            if (nums[i] > 0)
                return res;

            // 对于a去重 用nums[i] == nums[i - 1]?不用nums[i] == nums[i + 1]
            if (i > 0 && nums[i] == nums[i - 1])
                continue;

            int left = i + 1;
            int right = nums.size() - 1;
            while (left < right) // 为啥不能left<=right?
            {
                if (nums[i] + nums[left] + nums[right] > 0)
                    right--;
                else if (nums[i] + nums[left] + nums[right] < 0)
                    left++;
                else
                {
                    res.push_back({nums[i], nums[left], nums[right]});

                    // 对于 b、c 去重!
                    // 去重b、c要放在这里,因为我们要至少收获一个结果集
                    while (left < right && nums[left] == nums[left + 1])
                        left++;
                    while (left < right && nums[right] == nums[right - 1])
                        right--;
					// 找到答案时,双指针同时收缩
                    left++;
                    right--;
                }
            }
        }
        return res;
    }
};

整体模拟:
在这里插入图片描述
使得a + b +c =0,我们这里相当于 a = nums[i],b = nums[left],c = nums[right]。
移动left 和right, 如果nums[i] + nums[left] + nums[right] > 0,right- -,如果nums[i] + nums[left] + nums[right] < 0,left++;直到等于0,把结果拿出来就好了。

1、为啥要排序?

因为题目要求不能有重复的三元组,这样能够不遗不漏。排序完后,方便后续指针的加减。

去重不是去掉nums中的元素,而是去掉相同的结果集,题目要求了结果集不能重复

2、[难点] 如何对a去重?为啥要nums[i] == nums[i-1]这样写?

直接跳过去就行了。
但是判断条件 nums[i] 与 nums[i + 1]是否相同,还是判断 nums[i] 与 nums[i-1] 是否相同呢,那就是选择nums[i] 与 nums[i-1],若选择nums[i]==nums[i+1]那就我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1,那这组数据就pass了,本来这组数据是要算作结果的。

3、为啥要while(left<right) 不带等号?

0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组。

4、如何对b 、c去重?

也是一样的道理:

while (right > left && nums[right] = nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;

5. 四数之和

18.四数之和

一定要先做三数之和
这个题和三数之和的逻辑差不多,都可以使用双指针法。
在这里插入图片描述

class Solution
{
public:
    vector<vector<int>> fourSum(vector<int> &nums, int tar)
    {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        for (int k = 0; k < nums.size(); k++)
        {
            // 一级剪枝
            if (nums[k] > tar && nums[k] >= 0)
            {
                break;
            }
            // 一级去重:对于nums[k]去重
            if (k > 0 && nums[k] == nums[k - 1])
            {
                continue;
            }
            // 三数之和的逻辑
            for (int i = k + 1; i < nums.size(); i++)
            {

                // 二级剪枝
                if (nums[k] + nums[i] > tar && nums[k] + nums[i] >= 0)
                {
                    break;
                }
                // 二级去重:对于nums[i]去重
                if (i > k + 1 && nums[i] == nums[i - 1])
                {
                    continue;
                }
                int left = i + 1;
                int right = nums.size() - 1;
                while (left < right)
                {
                    if ((long)nums[k] + nums[i] + nums[left] + nums[right] > tar)
                        right--;
                    else if ((long)nums[k] + nums[i] + nums[left] + nums[right] < tar)
                        left++;
                    else
                    {
                        res.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});
                        // 对于left 和 right 再进行去重
                        while (left < right && nums[left] == nums[left + 1])
                            left++;
                        while (left < right && nums[right] == nums[right - 1])
                            right--;

                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
};

1、一级剪枝

if (nums[k] > tar && nums[k] >= 0)
{
    break;
}

2、一级去重,nums[k]去重

if (k > 0 && nums[k] == nums[k - 1])
{
    continue;
}

3、二级剪枝处理

nums[k] + nums[i]看做一个整体,然后再去移动left和right进行缩小判断。

4、二级去重,nums[i]去重

一样的道理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决appium-doctor报opencv4nodejs cannot be found

一、下载cmake 在CMake官网下载&#xff1a;cmake-3.6.1-win64-x64.msi 二、安装cmake cmake安装过程 在安装时要选择勾选为所有用户添加CMake环境变量 三、检查cmake安装 重新管理员打开dos系统cmd命令提示符&#xff0c;输入cmake -version cmake -version四、安装opencv4no…

美国某市政府出现重大数据泄露事件,疑似离职人员未删除权限

近日&#xff0c;美国得克萨斯州西部城市敖德萨市市长Javier Joven宣布&#xff0c;自2022年12月以来&#xff0c;已经有人多次使用前敖德萨市检察官Natasha Brooks的账户非法访问了该市的政府系统&#xff0c;并将大量敏感信息通过电子邮件转移到了一个私人账户&#xff0c;敖…

创建ReWorks自引导工程

自引导工程开发与集成流程 2、新建工程 3、资源配置 4、代码编写 5、构建项目 右键构件项目&#xff0c;或选择“构建按钮”构建项目 6、配置TFTP服务路径 右键IMX6Q_SMP文件夹&#xff0c;配置TFTP服务路径 或 7、打开串口终端 8、启动开发板 查看网卡 素材来源于&#xff1…

社区版、专业版、企业版、专有版,smardaten四个版本到底怎么选?

这是一篇新老用户都不容错过的文章&#xff01; 要问今年上半年smardaten最大的变化&#xff0c;轻量化版本的推出双手奉上~~ 这时每一个心痒痒的客户&#xff0c;几乎都要迷茫的问睿睿两个问题&#xff1a;“现有版本之间有什么区别&#xff1f;都怎么收费&#xff1f;”。 …

在Microsoft Excel中如何快速将上下两行数据合并为一行?

合并单元格是电子表格初学者最常用的选项之一。当一组单元格、行或列需要标题或标签时,合并单元格是一种常用的技术。 合并单元格时,仅保留区域左上角单元格中的值或公式,并将其显示在合并后的单元格中。将丢弃任何其他值或公式,那么如何在新的空白单元格中将两行数据合并…

yo!这里是类的默认成员函数

目录 前言 默认成员函数 构造函数 1.介绍 2.注意点 析构函数 1.介绍 2.注意点 拷贝构造函数 1.介绍 2.注意点 赋值运算符重载 1.介绍 2.注意点 取地址及const取地址操作符重载 1.介绍 2.注意点 后记 前言 在学习c的过程中&#xff0c;我们知道&#xff0c;c是…

Windows下PyTorch深度学习环境配置(GPU)

一&#xff1a;下载Anaconda &#xff08;路径最好全英文&#xff09; &#xff08;下载好后&#xff0c;可以创建其他虚拟环境&#xff0c;因为是自己学习&#xff0c;所以先不放步骤&#xff0c;有需要者可以参考B站up我是土堆的视频&#xff09; 二&#xff1a;利用 conda…

Stream实现List和Map互转总结

本文来说下Stream实现List和Map互转总结 文章目录 实体类Map转List代码List转Map 实体类 本篇介绍Stream流List和Map互转&#xff0c;同时在转换过程中遇到的问题分析。 package cn.wideth.collect;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArg…

【Linux】udp服务器实现大型网络聊天室

udp终结篇~ 文章目录 前言一、udp服务器实现大型网络聊天室总结 前言 根据上一篇文章中对于英汉互译和远程操作的两个小功能大家应该已经学会了&#xff0c;我们的目的是让大家可以深刻的理解udp服务器所需要的接口已经实现的简单步骤&#xff0c;下面我们开始实现网络聊天室。…

Spring 6【DI的两种方式、自动注入】(四)-全面详解(学习总结---从入门到深化)

目录 八、DI的两种方式 九、自动注入 八、DI的两种方式 IoC是由IoC容器帮助实例化Bean&#xff0c;并且在IoC容器内部注入关联属性(对象)的过程。 在上面演示的都是如何实例化Bean&#xff0c;下面演示的是如果给Bean注入属性。也就是说在讲解IoC/DI的另 一半功能。 在前面…

实训笔记7.18

实训笔记7.18 7.18一、座右铭二、Hadoop大数据技术 大数据软件一般都要求7*24小时不宕机三、Hadoop的组成3.1 HDFS3.2 MapReduce3.3 YARN3.4 Hadoop Common 四、Hadoop生态圈五、Hadoop的安装问题5.1 Hadoop的本地安装模式-基本不用5.2 Hadoop的伪分布安装模式5.3 Hadoop的完全…

webpack插件compression-webpack-plugin

Vue配置compression-webpack-plugin实现Gzip压缩 1、为什么要压缩&#xff1f; 打包的时候开启gzip可以很大程度减少包的大小&#xff0c;页面大小可以变为原来的30%甚至更小&#xff0c;非常适合于上线部署。更小的体积对于用户体验来说就意味着更快的加载速度以及更好的用户…

SOPC之NiosⅡ系统(五)

NIOS Ⅱ系统实例 目录 2.创建BSP工程 2.1 创建BSP工程 2.2 BSP Editor 2.3 创建C代码文件 3.Nios Ⅱ实例 3.1 Hello NIOS Ⅱ 3.2 System ID与Timestamp 3.3 蜂鸣器定时鸣叫 3.4 拨码开关输入GIO控制 4.FPGA器件的代码固化 4.1 嵌入式软件HEX文件生成 4.2 程序存储…

RocketMQ环境搭建

环境搭建 环境准备 下载地址: https://downloads.apache.org/rocketmq/4.9.5/安装 上传至服务器 mkdir /usr/soft #上传至此目录/usr/softmkdir /usr/soft 解压 cd /usr/soft unzip rocketmq-all-4.9.5-bin-release.zip移动 mkdir /usr/local/rocketmq cd /usr/soft mv r…

Mysql 修改group_concat_max_len的默认值

1.前言 最近在进行递归查询组织及其下属组织时&#xff0c;发现数据查询不全&#xff0c;子组织数据查询不出来的问题。经排查发现是group_concat_max_len的长度不足引起的&#xff0c;默认情况下group_concat_max_len1024&#xff0c;所以我们需要修改这个默认参数。 2.SQL语…

.net core控制台应用程序在linux运行

1&#xff09;创建.net 6.0控制台应用程序 2&#xff09;在应用根目录执行cmd命令发布应用&#xff1a;dotnet publish -o .\deploy 3&#xff09;将发布文件上传到服务器 4&#xff09;运行控制台应用程序&#xff08;dotnet /home/app/ConsoleApp/ConsoleApp5.dll&#xff09…

卡尔曼与扩展卡尔曼的区别与推导

1.卡尔曼的推导&#xff1a; 1&#xff09;先看系统随机系统状态空间模型&#xff1a;&#xff08;线性&#xff09; 所谓线性是指递推或者状态转移方程是线性的 至于参数解释自己去看书&#xff0c;本文旨在捋顺推导思路。 2&#xff09;k-1时刻值减去k-1的状态最优估计k-1时…

Vscode设置忽略文件,忽略node-modules、dist

####看图 files.exclude 设置排除和显示的文件夹 search.exclude 设置搜索时忽略的文件夹

WEB:Cat

背景知识 命令执行漏洞 Django框架 题目 先ping一下&#xff0c;输入127.0.0.1 这个输入可能存在命令执行的操作&#xff0c;但是经过尝试之后并不能正常执行 127.0.0.1&&dir、127.0.0.1&&ls、127.0.0.1|ls均被屏蔽&#xff0c;但经过尝试可知&#xff0c;网…

matplotlib笔记:qbstyle设置matplotlib 主题

0 原始matplotlib import numpy as np import matplotlib.pyplot as pltxnp.linspace(0,100) ynp.sin(100*x)plt.plot(x,y); 1 light from qbstyles import mpl_style mpl_style(darkFalse) #开启light主题 plt.plot(x,y); 2 dark from qbstyles import mpl_style mpl_styl…