LeetCode_Two Sum

题目描述:给出一个目标数值target,求出数组中是否有两个元素的和等于target,如果有将下标输出出来

我的第一想法是暴力运算:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        vector<int> vec;
        for(int i=0;i!=nums.size();i++)
        {
            for(int j=i+1;j!=nums.size();j++)
            {
                int sum=nums[i]+nums[j];
                if(sum==target)
                {
                    vec.push_back(i);
                    vec.push_back(j);
                }
            }
        }
        return vec;
    }
};

暴力计算的时间复杂度是n的平方量级,由于不用申请新的空间,空间复杂度为O(1)
运行情况:

  • runtime:360ms
  • memory usage:9.1MB

第二种想法调用了库函数,时间复杂度降到了nlogn量级

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        int i,j=0;
        for(i=0;i!=nums.size();i++)
        {
            int sup=target-nums[i];
            auto it=find(nums.begin()+i+1,nums.end(),sup);
            if(it!=nums.end())
            {
                j=it-nums.begin();
                break;
            }
        }
        return vector<int>{i,j};
    }
};

运行情况:

  • runtime:108ms
  • memory usage:9.1MB

第二种情况似乎更好,然后翻看答案,官方解法:One Pass Hash Table

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        unordered_map<int, int> indices;
        for (int i = 0; i < nums.size(); i++) 
        {
            if (indices.find(target - nums[i]) != indices.end()) 
            {
                return {indices[target - nums[i]], i};
            }
            indices[nums[i]] = i;
        }
        return {};
    }
};

用到了关联容器map,map的first将nums[i]作为key,second保存相应的i,One Pass方法通过先查找的方式,如果map中没有另一个值,那么将当前nums[i]放入map中进行下一次查找,这种方式将用还没有放入map的nums[i]作为减数,在已放入map的值中查找差值,可以只遍历一次map,因为map的查找复杂度为O(1),所以该算法的时间复杂度为O(n);
PS:还有一种Two Pass算法,先把数组中的值都放入map再查找,也是O(n)。
查找复杂度为O(1)参考https://mp.csdn.net/mdeditor/89343430

运行情况:

  • run time:16ms
  • memory usage:10.1MB

总结:

  • 利用其它算法(库函数的查找排序)提高效率
  • 利用数据结构(map),牺牲空间换取时间,来提高效率
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值