您的位置:首页 > 理论基础 > 数据结构算法

[算法] 使用“复杂”的数据结构降低时间复杂度

2017-12-04 22:47 441 查看

Leetcode 1: Two Sum

问题描述

给定一个整数数组和一个目标数,返回两个下标,使数组中这两个下标所代表的数字之和等于目标数。

你可以认为每组输入有且仅有一个正解,除此之外,两个下标不应当相等。

例子:

给定一数组nums = [2, 7, 11, 15],目标数target = 9

因为nums[0] + nums[1] = 2 + 7 = 9 = target,所以最后返回[0, 1]。

解题思路

显然的,本题最直接明了的方式就是暴力循环两个数组,依次算出所有和,并判定它是否与目标数相等,可以写出:

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


这里我们发现,已知nums[i]和target,nums[j]可以取的值是固定的,所以可以不必每次都做加法运算,将内循环改为:

int tar = target - nums[i];
ret[0] = i;
for (int j = i + 1; j < nums.size(); j++) {
if (nums[j] == tar) {
ret[1] = j;
return ret;
}
}


但这里只是改进了常数级别的时间复杂度,有没有什么方法只遍历数组一次就解决呢?如果想要只遍历一次就解决,主要的矛盾还是在如何不必循环就快速的查询出
target - nums[i]
是否在之前存在过。这里我使用了map作为查询的方法。

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


果然,改进之后,时间复杂度大幅度降低。通过时间由166ms降低为9ms。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐