English:
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].
中文:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
1.
我首先想到的是两层遍历,但是时间复杂度n+(n-1)+(n-2)····+1=O(n^2) 明显不是最优,而且算法题出现这么高的复杂度的很少。
两层遍历法和选择排序有点像:
int* twoSum(int* nums, int numsSize, int target)
{
static int a[2]={0};
for (int i = 0; i < numsSize - 1; i++)
{
for (int j = i+1; j < numsSize; j++)
{
if (nums[i] + nums[j] == target)
{
a[0] = i;
a[1] = j;
return a;
}
}
}
return 0;
}
2.
这是评论里面给出的解法,又被叫做暴力算法。是用C写的。
后来我选择将计算两个数和转化为求差:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if nums is None:
return None
for i,v in enumerate(nums):
p = target - v
cop = nums[i+1:]
if p in cop:
return [i, cop.index(p)+i+1]
将target值减去当前的遍历值,然后在找算出来的差值是否在后面剩余的数中,找到取下标输出,这样看似一层循环,但是if p in cop:
对于列表来说in的时间复杂度为O(K+1),k为目标的下标,并不是O(1)。
这还是很慢。
3.
所以在大佬的帮助下又写出了新的方法:利用字典:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if nums is None:
return None
d = {}
for i,v in enumerate(nums):
p = target - v
if p in d:
return [d[p], i]
d[v] = i
这是将找到符合的值之前将前面的元素保存在字典中,元素为键,下标为值。
image.png可以看到时间复杂度以下就提上来了,因为in 这个关键字,在列表里面用很慢,但是在字典中,使用的是映射,可以直接找到,所以快很多。但是明显的内存消耗变大了。
网友评论