代码随想录 Day6 哈希 LeetcodeT454 四数之和II T383赎金信 T15 三数之和 T18 四数之和

news2024/12/25 0:30:12

本文代码思路来源于:

代码随想录

前言

希望大家在刷这部分题的时候先熟悉熟悉哈希结构的基本常用api,比较方便理解.

LeetCode T454 四数之和

题目链接:454. 四数相加 II - 力扣(LeetCode)

题目思路

暴力解法仍然是遍历四个数组解决此题,

哈希的思路有点类似于两数之和的解决方式,我们可以将四个数组分成两部分,数组1和数组2的和形成一个新数组(便于理解并没有去这样做,只是遍历两个数组),同理三四号数组也是一样,

1.首先我们创建一个HashMap,key放两数之和,value放和出现的次数

2.遍历数组1和数组2,将两数之和和出现次数放到map中

3.遍历数组3和数组4,在HashMap中查找是否存在0-前面的两数之和,存在就用res变量来记录

getOrDefault函数解释

代码示例

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer,Integer> map = new HashMap<>();
        int res = 0;
        for(int i:nums1)
        {
            for(int j:nums2)
            {
                int sum = i+j;
                map.put(sum,map.getOrDefault(sum,0)+1);
            }
           
        }
        for(int i:nums3)
        {
            for(int j :nums4)
            {
                res+=map.getOrDefault(0-i-j,0);
            }
        }
        return res;

    }
}

LeetCode T383 赎金信

题目链接:383. 赎金信 - 力扣(LeetCode)

题目思路

这题乍一看有点像我们的相同字母的异序词那道题,那道题我们使用了哈希数组来实现,实际上这道题我们也能如法炮制,因为题目说了字符串全是小写字母,数量有限,很方便我们来映射,下面我们来说说基本步骤:

1.首先我们创建一个record数组用来当我们的哈希数组用来映射

2.然后我们将magazine字符串转成数组再用字符c遍历,c-'a'就是数组的下标,我们让这个位置的元素++即可

3.接着同理用字符c遍历ransomNote遍历,执行--操作

4.for循环遍历数组record,判断是否有小于0的数字,如果有,就返回false,没有就返回true.

代码实现

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] record = new int[26];
        if(ransomNote.length()>magazine.length())
        {
            return false;
        }
      
      for(char c:magazine.toCharArray())
      {
          record[c-'a']++;
      }
      for(char c:ransomNote.toCharArray())
      {
          record[c-'a']--;
      }

        for(int j: record)
        {
            if(j < 0)
            {
                return false;
            }
        }
        return true;

    }
}

 LeetCode T15 三数之和

题目链接:15. 三数之和 - 力扣(LeetCode)

题目思路

使用双指针法,首先我们创建一个二维数组res,然后对数组进行排序.(降序排列)

总体思路是i指向第一个元素的下标,left指针指向i+1的下标,right指针指向length-1的下标,然后for循环遍历数组,首先判断i下标的值是否小于0,如果小于0则直接返回数组元素,如果不是则进行判断,三数之和大于0的话,则应该让right向前走,反之则让left向后走,好了,剩下就是处理细节的去重操作了.也是本题的精华所在

去重逻辑的思考 

首先这里我们知道,三数之和不能取重复的三元组,比如 {1,1,-1,0},这里的{1,-1,0}这个三元组只能取一次,那么我们就要进行去重,首先对nums[i]进行去重,这里有两种去重方式,第一种是nums[i]nums[i+1]进行比较,还有一种是nums[i]nums[i-1]进行比较,我们到底选哪一种呢?
 

我们不妨就{-1,-1,2}这个例子来看,如果我们选择了第一种去重方式,那么我们就会发现,当遍历到第一个-1的时候,判断下一个也是-1,那这组数据就直接被pass了,这里强调一下我们要的三元组组内数据可以重复,但是三元组不能重复,例如{0,0,0}也是满足要求的一个三元组.

所以对于第一个去重操作,我们应该这样写:

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

接下来就是对nums[right]和nums[left]进行去重,我们知道数组是排好序的,如果三个数加起来是大于0的,我们就可以让right指针向前走,反之我们应该让left指针向后走.

但细想一下,这种去重其实对提升程序运行效率是没有帮助的.

拿right去重为例,即使不加这个去重逻辑,依然根据 while (right > left) 和 if (nums[i] + nums[left] + nums[right] > 0) 去完成right-- 的操作。

多加了 while (left < right && nums[right] == nums[right + 1]) right--; 这一行代码,其实就是把 需要执行的逻辑提前执行了,但并没有减少 判断的逻辑。

最直白的思考过程,就是right还是一个数一个数的减下去的,所以在哪里减的都是一样的。

所以这种去重 是可以不加的。 仅仅是 把去重的逻辑提前了而已。

代码实现

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List <List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0;i<nums.length;i++)
        {
            if(nums[i]>0)
            {
                return res;
            }              
            if(i>0 && nums[i-1] == nums[i])
            {
                continue;
            } 
            int left = i+1;
            int right = nums.length-1;
            while(left<right)
            {
                int  sum = nums[i] + nums[left] + nums[right];
                if(sum >0)
                {
                    right--;
                }
                else if(sum<0)
                {
                    left++;
                }
                else
                {
                    res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while(left<right && nums[right] == nums[right-1])
                {
                    right--;
                }
                while(left<right &&nums[left] == nums[left + 1] )
                {
                    left++;
                }
                left++;
                right--;
                }
                
            }
        }
        return res;
        

    }
}

LeetCode T18 四数之和

题目链接:18. 四数之和 - 力扣(LeetCode)

 

题目思路

本质上就是在三数之和,外面再套了一层for循环,重点就是这个去重的过程如何进行,下面我们来仔细分析一下去重的过程

去重的思路 

有人可能上来就按照三数之和的思路上来就判断nums[i]和target的大小,这里就出问题了,首先三数之和保证了target是0,这里target不知道是多少,所以我们要保证我们的nums[i]>0才可以,不然两个负数相加也可以越加越小啊,这明显不满足题目要求,我们注意这里虽然是排好序的数字,但是直接用nums[i]和target做判断未免太过武断,综上所述我们是这样操作的.

if (nums[i] > 0 && nums[i] > target) {
     return result;
}

然后进行和三数之和一样的去重操作

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

接着第二层for循环,先剪枝去重,接着进行双指针

 if(nums[i]+ nums[j]>target && nums[i]>=0){
      return result;
 }
 if(j>i+1 && nums[j] == nums[j-1])
 {
       continue;
 }

代码实现

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0;i<nums.length;i++)
        {
            //一级剪枝
            if(nums[i]>target && nums[i]>0)
            {
                return result;
            }
            if(i>0 && nums[i] == nums[i-1])
            {
                continue;
            }
            for(int j = i+1;j<nums.length;j++)
            {
                if(nums[i]+ nums[j]>target && nums[i]>=0){
                    return result;
                }
                if(j>i+1 && nums[j] == nums[j-1])
                {
                    continue;
                }
                int left = j+1;
                int right = nums.length-1;
                while(right>left)
                {
                    long sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if(sum>target)
                    {
                        right--;
                    }
                    else if(sum < target)
                    {
                        left++;
                    }
                    else
                    {
                        result.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(right>left && nums[left] == nums[left+1] )
                        {
                            left++;
                        }
                        while(right>left && nums[right] == nums[right-1])
                        {
                            right--;
                        }
                        left++;
                        right--;
                    }
                }
            }
            
        }
        return result;

    }
}

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

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

相关文章

干货分享 | TSMaster—CCP/XCP标定功能详解

众所周知&#xff0c;CCP是CAN Calibration Protocol CAN 标定协议的缩写&#xff0c;XCP是Universal Measurement and Calibration Protocol 通用测量与标定协议的缩写。二者都普遍使用于开发、测试和车载标定&#xff0c;由ASAM&#xff08;自动化和测量系统标准化协会&#…

k8s--storageClass自动创建PV

文章目录 一、storageClass自动创建PV1.1 安装NFS1.2 创建nfs storageClass1.3 测试自动创建pv 一、storageClass自动创建PV 这里使用NFS实现 1.1 安装NFS 安装nfs-server&#xff1a; sh nfs_install.sh /mnt/data03 10.60.41.0/24nfs_install.sh #!/bin/bash### How to i…

STM32cubeIDE 更改Repository folder

使用STM32CubeIDE时&#xff0c;会调用STM32CubeMX&#xff0c;但是这两个软件下载的更新包都放在C:/user/目录下面&#xff0c;而且文件很大&#xff0c;用不了多久就会把C盘填满&#xff0c;所以刚开始安装的时候就要把更新目录更换掉。具体更换方法如下&#xff1a; Window…

为您的视频编辑应用添加动力,美摄视频剪辑SDK

在当今的数字化时代&#xff0c;视频已经成为了最受欢迎的媒体形式之一。无论是社交媒体平台&#xff0c;还是在线教学站点&#xff0c;甚至是商业广告&#xff0c;都离不开视频的支持。而在这个领域&#xff0c;美摄视频剪辑SDK无疑是您的最佳选择。它不仅功能强大&#xff0c…

基于SSM的学生作业管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

sqlserver创建新用户并指定数据库

1、打开MSSM&#xff0c;安全性-->登录名-->右键-->新建登录名 2、按照下面6个步骤操作 3、用户映射页面&#xff0c;勾选对应数据库&#xff0c;数据库角色&#xff0c;增加db_owner的勾选 4、退出账号&#xff0c;使用新建的账号进行登录 5、对刚才授权的数据库&…

河北吉力宝智能科技鞋:引领健康产业全面升级和互联网转型

随着时代的变迁和人们对健康关注的不断升级&#xff0c;健康产业正迎来一次全面的升级浪潮。在这个浪潮中&#xff0c;河北吉力宝智能科技鞋生态战略正全面启动&#xff0c;为消费者带来高品质智能康养产品和全新的生活方式。 河北吉力宝智能科技鞋有限公司是一家致力于高品质智…

vue点击按钮收缩菜单

问题描述 VUE菜单有一个BUG&#xff0c;当我们点击其它按钮或者首页的时候&#xff0c;已经展示的一级菜单是不会自动收缩的。这个问题也导致很多开发者把一级菜单都换成了二级菜单。 错误展示 错误的效果请看下图。 解决方法 1、寻找菜单文件 因为我使用的是ruoyi的前端框…

D. A Simple Task

Problem - D - Codeforces 思路&#xff1a;这个题就是求环的数量&#xff0c;通过数据范围的大小&#xff0c;我们可以想到用状压dp来做&#xff0c;因为只有19个点&#xff0c;我们可以将环的路径进行状态压缩&#xff0c;用一个二进制数表示环&#xff0c;当某一位为1时表示…

同创永益CNBR平台——云原生时代下的系统稳定器

随着各行业数字化的快速发展&#xff0c;企业的业务运作、经营管理越来越依赖于云原生系统的可靠运行。信息系统服务的连续性, 业务数据的完整性、正确性、有效性会直接关系到企业的生产、经营与决策活动。一旦因自然灾害、设备故障或人为因素等引起信息数据丢失和云原生业务处…

【QT】使用toBase64方法将.txt文件的明文变为非明文(类似加密)

目录 0.环境 1.背景 2.详细代码 2.1 .h主要代码 2.2 .cpp主要代码&#xff0c;主要实现上述的四个方法 0.环境 windows 11 64位 Qt Creator 4.13.1 1.背景 项目需求&#xff1a;我们项目中有配置文件&#xff08;类似.txt&#xff0c;但不是这个格式&#xff0c;本文以…

SQLyog 连接 MySQL8.0+ 报错2058

问题如下&#xff1a; 解决方案&#xff1a; 1.首先用命令窗口进入user表 2.使用有mysql.user表权限的用户连接mysql并执行如下命令&#xff1a; ALTER USER sqlyoglocalhost IDENTIFIED WITH mysql_native_password BY root23456; 注&#xff1a;使用mysql_native_password…

Sui流动性质押黑客松入围项目公布

经过40多天积极的报名以及精心的选拔&#xff0c;Sui流动性质押黑客松现已完成对所有报名项目的筛选&#xff0c;最终入围名单也在众人的期待中新鲜出炉。两个赛道各六支队伍成功晋级黑客松的Demo Day&#xff0c;让我们来认识一下他们&#xff1a; 入围名单 流动性质押协议 …

git使用过程中出现乱码的解决办法

当我们使用git log或者git diff等git操作时&#xff0c;在终端很可能会遇到乱码&#xff0c;乱码效果如下&#xff1a; <E6><B7><BB><E5><8A><A0><E4><BA><86><E4><B8><80><E4><BA>&…

27、Flink 的SQL之SELECT (Pattern Recognition 模式检测)介绍及详细示例(7)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

【java、maven】报错: 类文件具有错误的版本 61.0, 应为 55.0 请删除该文件或确保该文件位于正确的类路径子目录中。

问题描述&#xff1a;导入依赖后&#xff0c;运行时发生 解决方法&#xff1a; 1.调高SDK版本 调高前&#xff1a; 调高后&#xff1a;

JavaSE11——面向对象_类和对象

一 面向对象 早期的程序设计经历了“面向问题”、“面向过程”的阶段&#xff0c;随着计算机技术的发展&#xff0c;以及所要解决问题的复杂性的提高&#xff0c;以往的程序设计方法已经不能适应这种发展的需求。于是&#xff0c;从 20 世纪 70 年代开始&#xff0c;相继出现了…

性能测试工具 — JMeter

1、jmeter介绍 Apache JMeter 应用程序是开源软件&#xff0c;是一个 100% 纯 Java 应用程序。用于测试Web应用程序、API和其他网络协议的性能。它具有以下特点&#xff1a; 1. 开源免费&#xff1a;JMeter是Apache软件基金会下的一个开源项目&#xff0c;它被称为Apache JMe…

2011年408计组真题步骤解析

12&#xff0e;下列选项中&#xff0c;描述浮点数操作速度指标的是D 。 A&#xff0e;MIPS B&#xff0e;CPI C&#xff0e;IPC D&#xff0e;MFLOPS 解析&#xff1a;浮点数&#xff1f;float&#xff1f;选有F的D 13&#xff0e;float 型数据通常用 IEEE 754 单精度浮点数格…

企业数据加密软件都有哪些?对公司能加密的软件有哪些

在当今的数字化时代&#xff0c;企业的信息安全已经成为了一个重要的议题。企业数据加密软件是一种能够保护企业敏感信息的工具&#xff0c;它通过将数据转化为无法直接理解的代码&#xff0c;从而防止未经授权的访问和泄露。本文将从企业数据加密软件的定义、种类以及一些具体…