关于leetcode上‘两数之和’的学习

一开始看到这个题目时,最先想到的就是暴力破解法,暴力法很简单,直接检索nums里每一个x并再次查找nums中是否存在一个与target-x相等的目标值。

暴力破解:

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

执行通过,耗时360ms,内存消耗9.5MB
复杂度分析:
时间复杂度为O(n2),空间复杂度为O(1)

之后,我又想到了使用map进行查找以降低其时间复杂度。

使用map进行查找:
对nums中的每一个i,都以target-nums[i]为key,i为value来构建一个map,再遍历数组nums对每一个nums[j]在map中查找,若找到一个key值为nums[j]则输出i,j。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
         map<int,int> num_map;
         vector<int> twonum;
         for(int i=0;i<nums.size();i++)
        {   
            num_map[nums[i]]=i;
        } 
        for(int i=0;i<nums.size();i++)
        {
            if(num_map.count(target-nums[i])&&num_map[target-nums[i]]!=i)
            {
                twonum.push_back(i);
                twonum.push_back(num_map[target-nums[i]]);
                return twonum;
            }
        }
        return twonum;
    }
};

执行通过,耗时12ms,内存消耗10.9MB
复杂度分析:
时间复杂度为O(nlogn),空间复杂度为O(n)

暴力破解耗时太长,为了对程序运行的时间复杂度进行优化,参考大佬们的讲解,使用哈希表降低其时间复杂度。遍历数组nums,对其中每个值都有一次判断哈希容器map中是否存在target-nums[i]的键值,若存在则找到了符合要求的两个值,输出其对应键值;若不存在则将当前的(nums[i],i)存入map中,继续遍历直到找到为止;如果直到最终仍未找到则抛出异常。也可以使用两次迭代,在第一次迭代中将nums中每个元素的值和其索引都存入表中,之后再在第二次迭代中,检查每个元素所对应的target-nums[i]是否存在在表中,若存在则输出两个值的索引,反之则抛出异常。

两遍哈希表:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        unordered_map<int,int> num_map;
        for(int i=0;i<nums.size();i++)
        {   
            num_map[nums[i]]=i;//将nums中的每个元素的值和其索引都存入表中
        } 
        for(int i=0;i<nums.size();i++)
        {
            if(num_map.find(target-nums[i])!=num_map.end()&&num_map[target-nums[i]]!=i)//num_map中存在与target-nums[i]对应的键值,且不为i
            {
                return vector<int>{i,num_map[target-nums[i]]};//输出两个值
            }
        }
        return vector<int>();
    }
};

执行通过,耗时16ms,内存消耗10.4MB
复杂度分析:
时间复杂度为O(n),空间复杂度为O(n)

一遍哈希表:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        unordered_map<int,int> num_map;  
        for(int i=0;i<nums.size();i++)
        {
            if(num_map.find(target-nums[i])!=num_map.end())//num_map中存在对应的键值
            {
                return vector<int>{num_map[target-nums[i]],i};//输出时i为表的最大的元素,之前添加进去的元素均小于i
            }
            num_map[nums[i]]=i;//num_map中不存在对应的键值时,将(nums[i],i)存入表中
        }
        return vector<int>();
    }
};

执行通过,耗时8ms,内存消耗10.3MB
复杂度分析:
时间复杂度为O(n),空间复杂度O(n)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值