【题解】Leetcode #1. 两数之和

题意简述

给定整数数组nums(以下简写为\(a\))和目标值target(以下简写为\(t\)),求一组\((i,j)\),其中\(0\leq i,j<n\),使得\(a_i+a_j=t\)

思路

我们来考虑暴力枚举。根据题意明显可以两层循环分别枚举\(i\)\(j\),当找到符合题意的一组\((i,j)\)时,直接输出。时间复杂度\(O(n^2)\),用leetcode水爆了的数据显然能过。

【代码】

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

运行数据:71ms/12.67MB

如何考虑更优的时间复杂度?我们注意到如果我们能够用\(O(1)\)的时间来处理和查询在先前的遍历中找到的数据信息反向映射,这样可以将时间复杂度优化到\(O(n)\),但是额外代价就是消耗了复杂度为\(O(n)\)的空间。我们的正向映射是题目中已经给出的,反向映射就不得不提到我们今天算法的主角:哈希表

这样我们创建一个哈希表,对于每一个\(x\),我们首先查询哈希表中是否存在\(t - x\),然后将\(x\)插入到哈希表中,即可保证不会让\(x\)和自己匹配。

【代码】

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

运行数据:14ms/14.04MB

posted @ 2024-07-30 22:46  -HERITAGE-  阅读(12)  评论(0)    收藏  举报