灵神算法基础算法精讲[01] :
两数之和 三数之和【基础算法精讲 01】_哔哩哔哩_bilibili
167.两数之和 II - 输入有序数组
链接 :
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
思路 :

- 采用双指针的思想,因为给出的数组是有序的,n = len(numbers),定 l = 0,r = n-1;
 - 如果s = numbers[l] + numbers[r] > target , 那么s要变小,则r--;
 - 如果s = numbers[l] + numbers[r] < target , 那么s要变大,则l++;
 - 如果s = numbers[l] + numbers[r] = target , 那么就得到结果了,则返回[l+1,r+1]即可;
 
代码(python):
class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        l = 0
        r = len(numbers)-1
        while True:
            s = numbers[l] + numbers[r]
            if s==target:
                break
            if s>target:
                r -= 1
            else :
                l += 1
        return [l+1,r+1] 
代码(c++):
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int l=0,r=numbers.size()-1;
        while(true){
            int s = numbers[l]+numbers[r];
            if(s==target) break;
            if(s>target) r--;
            else l++;
        }
        return {l+1,r+1};
    }
}; 
三数之和
链接 :
三数之和
思路 :
假设满足条件的三个数的下标分别为i , j, k,且默认i<j<k;
先对数组进行排序,方便后面的操作
对i进行枚举,然后就是一个双指针的问题,令x=nums[i] , j=i+1 , k=n-1 ; 令 s = x + nums[j] + nums[k] , 剩下的就可以参考前一题中的思路:
1.如果s > 0 : k--;
2.如果s<0 : j++
3.如果s=0 : 添加到结果中;
去重 : 分别对i,j,k去重;
优化 : 如果相邻的三数之和>0,那么就可以直接break了,因为后面的只会加大
如果nums[i]+nums[n-1]+nums[n-2]<0,那么就continue,因为这是以i为起点的情况下s的最大值,如果小于0,那么直接continue,跳到下一个 i 上;
代码( python ):
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        # 排序
        # i<j<k
        ans = []
        n = len(nums)
        for i in range(n-2):
            x = nums[i]
            if i>0 and x==nums[i-1]:# 对x去重
                continue
            if x+nums[i+1]+nums[i+2]>0: # 优化
                break
            if x+nums[-2]+nums[-1]<0: # 优化
                continue
            j = i + 1
            k = n - 1
            while j < k:
                s = x + nums[j] + nums[k]
                if s>0:
                    k -= 1
                elif s < 0:
                    j += 1 
                else:
                    ans.append([x,nums[j],nums[k]])
                    j += 1
                    while j<k and nums[j]==nums[j-1]:# 对j去重
                        j+=1
                    k-=1
                    while j<k and nums[k]==nums[k+1]:# 对k去重
                        k-=1
        return ans 
代码( c++ ) :
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    int n = nums.size();
    vector<vector<int>> ans;
    sort(nums.begin(),nums.end());
    for(int i=0;i<n-2;i++)
    {
        int x = nums[i];
        if(x+nums[i+1]+nums[i+2] > 0) return ans;//如果三数和最小值大于0,那么直接返回
        if(x+nums[n-1]+nums[n-2]<0) continue;
        // 对a去重
        if(i>0 && nums[i] == nums[i-1]) continue;
        int left = i+1;
        int right = n-1;
        while(right>left)
        {
            int x = nums[i] + nums[left] + nums[right];
            if(x > 0) right--;
            else if(x < 0) left++;
            else 
            {
               ans.push_back(vector<int>{nums[i],nums[left],nums[right]});
               while(left<right && nums[right] == nums[right-1]) right--;
               while(left < right && nums[left] == nums[left+1]) left ++; 
               left++;
               right--;
            }
        }
    }
    return ans;
    }
}; 
                


















