Two Sum leetcode

本文探讨了一个常见的编程问题:在一个整数数组中,如何找出两个数的组合,使得它们的和等于给定的目标值。文章详细介绍了如何通过使用哈希表来优化搜索过程,以及如何处理包含重复元素的情况。同时,分享了解决方案的复杂结构设计和从高支持答案中获得的启发。

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

 

Subscribe to see which companies asked this question

这个题目一开始我没有考虑到有重复元素的情况,这样直接用一个hashmap保存所有元素和其下标,然后遍历数组,查看hashmap中是否有键等于差值就可以了。

提交代码后发现还有重复元素,这着实非常伤脑筋。因为hashmap无法保存重复的键,而且我认为务必要保存所有元素的下标。

于是我开始拿hashmap开刀,试图弄出一个可以保存重复元素的map,我马上就想到了map<int, vector<int>>这个复杂的结构,vector<int>保存的是相同键值对应的所有下标,谁知从此我踏上了一条不归路。。。

构造好了这个复杂的结构后,依次遍历就可以了,代码是下边那一长串,算法和代码可以算作冗余繁杂的负面典型了,记录于此为戒。

 

看了leetcode上支持最高的答案后,拍案叫绝后又有些许疑惑

在这里慢慢分析一下

还是使用hashmap,不同于往常先构造map,然后查找的思路。

这里是一边查找,一边添加,而且顺序很重要,一定是先查找,后添加。

题目说明只存在一对解,所以我们没有必要保存所有重复元素,找到后直接返回就可以了

vector<int> twoSum(vector<int> &nums, int target)
{
    unordered_map<int, int> hash;
    vector<int> ret;
    for (int i = 0; i < nums.size(); ++i)
    {
        int remain = target - nums[i];
        if (hash.find(remain) != hash.end())
        {            
            ret.push_back(hash[remain] + 1);
            ret.push_back(i + 1);
            return ret;
        }
        hash[nums[i]] = i;
    }
    return ret;
}

 

 

vector<int> twoSum(vector<int>& nums, int target) {
    int i = 0;
    vector<int> twoSums;
    map<int, vector<int>> sumsMap;
    for (auto one : nums)
    {
        vector<int> group;
        auto iter = sumsMap.find(one);
        if (iter != sumsMap.end())
        {
            group = iter->second;
            sumsMap.erase(iter);
        }
        group.push_back(i);
        sumsMap.insert(make_pair(one, group));
        i++;
    }
    for (i = 0; i < nums.size() - 1; i++)
    {
        int valueI = nums.at(i);
        int remain = target - valueI;
        if (sumsMap.find(remain) != sumsMap.end())
        {
            vector<int> vecj = sumsMap.at(remain);
            int len = vecj.size();
            for (int j = 0; j < len; j++)
            {
                int index = vecj[j];
                if (i != index)
                {
                    twoSums.push_back(i + 1);
                    twoSums.push_back(index + 1);
                    return twoSums;
                }
            }
        }
    }
    return twoSums;
}

 

转载于:https://www.cnblogs.com/sdlwlxf/p/5100408.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值