力扣.167 两数之和 II two-sum-ii

news2024/11/13 15:44:32

数组系列

力扣数据结构之数组-00-概览

力扣.53 最大子数组和 maximum-subarray

力扣.128 最长连续序列 longest-consecutive-sequence

力扣.1 两数之和 N 种解法 two-sum

力扣.167 两数之和 II two-sum-ii

力扣.170 两数之和 III two-sum-iii

力扣.653 两数之和 IV two-sum-IV

力扣.015 三数之和 three-sum

力扣.016 最接近的三数之和 three-sum-closest

力扣.259 较小的三数之和 three-sum-smaller

题目

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列,请你从数组中找出满足相加之和等于目标数 target 的两个数。

如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

示例 1:

输入:numbers = [2,7,11,15], target = 9 输出:[1,2] 解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例 2:

输入:numbers = [2,3,4], target = 6 输出:[1,3] 解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

示例 3:

输入:numbers = [-1,0], target = -1 输出:[1,2] 解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

提示:

2 <= numbers.length <= 3 * 10^4

-1000 <= numbers[i] <= 1000

numbers 按 非递减顺序 排列

-1000 <= target <= 1000

仅存在一个有效答案

前言

这道题和 leetcode 的第一道题非常类似,看起来非常简单。

不过今天回头看,解法还是很多的。

大概可以有下面几种:

  1. 暴力解法

  2. 数组排序+二分

  3. HashSet/HashMap 优化

v1-暴力解法

思路

直接两次循环,找到符合结果的数据返回。

这种最容易想到,一般工作中也是我们用到最多的。

实现

注意:这里的下标从1开始。一看就不是一个面向程序员的题目。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];

        final 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) {
                    res[0] = i+1;
                    res[1] = j+1;
                }
            }
        }

        return res;
    }
}

效果

超出时间限制 21 / 24 个通过的测试用例

小结

暴力算法虽然容易想到,不过如果遇到特别长的场景用例,会直接超时。

我们如何改进一下呢?

排序是这个场景另一种很有用的方式。

v2-排序+二分

思路

我们希望排序,然后通过二分法来提升性能。

这里就发现,题目已经帮我排序好了。所以第一题的麻烦的部分全部省略了。

代码

class Solution {
   public int[] twoSum(int[] nums, int target) {
        final int n = nums.length;
        for(int i = 0; i < n; i++) {
            int other = target - nums[i];

            int j = binarySearch(nums, other, i+1);
            if(j >= 0) {
                return new int[]{i+1, j+1};
            }
        }

        return new int[]{-1, -1};
    }

    private int binarySearch(int[] nums,
                             int target,
                             int startIx) {
        int left = startIx;
        int right = nums.length-1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            int val = nums[mid];
            if(val == target) {
                return mid;
            }
            if(val > target) {
                right = mid-1;
            } else {
                left = mid+1;
            }
        }

        return -1;
    }
}

效果

4ms 16.87%

嗯?

这个竟然不是本题目的最佳解法吗?

v3-HashMap

思路

在我们写完上面的写法之后,有没有一种感觉?

既然是要找另一部分的值,那么直接 Hash,复杂度 O(1) 不是更快?

是的,你真是个小机灵鬼。

哈希在这种等于的场景是最快的,不过上面的二分适用性更广一些,比如查询大于或者小于的时候。

当然本体限制了,必须常量的空间,所以这种解法被限制了,不过也值得看一下。

我们先来看一下哈希的解法。

代码

注意:这里的顺序要求有序,所以返回的时候和 T1 要反过来。

class Solution {
   public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        for(int i = 0; i < n; i++) {
            int other = target - nums[i];
            if(hashMap.containsKey(other)) {
                int j = hashMap.get(other);
                return new int[]{j+1, i+1};
            }
            // 存储
            hashMap.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }
}

效果

7ms 6.01%

只能说性能很差,猜测是 map 构建导致的耗时,不然这个作为 O(n) 的解法一定性能更好才对。

说明这一题一定有更加适合的解法。

v4-双指针

思路

其实在 v2 二分法的排序思路上,我们可以受到一些启发。

排序+二分是我们非常老实的一次遍历,然后再二分查找,复杂度为 n*log(n)

那么有没有可能在有序的数组中不用这么麻烦?

那就要说到巧妙的双指针了。

双指针

我们定义两个指针

left=0
right=n-1
sum=num[left]+num[right-1]

因为数组有有序的,所以只有 3 种情况:

  1. sum == target 直接满足

  2. sum < target,left++

  3. sum > target, right--

代码

class Solution {
   public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        int left = 0;
        int right = n-1;

        while (left < right) {
            int sum = nums[left] + nums[right];
            if(sum == target) {
                return new int[]{left+1, right+1};
            }
            if(sum < target) {
                left++;
            }
            if(sum > target) {
                right--;
            }
        }

        return new int[]{-1, -1};
    }
}

效果

1ms

99.36%

小结

这类题目的思路基本都是类似的。

我们有常见的几种解法:

1) 暴力

2)借助 Hash

3) 排序+二分

4)双指针==》针对有序数组

我们后续将看一下 n 数之和的系列,感兴趣的小伙伴点点赞,关注不迷路。

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

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

相关文章

2024-11-01 - 统一身份认证 - OpenLdap - 中间件 - 流雨声

摘要 2024-11-01 周五 杭州 暴雨 调查问卷: https://www.wjx.cn/vm/exIBFDM.aspx# 2024年转瞬即逝&#xff0c;可是生活还在继续&#xff0c;这里有一项关于人工智能和项目管理对于效能关系的调研问卷&#xff0c;AI 对工作的作用和影响。问卷不采集个人信息&#xff0c;在此…

基于微信小程序的电商平台+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、普通用户功能模块&#xff1a;管理员&#xff08;用户管理、商品分类、商品管理、订单管理、系统管理等&#xff09;&#xff0c;普通用户&#xff08;个人中心、收藏、我的订单、查看商品等&#xff09;技术选型&#xff1a;SpringBo…

python读取word的自动编号以及添加自动编号

目录 1、读取编号 读取示例 如何判断段落是否有自动编号呢&#xff1f; 如何区分不同的类型编号呢&#xff1f; 2、添加自动编号 有的时候需要提取word中带自动编号的信息。对于word中的文字很多第三方的库都可以搞定&#xff0c;但是&#xff0c;提取格式&#xff0c;可能…

ImportError: cannot import name ‘packaging‘ from ‘pkg_resources‘ 的参考解决方法

文章目录 写在前面一、问题描述二、解决方法参考链接 写在前面 自己的测试环境&#xff1a; Ubuntu20.04 ROS-Noetic 一、问题描述 自己在通过 pip install 安装module时 &#xff08;使用的是 pip install mmcv&#xff09;遇到如下问题&#xff1a; ImportError: cannot …

【论文笔记】Wings: Learning Multimodal LLMs without Text-only Forgetting

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Wings: Learning Multimod…

Tomasulo算法介绍

Tomasulo算法详细解释 #mermaid-svg-x5G4yi740f0ju3OB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-x5G4yi740f0ju3OB .error-icon{fill:#552222;}#mermaid-svg-x5G4yi740f0ju3OB .error-text{fill:#552222;strok…

【C++练习】二进制到十进制的转换器

题目&#xff1a;二进制到十进制的转换器 描述 编写一个程序&#xff0c;将用户输入的8位二进制数转换成对应的十进制数并输出。如果用户输入的二进制数不是8位&#xff0c;则程序应提示用户输入无效&#xff0c;并终止运行。 要求 程序应首先提示用户输入一个8位二进制数。…

量子计算包kaiwu安装过程踩过的坑

目录 1 安装过程 2 官方代码测试 3 踩坑说明 首先&#xff0c;目前的kaiwu版本仅支持python3.8&#xff0c;所以必须要下载python3.8才能运行kaiwu 1 安装过程 step1: 在页面的SDK标签下&#xff0c;找到对应操作系统的kaiwu包。 step2: 下载python3.8到本地&#xff0c;可…

全文检索ElasticSearch到底是什么?

学习ElasticSearch之前&#xff0c;我们先来了解一下搜索 1 搜索是什么 ① 概念&#xff1a;用户输入想要的关键词&#xff0c;返回含有该关键词的所有信息。 ② 场景&#xff1a; ​ 1互联网搜索&#xff1a;谷歌、百度、各种新闻首页&#xff1b; ​ 2 站内搜索&#xff…

海鲜特写镜头视频素材去哪找 热门视频素材网站分享

作为美食自媒体创作者&#xff0c;海鲜特写镜头的视频素材无疑是提升内容吸引力和质量的重要利器。无论你想展示新鲜的海鲜原料、精美的烹饪过程&#xff0c;还是诱人的餐桌美食&#xff0c;精致的海鲜特写镜头都能极大地吸引观众的注意力。那么&#xff0c;问题来了&#xff1…

Unity 如何优雅的限定文本长度, 包含对特殊字符,汉字,数字的处理。实际的案例包括 用户昵称

常规限定文本长度 ( 通过 UntiyEngine.UI.Inputfiled 附带的长度限定 ) 痛点1 无法对中文&#xff0c;数字&#xff0c;英文进行识别&#xff0c;同样数量的汉字和同样数量的英文像素长度是不一样的&#xff0c;当我们限定固定长度后&#xff0c;在界面上的排版不够美观 痛点2…

SH3001姿态解算

姿态角&#xff0c;机体坐标系相对于参考坐标系的角度 旋转的非交换性 姿态角指的是载体坐标系与参考系之间的关系&#xff0c; 欧拉角是描述物体与某个轴(X,Y,Z)的关系&#xff0c;欧拉角属于姿态角的一种常见描述形式&#xff0c;另外两种描述形式就是四元数和和旋转矩阵 飞…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-19

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

电信网关配置管理系统 upload_channels.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

【C/C++】memcpy函数的使用

零.导言 当我们学习了strcpy和strncpy函数后&#xff0c;也许会疑惑整形数组要如何拷贝&#xff0c;而今天我将讲解的memcpy函数便可以拷贝整形数组。 一.memcpy函数的使用 memcpy函数是一种C语言内存函数&#xff0c;可以按字节拷贝任意类型的数组&#xff0c;比如整形数组。 …

【数据分享】1901-2023年我国省市县镇四级的逐年降水数据(免费获取/Shp/Excel格式)

之前我们分享过1901-2023年1km分辨率逐月降水栅格数据和Shp和Excel格式的省市县四级逐月降水数据&#xff0c;原始的逐月降水栅格数据来源于彭守璋学者在国家青藏高原科学数据中心平台上分享的数据&#xff01;基于逐月数据我们采用求年累计值的方法得到逐年降水栅格数据&#…

【Qt问题】解决 Cannot retrieve debugging output

【Qt问题】解决 Cannot retrieve debugging output Chapter1 【Qt问题】解决 Cannot retrieve debugging output方案1 关闭其他Qt工程实例&#xff08;等于没说&#xff09;方案2 在PRO文件中&#xff0c;加上CONFIG console Chapter1 【Qt问题】解决 Cannot retrieve debuggi…

软考中级 软件设计师 上午考试内容笔记(个人向)Part.3

软考上午考试内容 7. 网络安全 威胁名称描述恶意攻击&#xff08;ARP&#xff09;所截获的合法通信数据拷贝&#xff0c;出于非法的目的而被重新发送。拒绝服务&#xff08;DOS&#xff09;对信息或其它资源的合法访问被无条件地阻止。窃听用户可利用合法或非法的手段窃取系统中…

第四十章 Vue之使用ESLint修正代码规范

目录 一、引言 二、前端开发规范 三、ESLint规范工具 四、ESLint规范错误解决方式 4.1. 手动修正 4.2. 自动修正 JavaScript Standard Style 规范说明地址&#xff1a; https://standardjs.com/rules-zhcn.html 一、引言 在我们实际项目的开发过程中&#xff0c;统一标…