面试经典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};
}

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

相关推荐
杰克尼8 分钟前
1. 两数之和 (leetcode)
数据结构·算法·leetcode
YuTaoShao1 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张31 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx4 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野5 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person5 小时前
Java SE--方法的使用
java·开发语言·算法
OneQ6666 小时前
C++讲解---创建日期类
开发语言·c++·算法
JoJo_Way6 小时前
LeetCode三数之和-js题解
javascript·算法·leetcode
小阳拱白菜6 小时前
java异常学习
java
.30-06Springfield6 小时前
人工智能概念之七:集成学习思想(Bagging、Boosting、Stacking)
人工智能·算法·机器学习·集成学习