两数之和(Hash表)[简单]

优质博文:IT-BLOG-CN

一、题目

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

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

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

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

示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

进阶: 你可以想出一个时间复杂度小于O(n2)的算法吗?

二、代码

哈希表思路:
【1】先获取数组中的第一个元素,通过target - num[i] = x,直接过去x的下标,存在直接返回当前索引和查询到的索引,但需要对[3,3]=6等特殊场景进行处理。
【2】们发现这个题目属于hash表下面的,所以使用hash表来实现。可以用key保存数值,用value在保存数值所在的下标map中的存储结构为{key:数据元素,value:数组元素对应的下表}

在遍历数组的时候,只需要向map去查询是否存在target - num[i] = x中的x,如果存在,就返回value也就是下标和i,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 先获取数组中的第一个元素,通过 target - num[i] = x, 直接过去x的下标,存在直接返回,需要对[3,3]相同的做特殊处理。
        // 我们发现这个题目属于 hash表下面的,所以使用hash表来实现。可以用key保存数值,用value在保存数值所在的下标
        // map中的存储结构为 {key:数据元素,value:数组元素对应的下表}
        int[] res = new int[2];
        Map<Integer,Integer> map = new HashMap();
        for (int i = 0; i < nums.length; i++) {
            int x = target - nums[i];
            if (map.containsKey(x)) {
                res[0] = map.get(x);
                res[1] = i;
                return res;
            }
            map.put(nums[i], i);
        }
        return res;
    }
}

时间复杂度: O(N),其中N是数组中的元素数量。对于每一个元素x,我们可以O(1)地寻找target - x
空间复杂度: O(N),其中N是数组中的元素数量。主要为哈希表的开销。

暴力枚举: 最容易想到的方法是枚举数组中的每一个数x,寻找数组中是否存在target - x

当我们使用遍历整个数组的方式寻找target - x时,需要注意到每一个位于x之前的元素都已经和x匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在x后面的元素中寻找target - x

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

时间复杂度: O(N^2),其中N是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
空间复杂度: O(1)

思考:
1、如果nums是有序的,是否还需要哈希表?换句话说,能否做到O(1)额外空间?
2、如果要求寻找三个数,它们的和等于target呢?

含有重复元素的两数之和(字节算法工程师面试题) :给定一个可能包含重复元素的有序数组,以及一个目标值target。计算数组中有多少对两个整数的组合满足和等于target
示例1: nums=[2,2,2,2], target= 4, ans=6
示例2: nums=[1,1,2,2,2,2,3,3], target=4, ans=10
示例3: nums=[1,1,1,1], target=4, ans=0

其实第一眼看上去倒也不难,就是一个变体的两数之和。所以刚开始的思路就是先统计每一个数出现的次数,然后再按照两数之和的方法去算,只不过算的时候要考虑两个数出现的次数相乘才是所有的组合。

但是面试官说还有更好的,让我往三数之和上想。但是我想偏了,我一直想的是在三数之和中如果当前数和前一个数相等,那么会直接跳过。这里的话应该是可以根据前一个数对答案的贡献度直接推出来当前数的贡献度的。比如[1,1,2,2,2,2,4,4]的测试用例,首先第一次计算出第一个1对结果的贡献度是2之后,指针右移,又遇到一个1,那么可以不用计算,直接加上上一次的答案,同理,第一次遇到2也是,但是由于2 = 4 - 2,所以,第二次遇到2的时候,不能直接加上上一次的答案,应该加上上一次的答案-1

import bisect
def solve(nums, target):
    ans = 0
    pre = 0
    for i, num in enumerate(nums):
        if num == target - num:
            r = bisect.bisect_right(nums, num)
            ans += (r - i) * (r - i - 1) // 2
            return ans

        if i > 0 and nums[i-1] == num:
            ans += pre
            continue
        l, r = bisect.bisect_left(nums, target - num), bisect.bisect_right(nums, target - num)
        if l < r:
            ans += r - l
            pre = r - l

    return ans

面试完又想了一下另一个思路,可以按照三数之和内层循环的思路,用两个指针分别指向首尾,
1、如果这两个数的和小于taregt,右移左指针,
2、如果大于target,左移右指针。
3、如果等于target,分情况讨论
4、如果两个数相等,可以直接计算,然后终止循环。因为数组有序,继续循环下去也没意义。
5、如果两个数不相等,分别计算出左右两个数出现的次数。然后再计算对答案的贡献度。

时间复杂度: 因为每个数最多只会遍历一次,所以是O(n)
空间复杂度: 只需要常数级的额外空间,所以是:O(1)

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        ans = 0
        left, right = 0, len(nums) - 1

        while left <= right:
            current_sum = nums[left] + nums[right]

            if current_sum == target:
                # 找到一组满足条件的组合
                if nums[left] == nums[right]:
                    ans += (right - left + 1) * (right - left) // 2
                    break

                # 统计左右两个数各自出现的次数
                left_num, right_num = 1, 1
                left += 1
                right -= 1
                while left <= right and nums[left] == nums[left - 1]:
                    left_num += 1
                    left += 1
                while left <= right and nums[right] == nums[right + 1]:
                    right_num += 1
                    right -= 1
                ans += left_num * right_num
            elif current_sum < target:
                left += 1
            else:
                right -= 1

        return ans

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch 7.8.0从入门到精通

安装Elasticsearch 7.8.0 官网&#xff1a;Elasticsearch 7.8.0 | Elastic 大家下载所需要的安装包即可。然后解压缩&#xff1a; Elasticsearch是通过java编写的&#xff0c;所以自带jdk。多好&#xff0c;下载Elasticsearch赠送jdk 0.0&#xff0c;不过一般我们用自己的jdk…

java发送邮件(注:本章以163邮箱为例)

目录 前言 一邮件服务器与传输协议 二.发送邮件思路 2.1注册163邮箱: 2.2、打开邮箱服务获取授权码 三.代码实现邮件发送 3.1第三方jar包 3.2创建邮件工具类 3.3编写测试类 前言 电子邮件的应用非常广泛&#xff0c;例如在某网站注册了一个账户&#xff0c;自动发送一…

C#/WPF 设置和启动Windows屏保程序

前言 我们平时电脑启动的屏保程序其本质也是应用程序&#xff0c;只是后缀名为.scr。所以我们只需要把应用程序后缀改为.scr&#xff0c;然后右键选择安装即可启动我们自己的屏保程序。 屏保注册表参数 设置电脑屏保参数&#xff0c;在个性化设置>锁屏界面>屏幕保护程序设…

解决若依Vue3前后端分离---路由切换时显示白屏

解决若依Vue3前后端分离---路由切换时显示白屏 1.问题重述 解决基于Vue3若依前后端分离项目中出现的路由正常切换但是就是不显示数据的问题&#xff0c;也就是不发起网络请求的问题。 找到如下位置中AppMain.vue文件 将除了css中的代码进行替换成如下的代码。 <template&g…

element-ui表单验证同时用change与blur一起验证

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 当审批时不通过审批意见要必须输入&#xff0c; 1&#xff1a;如果用change验证的话删除所有内容时报错是massage的提示&#xff0c;但是在失去焦点的时候报错就成了英文&#xff0c;如下图&#xf…

K8S--Ingress的作用

原文网址&#xff1a;K8S--Ingress的作用-CSDN博客 简介 本文介绍K8S的Ingress的作用。 ----------------------------------------------------------------------------------------------- 分享Java真实高频面试题&#xff0c;吊打面试官&#xff1a; Java后端真实面试题…

【MIdjourney】几种独特的艺术风格

1.合成器波(Synthwave) Synthwave是一种音乐风格&#xff0c;起源于20世纪80年代电子音乐和电影的复古元素。这种音乐风格通常包括合成器音乐、电子鼓声和强烈的电子声效&#xff0c;以模拟80年代电影和视频游戏的声音。Synthwave的特点包括浓厚的合成器声音、强烈的节奏和对复…

代码随想录 Leetcode541. 反转字符串 II

题目&#xff1a; 代码(首刷自解 2024年1月16日&#xff09;&#xff1a; class Solution { public:void reverse(string& s,int left,int right) {char temp;while (left < right) {temp s[left];s[left] s[right];s[right] temp;left;--right;}return;}string rev…

[NSSCTF Round#16 Basic]了解过PHP特性吗

了解过PHP特性吗 wp 第一页题目代码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); include("rce.php"); $checker_1 FALSE; $checker_2 FALSE; $checker_3 FALSE; $checker_4 FALSE; $num $_GET[num]; if (preg_match("/[0-9]/…

基于Yolov5+Deepsort+SlowFast算法实现视频目标识别、追踪与行为实时检测

前言 前段时间打算做一个目标行为检测的项目&#xff0c;翻阅了大量资料&#xff0c;也借鉴了不少项目&#xff0c;最终感觉Yolov5DeepsortSlowfast实现实时动作检测这个项目不错&#xff0c;因此进行了实现。 一、核心功能设计 总的来说&#xff0c;我们需要能够实现实时检测视…

pyhton实现录屏

python代码录屏录音 写的不是很好&#xff0c;不如那些obs的录屏软件&#xff0c;而且没有实现音频和视频的合并&#xff0c;请多见谅。 def audio_record() 实现音频录制 def video_record() 实现视频录制 def on_press(key) 按键监听 import time,threading from datetime i…

【project】estimate Aβ-PET pattern

1.17 1.16 1.14 写一个函数&#xff0c;输入是每个文件的地址&#xff0c;然后能做这一系列的操作 用AFM0095进行bbr的配准 方法一&#xff0c;间接配准&#xff0c;frmi先到str&#xff0c;再到mni&#xff08;str2fmri后再fmri2str&#xff09; fmri2str 只需要dof 6,6个自…

ROS第 2 课 ROS 系统安装和环境搭建

文章目录 方法一&#xff1a;一键安装&#xff08;推荐&#xff09;方法二&#xff1a;逐步安装&#xff08;常规安装方式&#xff09;1.版本选择2.检查 Ubuntu 的软件和更新源3.设置 ROS 的下载源3.1 设置国内下载源3.2 设置公匙3.3 更新软件包 4. 安装 ROS5. 设置环境变量6. …

leetcode 2418. 按身高排序

题目 给你一个字符串数组 names &#xff0c;和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i&#xff0c;names[i] 和 heights[i] 表示第 i 个人的名字和身高。 请按身高 降序 顺序返回对应的名字数组 names 。 解题方法&#xff…

Kafka-RecordAccumulator分析

前面介绍过&#xff0c;KafkaProducer可以有同步和异步两种方式发送消息&#xff0c;其实两者的底层实现相同&#xff0c;都是通过异步方式实现的。 主线程调用KafkaProducer.send方法发送消息的时候&#xff0c;先将消息放到RecordAccumulator中暂存&#xff0c;然后主线程就…

SpringBoot教程(十七) | SpringBoot中ApplicationEvent用法

SpringBoot教程(十七) | SpringBoot中ApplicationEvent用法 对不起大家&#xff0c;昨天文章里的告别说早了&#xff0c;这个系列还不能就这么结束。 我们前面的文章中讲解过RabbitMQ的用法&#xff0c;所谓MQ就是一种发布订阅模式的消息模型。在Spring中其实本身也为我们提供…

如何十分钟快速看懂一篇英文CV论文?

已经2024年了&#xff0c;该出现一个写论文解读的AI Agent了。 大家肯定也在经常刷论文吧。 但真正尝试过用GPT去刷论文、写论文解读的小伙伴&#xff0c;一定深有体验——费劲。其他agents也没有能搞定的&#xff0c;今天我发现了一个超级厉害的写论文解读的agent &#xff…

快速上手的 AI 工具-文心一言

简介 最近正打得火热的AIGC概念&#xff0c;相信大家肯定也都多少接触到了&#xff0c;那么AIGC概念股到底是什么呢&#xff1f;我个人最近也看了一些平台如&#xff1a;文心一言、通义千问、讯飞星火、豆包等等&#xff01;各位朋友也千万不要错过啦&#xff0c;真是各有各的特…

国考省考行测:语句排序,选择首句、选择尾句

国考省考行测&#xff1a;语句排序 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点 遇到…

MySQL之单表查询

素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varchar(10) NO…