leetcode 刷题笔记 08-28 (双指针 plus plus)

167. Two Sum II - Input array is sorted

Given an array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number.

Return the indices of the two numbers (1-indexed) as an integer array answer of size 2, where 1 <= answer[0] < answer[1] <= numbers.length.(这句英文不会翻译...)

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Example 1:

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.

Example 2:

Input: numbers = [2,3,4], target = 6
Output: [1,3]

Example 3:

Input: numbers = [-1,0], target = -1
Output: [1,2]

Constraints:

  • 2 <= numbers.length <= 3 * 104
  • -1000 <= numbers[i] <= 1000
  • numbers is sorted in non-decreasing order.
  • -1000 <= target <= 1000
  • The tests are generated such that there is exactly one solution.

日常尝试使用暴力方法然后失败:

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int len = numbers.size();
        vector<int> ans;
        int start,end;
        for(int i = 0;i < len; i++)
        {
            if(numbers[i]>0 && target < numbers[i])
            continue;
            for(int j = i + 1;j < len;j++)
            {
                if((numbers[i] + numbers[j] > target) ||
                (numbers[i] + numbers[len - 1] < target) )
                break;
                else if(numbers[i] + numbers[j] == target)
                {
                    ans.push_back(i+1);
                    ans.push_back(j+1);
                    return ans;
                }
                
            }
        }
        return ans;
    }
};

时间复杂度为o(n*n),使用的两个if判别语句是我最后的努力了,证明在本题的数据规模使用接近n方的算法是绝对会超时的,希望以后自己不要做类似的尝试了。

然后考虑到原来数组非递减的性质,在第二重循环中使用二分查找,时间复杂度为o(n*logn),代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int len = numbers.size();
        vector<int> ans;
        int start,end;
        for(int i = 0;i < len; i++)
        {
           start = i + 1;
           end = len - 1;
           while(start <= end)
           {
               int temp = start + (end - start) / 2;
               if(numbers[i] + numbers[temp] == target)
               {
                   ans.push_back(i + 1);
                   ans.push_back(temp + 1);
                   return ans;
               }
               else if(numbers[i] + numbers[temp] < target)
               {
                   start = temp + 1;
               }
               else 
               end = temp - 1;
           } 
        }
        return ans;
    }
};

最最最牛逼的方法!(敲黑板!!!)当然是双指针了(鄙人今天第一次看到双指针的妙处,情绪失控大家见谅,双指针真是太牛逼了!此处省略一万字赞美....),时间复杂度为o(n)

代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int len = numbers.size();
        vector<int> ans;
        int start = 0;
        int end = len - 1;
        while(start < end)
        {
            if(numbers[start] + numbers[end] == target)
            {
                ans.push_back(start + 1);
                ans.push_back(end + 1);
                return ans;
            }
            else if(numbers[start] + numbers[end] < target)
            start++;
            else
            end--;
        }
        return ans;
    }
};

nettee大佬在本题的题解真的写的绝绝子,有兴趣的同学一定要看,此处附上链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/yi-zhang-tu-gao-su-ni-on-de-shuang-zhi-zhen-jie-fa/

下面我们来讲解一下为什么我们使用这种迭代方法不会遗漏我们的可行解:

此处本应当有我个人的解答,但由于今日天色已晚,加上此算法需要讲解会用到公式比较多,使用我一贯的偷懒技巧,此处省略,待日后得空补充

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值