两数之和[中等]

优质博文:IT-BLOG-CN

一、题目

给你一个下标从1开始的整数数组numbers,该数组已按非递减顺序排列,请你从数组中找出满足相加之和等于目标数target的两个数。如果设这两个数分别是numbers[index1]numbers[index2],则1 <= index1 < index2 <= numbers.length。以长度为2的整数数组[index1, index2]的形式返回这两个整数的下标index1index2。你可以假设每个输入 只对应唯一的答案 ,而且你不可以重复使用相同的元素。你所设计的解决方案必须只使用常量级的额外空间。

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

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

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

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers非递减顺序排列
-1000 <= target <= 1000
仅存在一个有效答案

二、代码

【1】使用二分查找法: 通过target - numbers[i]得到目标值,然后根据二分查找目标值,二分查找小于目标值,取右边进行递归,否则取左边的数据进行递归。

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        // 通过 target - numbers[i] 得到目标值,然后根据二分查找目标值,二分查找小于目标值,取右边进行递归,否则取左边的数据进行递归。
        int left = 0, right = 0, val = 0, mid = 0;
        for (int i = 0; i < numbers.length; i++) {
            left = i + 1;
            right = numbers.length - 1;
            // 需要查找的值
            val = target - numbers[i];
            // 中间数据
            while(left <= right) {
                mid = (right - left) / 2 + left;
                // 循环退出条件
                if (numbers[mid] == val) {
                    return new int[] {i + 1 , mid + 1};
                }
                // 如果中间值大于目标值,二分查找左边数组,否则查找右边数组
                if (numbers[mid] > val) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
            }
        }
        return new int[]{-1,-1};
    }
}

时间复杂度: O(nlog⁡n)其中n是数组的长度。需要遍历数组一次确定第一个数,时间复杂度是O(n),寻找第二个数使用二分查找,时间复杂度是O(log⁡n),因此总时间复杂度是O(nlog⁡n)
空间复杂度: O(1)

【2】双指针: 初始时两个指针分别指向第一个元素位置和最后一个元素的位置。每次计算两个指针指向的两个元素之和,并和目标值比较。如果两个元素之和等于目标值,则发现了唯一解。如果两个元素之和小于目标值,则将左侧指针右移一位。如果两个元素之和大于目标值,则将右侧指针左移一位。移动指针之后,重复上述操作,直到找到答案。

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        // 思想:将左右指针累加后,如果sum > target 右指针-1,sum < target 左指针 + 1
        int left = 0 , right = numbers.length - 1;
        while (left < right) {
            int sum = numbers[left] + numbers[right];
            if (sum == target) {
                return new int[]{left + 1 , right + 1};
            } else if (sum > target){
                --right;
            }else {
                ++left;
            }
        }
        return new int[]{-1,-1};
    }
}

时间复杂度: O(n)其中n是数组的长度。两个指针移动的总次数最多为n次。
空间复杂度: O(1)


http://www.niftyadmin.cn/n/5082273.html

相关文章

18__call__函数的调用

目录 把对象当成函数一样调用 吼吼~补充一个小的知识点哦~就是括号里的参数&#xff01; 具体的应用场景 原先一个实例化对象&#xff0c;并不会被调用&#xff0c;但是可以引入call class Person:pass pPerson() p() 这个时候引入__call__ 把对象当成函数一样调用 class…

LCR 158.库存管理 II

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 158. 库存管理 II - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 将数组中的不同的元素两两相消后&#xff0c;最后留下来的 元素一定是目标元素&#xff08;元素个数大于数组长度的一…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例评测用例(五)

六、华为云耀云服务器L实例评测用例&#xff1a; “兵马未动&#xff0c;粮草先行”&#xff0c;随着企业业务的快速发展&#xff0c;服务器在数字化建设体系至关重要&#xff0c;为了保证服务器的稳定性、可靠性&#xff0c;需要对服务器进行评测&#xff0c;以确保服务器能够…

【rust】cargo的概念和使用方法

啥是cargo 包管理器 cargo 提供了一系列的工具&#xff0c;从项目的建立、构建到测试、运行直至部署&#xff0c;为 Rust 项目的管理提供尽可能完整的手段&#xff0c;与 Rust 语言及其编译器 rustc 紧密结合。 创建项目 使用cargo创建一个项目&#xff1a; $ cargo new wo…

UE4和C++ 开发--HUD类

HUD 平视显示器(Head Up Display),简称HUD。在蓝图中是指在屏幕上面绘制的二维物体。 1. 创建HUD 打开蓝图编辑器&#xff0c;创建一个蓝图类&#xff0c;搜索HUD&#xff0c;选择并命名BP_HUD。 2. 开始绘制 打开事件列表&#xff0c;右键搜索 EventReceive Draw HUD。有两…

每日一题 1458两个子序列的最大点积

题目 题目 给你两个数组 nums1 和 nums2 。 请你返回 nums1 和 nums2 中两个长度相同的 非空 子序列的最大点积。 数组的非空子序列是通过删除原数组中某些元素&#xff08;可能一个也不删除&#xff09;后剩余数字组成的序列&#xff0c;但不能改变数字间相对顺序。比方说&…

代理IP、Socks5代理与网络工程:解析技术世界的无限可能

在当今数字化的世界中&#xff0c;网络工程师不仅需要保证网络的稳定性&#xff0c;还要应对多样的技术挑战。代理IP和Socks5代理技术已经成为网络工程师工具箱中不可或缺的利器&#xff0c;在跨界电商、爬虫、出海、网络安全、游戏等领域发挥关键作用。本文将深入探讨这两项技…

网络架构介绍

1 网络 7 层架构 7 层模型主要包括&#xff1a; 1. 物理层&#xff1a;主要定义物理设备标准&#xff0c;如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流&#xff08;就是由 1、0 转化为电流强弱来进行传输,到达目的地后在转化为1、0…