面试经典150题——两数之和 II - 输入有序数组

面试经典150题 day27

      • 题目来源
      • 我的题解
        • [方法一 哈希表](#方法一 哈希表)
        • [方法二 双指针](#方法二 双指针)
        • [方法三 双指针(二分查找优化)](#方法三 双指针(二分查找优化))

题目来源

力扣每日一题;题序:167

我的题解

方法一 哈希表

使用哈希表存储每个元素及其位置。

然后遍历过程中判断 哈希表中是否存在 target-numbers[i],若存在,则直接将 当前位置+1 和 map.get(target-numbers[i]) 返回
时间复杂度 :O(n)
空间复杂度:O(n)。哈希表需要的空间

java 复制代码
public int[] twoSum(int[] numbers, int target) {
    Map<Integer,Integer> map=new HashMap<>();
    int n=numbers.length;
    for(int i=0;i<n;i++){
        map.put(numbers[i],i+1);
    }
    for(int i=0;i<n;i++){
        if(map.containsKey(target-numbers[i])){
            return new int[]{i+1,map.get(target-numbers[i])};
        }
    }
    return new int[]{-1,-1};
}
方法二 双指针

因为数组本身升序排序,所以可以使用双指针来解决。初始时,一个指针left指向开始位置,一个指针right指向结束位置。若numbers[left]+numbers[right]=target,则直接返回[left+1,right+1];若大于则right--,因为只有right往左移才会使得和更小;若小于则left++,因为只有left往右移才会使得和更大。
时间复杂度:O(n)

空间复杂度:O(1)

java 复制代码
public int[] twoSum(int[] numbers, int target) {
    int n=numbers.length;
    if(n==2){
        return new int[]{1,2};
    }
    int left=0,right=n-1;
    while(left<right){
        int t=numbers[left]+numbers[right];
        if(t==target){
            return new int[]{left+1,right+1};
        }else if(t>target){
            right--;
        }else{
            left++;
        }
    }
    return new int[]{-1,-1};
}
方法三 双指针(二分查找优化)

因为数组本身升序排序,所以可以使用双指针来解决。初始时,一个指针left指向开始位置,一个指针right指向结束位置。

若numbers[left]+numbers[right]=target,则直接返回[left+1,right+1];

若numbers[left]+numbers[mid]=target,则直接返回[left+1,mid+1];

若numbers[left]+numbers[mid]>target则right=mid-1,因为只有mid往左移才会使得和更小;

若numbers[left]+numbers[mid]<target则left=mid+1,因为只有left往右移才会使得和更大。
时间复杂度:最好情况O(logN),最坏O(N)

空间复杂度:O(1)

java 复制代码
public int[] twoSum(int[] numbers, int target) {
    int left=0,right=numbers.length-1;
    while(left<right){
        int sum=numbers[left]+numbers[right];
        int mid=left+((right-left)>>1);
        if(sum==target)
            return new int[]{left+1,right+1};
        else if(numbers[left]+numbers[mid]>target)
            right=mid-1;
        else if(numbers[mid]+numbers[right]<target)
            left=mid+1;
        else if(sum>target)
            right--;
        else
            left++;
    }
    return new int[]{-1,-1};
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

相关推荐
Warren986 分钟前
软件测试-Selenium学习笔记
java·javascript·笔记·学习·selenium·测试工具·安全
秋难降9 分钟前
LRU缓存算法(最近最少使用算法)——工业界缓存淘汰策略的 “默认选择”
数据结构·python·算法
tkevinjd16 分钟前
图论\dp 两题
leetcode·动态规划·图论
没有bug.的程序员32 分钟前
JVM 运行时数据区详解:内存模型与对象生命周期全景解析
java·jvm·运行时数据区·内存模型·对象生命周期
一语长情1 小时前
Netty流量整形:保障微服务通信稳定性的关键策略
java·后端·架构
Dignity_呱1 小时前
如何在不发版时,实现小程序的 AB 测试?
前端·面试·微信小程序
盖世英雄酱581361 小时前
第一个RAG项目遇到的问题
java·spring boot
最初的↘那颗心1 小时前
Flink Stream API - 源码开发需求描述
java·大数据·hadoop·flink·实时计算
CoovallyAIHub2 小时前
线性复杂度破局!Swin Transformer 移位窗口颠覆高分辨率视觉建模
深度学习·算法·计算机视觉