面试热题(两数之和)

news2025/3/13 17:23:36

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

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

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

       相信两数之和是很多同学梦开始的地方,曾经的自己,看到这道题无从下手的样子是否还记得?现在你又会用多少种方式去解决它呢? 今天我们用3种方法来解决这道极具思考的问题

  • for循环(枚举)

 两层for循环,枚举每一个数,看是否符合情况(这种方法时最朴素的,但也是复杂度最高的)

 public int[] twoSum(int[] nums, int target) {
        //维护长度为2的数组,将最后的结果添加到数组中
        int [] arr=new int[2];
        //枚举第一个数
        for(int i=0;i<nums.length;i++){
            //枚举第二个数
            for(int j=i+1;j<nums.length;j++){
                 //如果相等就说明找到结果
                if(nums[i]+nums[j]==target){
                    arr[0]=i;
                    arr[1]=j;
                }
            }
        }
        return arr;
    }
  • 哈希表

怎么利用哈希表解决这道题呢?

         我们可以利用Map进行对原数组中的元素进行value和索引的联系,key绑定数组中的元素,value绑定对应的索引,这样我们枚举数组中的每个元素,然后载判断target-num[i]的这个元素是否在Map中存在,存在的话就说明有满足条件的值

 Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],i);
        }
 for(int i=0;i<nums.length;i++){
             //判断Map中是否存在target-nums[i]
            if(map.containsKey(target-nums[i])){
                res[0]=i;
                res[1]=map.get(target-nums[i]);
                return res;
                  }
        }

 你们觉得这样写正确么?

我一运行:

       结果居然出错了?难道是我们的思路出现的问题?NONONO,只是我们少考虑了有某种情况,这种用Map的思路类似于循环遍历,但是Map的查找是O(1)的,所以当我们枚举的这个值为target/2的时候,就会出现上面这种情况,那么我们知道枚举的数字不是当前set包含中的这个数字呢?刚刚不是说了,Map中的value是key值的索引,只要我们进行判断当前的枚举的i和map中这个key的value值是否一样就可有判断出是否是同一个数,只需要加上这么一个小小的判别条件

 if(i!=map.get(target-nums[i])){
          ......
}

 然后不出意外,果然就AC了

 源代码:

public int[] twoSum(int[] nums, int target) {
        int[] res=new int[2];
        if(nums==null||nums.length==0){
            return res;
        }
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],i);
        }
        for(int i=0;i<nums.length;i++){
              if(map.containsKey(target-nums[i])){
                if(i!=map.get(target-nums[i])){
                res[0]=i;
                res[1]=map.get(target-nums[i]);
                return res;
                  }
            }
 }
        return res;
    } 
  • 排序+双指针

       排序双指针,这种容易想,但是不太好实现,因为想用双指针从两端往中间收缩的情况,前提是数组必须是有序的,但是题目中给我们的是无序数组,如果是要我们返回值的话,直接排序,利用双指针就可以找到结果,但是这个题偏偏让你返回的结果值的索引,这就有点头大了,如果直接排序,对应值的索引的就会发生改变,如果不排序,就无法使用双指针(其实无序也可以用,只是解决的方法不一样)

       有人肯定又会说?啊!!!这个数组我们可以用Hash表的方式,去将它们的值和索引一一对应起来不就可以了么?能想到这里说明你对这个问题算是熟悉了,但还是没有完全吃透,怎么说,如果,数组中有两个值一样的元素,后面添加的元素的key值肯定会把前面添加的key值进行覆盖,那么我们第一次添加的元素那不成立无效元素了么?所以利用这种方式显然是行不同的,那这道题难道就没有一个合适的解决办法了么?

       我们现在要的是key和index进行关联,且相同的元素还不能进行覆盖,维护两个变量,而且还有对应关系,这是不是和我们坐标轴的(x,y)差不多,所以我们可以利用二维数组[x][y]去解决这个问题,[x][0]代表的是值,[x][1]代表的是值的索引

 首先我们先对二维数组进行排序,自定义的排序方式会出现

 所以我们应该自定义比较器

 Arrays.sort(resNum,(o1,o2)->{
          //数组中第一个相等? 按照第二个大小进行排序(升序):按照第二个大小进行排序(升序)
          return o1[0]==o2[0]?o1[1]-o2[1]:o1[0]-o2[0];
      });

 然后就是双指针的固定模板了(必会)

//左指针
int left=0;
//右指针
int right=n-1;
while(left<right){
int sum=nums[left]+nums[right];
//如果相等找到结果
if(sum==target){
   reutrn ...;
//如果大于,说明,右边的太大了,要往左进行收缩
}else if(sum>target){
   right--;
//如果小于,说明左边太小了,要往右进行收缩
}else{
   left++;
}
}

源码如下:

 public int[] twoSum(int[] nums, int target) {
        int[] res=new int[2];
       //对入参进行判断
       if(nums==null||nums.length==0){
           return res;
       }
       //声明一个二维数组
       int[][] resNum=new int[nums.length][2];
       //将原数组中的值和index进行映射(关联)
       for(int i=0;i<nums.length;i++){
           resNum[i][0]=nums[i];
           resNum[i][1]=i;
       }
       //自定义比较器
       Arrays.sort(resNum,(o1,o2)->{
          return o1[0]==o2[0]?o1[1]-o2[1]:o1[0]-o2[0];
       });
       //反向双指针的模板变写
       int left=0;
       int right=nums.length-1;
       while(left<right){
           int sum=resNum[left][0]+resNum[right][0];
           //碰到满足题意的值直接进行返回
           if(sum==target){
               res[0]=resNum[left][1];
               res[1]=resNum[right][1];
               return res;
           }else if(sum>target){
               right--;
           }else{
               left++;
           }

       }
       return res;
    }

       毫无疑问过了,希望今天的博客能给大家带来一点帮助,更主要的是拓阔思路,即使是最简单的题,做完一遍过了以后,我们应该还要想想有没有其他的方式去解决,这样才能不断的进步,不断的向前,我想到了的一句话“我不怕会一万种腿法的人,我怕的是把一种腿法练一万次的人”,共勉之!!!   

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

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

相关文章

并发——JDK 提供的并发容器总结

文章目录 一 JDK 提供的并发容器总结二 ConcurrentHashMap三 CopyOnWriteArrayList3.1 CopyOnWriteArrayList 简介3.2 CopyOnWriteArrayList 是如何做到的&#xff1f;3.3 CopyOnWriteArrayList 读取和写入源码简单分析3.3.1 CopyOnWriteArrayList 读取操作的实现3.3.2 CopyOnW…

K8S MetalLB LoadBalancer

1. 简介 kubernetes集群没有L4负载均衡&#xff0c;对外暴漏服务时&#xff0c;只能使用nodePort的方式&#xff0c;比较麻烦&#xff0c;必须要记住不同的端口号。 LoadBalancer&#xff1a;使用云提供商的负载均衡器向外部暴露服务&#xff0c;外部负载均衡器可以将流量路由…

【数学】CF1514 C

Problem - 1514C - Codeforces 题意&#xff1a; 思路&#xff1a; Code&#xff1a; #include <bits/stdc.h>using i64 long long;constexpr int N 2e5 10; constexpr int M 2e5 10; constexpr int mod 998244353;void solve() {int n;std::cin >> n;std:…

图像处理技巧形态学滤波之腐蚀操作

1. 引言 欢迎回来&#xff0c;我的图像处理爱好者们&#xff01;今天&#xff0c;让我们深入研究图像处理领域中的形态学计算。这些非线性的图像处理技术允许我们操纵图像中对象的形状和结构。在本系列中&#xff0c;我们将依次介绍四种基本的形态学操作&#xff1a;腐蚀、膨胀…

走出象牙塔:李郓梁的区块链实践之路丨对话MVP

如何从科研走向实践&#xff1f;李郓梁在社区找到了答案。 作为西安工业大学的硕士研究生&#xff0c;李郓梁从学校的实验室接触区块链技术。通过研读大量论文&#xff0c;李郓梁为区块链多中心化、不可篡改等前沿理论深深着迷&#xff0c;并选择将区块链作为主要研究方向&…

网络原理(JavaEE初阶系列11)

目录 前言&#xff1a; 1.网络原理的理解 2.应用层 2.1自定义协议的约定 2.1.1确定要传输的信息 2.1.2确定数据的格式 3.传输层 3.1UDP 3.1.1UDP报文格式 3.2TCP 3.2.1确认应答 3.2.2超时重传 3.2.3连接管理 3.2.3.1三次握手 3.2.3.2四次挥手 3.2.4滑动窗口 3.…

Invalid bound statement (not found)

在使用Mybatisplus时报错Invalid bound statement (not found)&#xff0c;在此记录一下 先附上解决办法 step 1、启动类加上MapperScan注解 package com.study.test;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; …

基于QT ,halcon实现可视化程序编程框架

基于qt ,halcon 实现可视化程序编程框架 完整源码 :订阅后 请加微信 SimpleAuto6,将在第一时间发送,未订阅,时间宝贵,勿扰 部分源码: #include "LogInDialog.h"LogInDialog::LogInDialog(int w, int h,QWidget *parent): QDialog(parent),m_Password(…

SpringBoot复习:(31)Controller中返回的对象是如何转换成json字符串给调用者的?

首先&#xff0c;SpringBoot自动装配了HttpMessageConvertersAutoConfiguration这个自动配置类 而这个自动配置类又通过Import注解导入了JacksonHttpMessageConvertersConfiguration类&#xff0c; 在这个类中配置了一个类型为MappingJackson2HttpMessageConverter类型的bean…

教你一招:非计算机科班如何丝滑转码?

近年来&#xff0c;很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码&#xff1f; 目录 一、确定方向 二、确定学习计划&#xff08;自学&#xff09; 三、学习 看到组里好多非科班姐妹决定转码之后&#xff0c;因为相关背景知识不足难以确定学习计划&am…

田间农业数字管理系统-高标准农田建设

政策背景 2019年11月&#xff0c;国务院办公厅印发的《国务院办公厅关于切实加强高标准农田建设提升粮食安全保障能力的意见》明确提出&#xff0c;到2022年&#xff0c;全国要建成10亿亩高标准农田。 2021年9月16日&#xff0c;由农业农村部印发的《全国高标准农田建设规划&a…

python时间戳转换字符串时间

Python时间戳和日期格式之间的相互转化 将10位或13位时间戳转为日期格式&#xff08;年-月-日 时-分-秒&#xff09; python毫秒时间戳转为字符串时间 java默认精度是毫秒级别的&#xff0c;生成的时间戳是13位&#xff0c; 而python默认是10位的&#xff0c;精度是秒。如p…

2023牛客暑期多校训练营8-I Make It Square

2023牛客暑期多校训练营8-I Make It Square https://ac.nowcoder.com/acm/contest/57362/I 文章目录 2023牛客暑期多校训练营8-I Make It Square题意解题思路代码实现 题意 解题思路 这里有两种情况&#xff0c;即 ∣ s ∣ > ∣ t ∣ |s|>|t| ∣s∣>∣t∣和 ∣ s ∣…

如何让你的视频在 TikTok上变得火爆?

TikTok凭借巨大的用户量和商业价值&#xff0c;它从来不缺优质内容。如何在众多内容中脱颖而出获得关注&#xff0c;这并不简单。和泛流量账号不同&#xff0c;商业账号的目的更加明确&#xff0c;也就是说&#xff0c;商业账号并不一定要以高流量最为唯一的追求目标&#xff0…

动态规划之斐波拉契数列模型

斐波拉契数列模型 1. 第 N 个泰波那契数2. 三步问题&#xff08;easy&#xff09;3. 使⽤最⼩花费爬楼梯&#xff08;easy&#xff09;4. 解码⽅法&#xff08;medium&#xff09; 动态规划的介绍&#xff1a; 动态规划是一种在数学、管理科学、计算机科学、经济学和生物信息学…

最短路相关思想总结

dijkstra—所有边均为正权边 1.稠密图 算法思想 将所有的点读入邻接表 外层n次循环 每次找到最近的点&#xff0c;记录这个点的访问状态&#xff0c;使用这个点对其他的点进行更新&#xff0c;最后返回最短路 为什么要记录每个点的状态&#xff1f;我不能重复搜这个点吗&…

面对AI冲击,技术人才该如何考核?

一天下午&#xff0c;在与知名企业的技术交流会议室里&#xff0c;一位兄弟企业的CTO 小力苦笑着&#xff0c;分享了一个技术招聘的故事&#xff1a; “我们有个高级工程师&#xff0c;为了搞定MySQL三个表Join的问题&#xff0c;搞了一整天都研究不出来。结果他尝试将表结构扔…

【C++进阶】继承、多态的详解(继承篇)

【C进阶】继承、多态的详解&#xff08;继承篇&#xff09; 目录 【C进阶】继承、多态的详解&#xff08;继承篇&#xff09;继承的概念及定义继承的概念继承的定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类和派生类对象赋值转换继承中的作用域派生类的默认…

你不能访问此共享文件夹因为你组织的安全策略

我在windows 10中尝试访问没有密码的共享文件只报错如下&#xff1a; 解决办法 运气中执行 gpedit.msc来启动本地组策略编辑器。 这样设置完成后&#xff0c;就可以在运行中输入 \\192.168.199.1\可以访问共享的文件了。 参考 https://zhuanlan.zhihu.com/p/164721714…

HashMap 二十一问

1&#xff1a;HashMap 的数据结构&#xff1f; A&#xff1a;哈希表结构&#xff08;链表散列&#xff1a;数组链表&#xff09;实现&#xff0c;结合数组和链表的优点。当链表长度超过 8 时&#xff0c;链表转换为红黑树。transient Node<K,V>[] table; 2&#xff1a;…