leetcode 两数之和、三数之和

本文深入解析LeetCode上的经典算法题目“两数之和”与“三数之和”,探讨了使用HashMap和双指针法解决这两类问题的高效算法策略,通过实例代码展示了如何在时间复杂度和空间复杂度上取得最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两数之和

https://leetcode-cn.com/problems/two-sum/

思路:找一个数,再找一个满足和是target的数(第二次查找的范围和操作决定时间)

注意点

1:找的是数下标而不是本身,排序会加大难度(如使用二分查找,或双指针)

2:存在相同的数,使用hashmap才能存放key相同的元素

3:可利用只有唯一一个正确答案的条件,实现插入时查找

//map法 时间复杂度 nlogn
class Solution {
public:
   vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> ans;
        map<int,int> m;
        for( int i=0; i<nums.size(); i++ ){
            if( m.find( target - nums[i] )!=m.end() ){
                ans.push_back(i);
                ans.push_back( m.find( target-nums[i])->second );
                return ans;
            }
            m[nums[i]] = i;
        }
    return ans;
    }
};

 

 

三数之和

https://leetcode-cn.com/problems/3sum/

思路:先找一个数,再在使用"两数之和"的方法把所有符合的数找到,循环

注意点

1:答案有多个,但每个答案唯一(

       {1,0,-1},{-1,0,1}是一个答案 ,这意味着需要避免重复答案

       第一个数会对应的多个满足的第二第三个数如{0,5,-5}{0,6,-6})

2:输出答案为数字本身,可对原数据集合进行排序

3:存在相同数据,并不是三个数各不相同如{0,0,0}

//双指针法(双指针法用于两数之和,当要求数据集合可排序)
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
       sort( nums.begin(), nums.end() ); //排序使数组左小右大
       vector<vector<int>> ans;

        int l , r ;
        for( int i=0; i<nums.size(); i++ ){
            //依次寻找第一个数nums[i]
            if( i!=0 && nums[i]==nums[i-1] ){ //这步使得每次找的第一个数都不同
                continue;
            }

            l = i+1 ;
            r = nums.size()-1;

            //遍历余下数组,找到所有满足能与第一个和为0的数
            while( l<r ){
                
                if( nums[l] + nums[r] + nums[i] > 0 ){   //大了
                    r--;
                }else if( nums[l] + nums[r] + nums[i] < 0){  //小了
                    l++;
                }else{ 
                    //满足
                    ans.push_back({ nums[i],nums[l],nums[r] });
                    l++;r--;
                } 

                //这里用来跳过相同的数据
                while( l<r && l!=i+1 && nums[l]==nums[l-1] ) l++;
                while( l<r && r!=nums.size()-1 && nums[r]==nums[r+1] ) r--;
            }

        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值