几数之和总结

1.两数之和

1. 两数之和

这个题应该算是几数之和里面最简单的问题了,就直接用unordered_map就行。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int>temp(2,-1);
        unordered_map<int, int> mymap;
        for(int i = 0; i < nums.size(); ++i){
            int numberToFind = target - nums[i];
            if(mymap.count(numberToFind) > 0){
                temp[0] = i;
                temp[1] = mymap[numberToFind];
                break;
            }
            mymap[nums[i]] = i;
        }
        return temp;
    }
};

2.三数之和

15. 三数之和

在这里插入图片描述

这个题用哈希表也能做,不过很麻烦,因为答案中不能包含重复的三元组,用哈希表之后去重就很恼火了,所以用三指针,不过要先排序,具体思路看之后的代码,像这种题吧时间复杂度就很难基本不可能降到O(n),所以不要浪费时间去想这种算法。

/**
* 解题思路:使用双指针法,或者说叫三指针法,这个题第一印象肯定是用哈希表,但是用哈希表太麻烦了
* 使用三指针,指针i指向现在的a元素,left和right负责移动遍历a对应的可能性,为了让时间控制在O(n)
* 我们需要先排序,然后再利用双指针,left和right分别开始指向i+1的位置和末尾位置,如果三数之和大了
* 则移动right,小了移动left,直至三数之和等于0或者leftright相遇。
*/

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size(), i = 0;
        vector<vector<int>> ans;
        while ( i + 2 < n) {
            int left = i + 1;
            int right = n - 1;
            if (i > 0 && nums[i] == nums[i - 1]) {
                i++;
                continue;
            }
            while (left < right) {
                if (nums[i] + nums[left] + nums[right] == 0) {
                    ans.push_back({nums[i], nums[left], nums[right]});
                    left++;
                    right--;
                    while (left < right && nums[left] == nums[left - 1]) left++;
                    while (left < right && nums[right] == nums[right + 1]) right--;
                }
                else if (nums[i] + nums[left] + nums[right] > 0)
                    right--;
                else
                    left++;
            }
            i++;
        }
        return ans;
    }
};

3.四数之和

18. 四数之和

在这里插入图片描述

四数之和和前面的三数之和也差不多,又多用了一个指针,去重也多了一个,反正边界条件自己要想清楚,当然时间复杂度也多了n,其实几数之和都可以这样做,其实双指针最大的作用就是降低一个n的时间复杂度(不过有时候可能要先排序)。

/**
* 解题思路:这道题用四指针法吧,先用first和last两个指针指向外围,然后用left和right两个指针指向里面循环查找
* 符合条件的元素。当然用指针法一般还是要先考虑排序,这里要排序,然后是考虑如何完整的遍历数组,这里采用的方法是把
* first和last指针指向分为三种情况,一种是对称位置,其余两种分别是first和last不对称的前进了一步,当然也要去重,
* 对四个元素都要考虑去重,具体看代码吧。
*/

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size();
        int first = 0, last = n - 1;
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        while (first + 3 < n) {
            if (first + 3 > last) {
                first++;
                last = n - 1;
            }
            int left = first + 1, right = last - 1;
            if (first > 0 && nums[first] == nums[first - 1]) {
                first++;
                continue;
            }
            if (last < n - 1 && nums[last] == nums[last + 1]) {
                last--;
                continue;
            }
            while (left < right) {
                if ((long)nums[first] + nums[last] + nums[left] + nums[right] > target) {
                    right--;
                }
                else if ((long)nums[first] + nums[last] + nums[left] + nums[right] < target) {
                    left++;
                }
                else {
                    ans.push_back({nums[first], nums[left], nums[right], nums[last]});
                    left++;
                    right--;
                    while (left < right && nums[left] == nums[left - 1]) left++;
                    while (left < right && nums[right] == nums[right + 1]) right--;
                }
            }
            last--;


        }
        return ans;
    }
};

4.四数相加Ⅱ

454. 四数相加 II

在这里插入图片描述

这个题倒又回到哈希表身上了,反正想到了就行。

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> Sum12;
        for (auto i : nums1)
            for (auto  j : nums2)
                Sum12[i + j]++;
        int ans = 0;
        for (auto i : nums3) {
            for (auto j : nums4) {
                if (Sum12.count(-i-j)); {
                    ans += Sum12[-i-j];
                }
            }
        }
        return ans;
    }
};

总结

几数相加这个问题要分情况,如果只是两数相加或只是求相加满足条件的元组数可以用哈希表,如果要返回的是一个存储相应值的元组,因为存在去重的原因,所以用双指针比较好。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值