No.1 两数之和 (easy)

题目描述

  给定一个整数数组 nums​ 和一个整数目标值 target​,请你在该数组中找出 和为目标值 target​ 的那 两个 整数,并返回它们的数组下标。

  你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

  你可以按任意顺序返回答案。

  给你一个整数 x​ ,如果 x​ 是一个回文整数,返回 true​ ;否则,返回 false​ 。

  示例 1:

  输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

  示例 2:

  输入: nums = [3,2,4], target = 6
输出: [1,2]

  示例 3:

  输入: nums = [3,3], target = 6
输出: [0,1]

题目分析

  该题目给出了一个数组,要求我们返回数组中两个数之和等于所给目标值的下标。如果所给的数组是有序那就好办了,可以直接使用从左右两端向中间扫描的办法(如果左1+右1比目标值大,则说明右1的值过大,则换成右2,反之亦然,以此类推),时间复杂度为:O(logN)。然而,从示例2可以看出来,数组是无序的,因此,我们有以下2种解法:

  解法1: 使用双重循环的暴力解法,时间复杂度为O(N^2)

  解法2: 使用字典(或称哈希表的办法),时间复杂度O(N)

解题思路

解法1

  固定从左1开始与其余各数相加,若不相等,则从左2开始以此类推。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//几年前的提交记录!_!
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int l=0,r=nums.size()-1;
while(l<r){
int i=r;
while(i>l){
if(nums[l]+nums[i] == target)return {l,i};
i--;
}
l++;
}
return {};
}
};

解法2

  固定从左1开始,如果左1的另一半(目标值减去左1)不在字典里,将左1作为键,左1的下标作为值存入字典,以此类推到左n,直到找到另一半的记录,与此同时返回左n与左n的另一半的下标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
std::vector<int> twoSum(std::vector<int> &nums, int target)
{
std::map<int, int> nums_index;
for (int i = 0; i < nums.size(); i++)
{
int elem = target - nums[i];
if (nums_index.find(elem) != nums_index.end())
{
return {nums_index[elem], i};
}
else
{
nums_index[nums[i]] = i;
}
}
return {};
}
};