leetcode-two-sum

问题

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

出处:https://leetcode.com/problems/two-sum/description/

原文大意

给定一个整数数组和一个目标数target,返回数组中两个相加等于target的元素的下标;假设给定的数据中恰巧只有一个解,并且同一个元素不可使用两次.

例如:
给定一个数组nums = [2, 7, 11, 15],target = 9,
因为 2+7 = 9,而2, 7在数组中的下标分别为0,1,所以返回[0,1].

解题思路

1. 暴力求解

看到这道题,就想到用两个for循环遍历两遍,判断两个值相加是否等于target,C++代码如下:

vector<int> twoSum(vector<int>& nums, int target) {
      std::vector<int> r;
        int len = nums.size();
        //遍历一次数组
        for (int i = 0; i < len; ++i)
        {
          bool f = false;
          //再遍历一次数组,让当前值与后面的值全都运算一遍
          for (int j = i+1; j < len; ++j)
          {
            if(nums[i] + nums[j] == target){
              r.push_back(i);
              r.push_back(j);
              f = true;
              break;
            }
          }
          if (f)
          {
            break;
          }
        }
        return r;

由于遍历了两遍,时间复杂度为O(n^2),同时此段代码提交到leetcode,其runtime为119ms,这个时间已经很长了.

2. 哈希表

减少运算时间,寻找优化方法,使用哈希表求解,哈希表查找速度非常快,时间复杂度为O(1),把当前元素的值作为key,其下标作为value,要求两个值之和等于target,即相当于在数组中查找target与当前元素的值之差,于是整个运算只需要循环一遍,其时间复杂度为O(n),C++代码如下:

vector<int> twoSum(vector<int>& nums, int target) {
      int len = nums.size();
      std::vector<int> r;
      std::unordered_map<int, int> hash;

      for (int i = 0; i < len; ++i)
      {
          //计算target与当前元素的差
          int tmp = target - nums[i];
          //判断差值是否在hash中
          if (hash.count(tmp))
          {
              r.push_back(i);
              r.push_back(hash[tmp]);
              return r;
          }
          //若不存在,则将当前元素的下标与其值以key-value形式存入hash中
          hash[nums[i]] = i;
      }
      return r;

此段代码提交到leetcode,其runtime为6ms,运行时间较之暴力求解法明显缩短了.

本文总阅读量