力扣算法题:167. 两数之和 II - 输入有序数组

题目链接:167.两数之和 II - 输入有序数组 - 力扣(LeetCode)

 这题相对两数之和来说最大的区别就是数组按非递减顺序排列,依旧可以和两数之和一样使用暴力枚举和哈希表来进行解答,在这里不做赘述。见两数之和解答:力扣算法题:1. 两数之和_storykeep的博客-CSDN博客y

由于这是有个有序数组,可以利用有序数组的性质选用其他方法解答。 

解法一:二分查找

先固定一个数,那么与之对应的另一个数的值就是确定的。由于这是一个有序数组,在有序数组中可以采用二分查找来确定要寻找的元素的位置。

二分查找使用两个标识来确定查找范围,每次取中间的值进行对比,确定目标值的范围,移动标识,缩小查找范围,不断二分,直到找到目标值,或确定查找范围内没有目标值停止。

JavaScript代码:

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    const len=numbers.length
    for(let i=0;i<len;i++){
        const temp=target-numbers[i]
        let left=i+1
        let right=len-1
        while(right>=left){
            let mid=Math.floor((right-left)/2+left)
            if(numbers[mid]===temp){
                return [i+1,mid+1]
            }else if(numbers[mid]>temp){
                right=mid-1
            }else{
                left=mid+1
            }
        }
    }
};

go语言代码:

func twoSum(numbers []int, target int) []int {
    var left,rigth,mid int
    for i,item := range numbers {
        temp:=target-item
        left=i+1
        rigth=len(numbers)-1
        for rigth>=left {
            mid=left+(rigth-left)/2
            if numbers[mid]==temp {
                return []int{i+1,mid+1}
            }else if numbers[mid]>temp {
                rigth=mid-1
            }else{
                left=mid+1
            }
        }
    }
    return nil
}

时间复杂度:O(nlogn)

解法二:双指针

双指针分为快慢指针和对撞指针(左右指针),在这里采用对撞指针求解。

初始时左右指针分别指向数组的第一个和最后一个值,然后计算两指针之和,与目标值对比,根据对比结果移动左右指针,直至找到目标结果,或指针相撞。

JavaScript代码:

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
   let left=0;
   let right=numbers.length-1
   while(right>left){
       if(numbers[left]+numbers[right]==target){
           return [left+1,right+1]
       }else if(numbers[left]+numbers[right]>target){
           right--
       }else{
           left++
       }
   }
};

go语言代码:

func twoSum(numbers []int, target int) []int {
    left:=0
    right:=len(numbers)-1
    for right>left {
        if numbers[left]+numbers[right]==target {
            return []int{left+1,right+1}
        }else if numbers[left]+numbers[right]>target {
            right--
        }else{
            left++
        }
    }
    return nil
}

时间复杂度:O(n)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值