[算法] 使用“复杂”的数据结构降低时间复杂度
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。
相关文章推荐
- 时间复杂度和空间复杂度2 - 数据结构和算法04
- 数据结构--算法(时间复杂度和空间复杂度)
- 时间复杂度和空间复杂度2 - 数据结构和算法04
- 数据结构2:算法时间复杂度和空间复杂度的计算
- 数据结构-算法效率的度量-时间复杂度和空间复杂度
- 数据结构和算法-时间复杂度和空间复杂度
- 数据结构和算法学习02-时间复杂度和空间复杂度
- 数据结构与算法2——时间复杂度和空间复杂度
- 数据结构——算法之(017)( 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1))
- n个无序整数,已知第i个数在排好序的序列中的位置为j,满足|i-j|<=K,请设计一种排序算法,对该序列进行排序。注:算法时间复杂度为O(nlgn)的得0分,复杂度为O(nk) 的得两分,总分是20分
- 排序算法的C语言实现以及各个算法的时间复杂度和空间复杂度分析(冒泡排序)
- 试设计一个算法,将数组A(0..n-1)中的元素循环右移k位,并要求空间复杂度为O(1),时间复杂度为O(n)。
- 算法和数据结构 第一章:算法的时间复杂度
- 归并排序的改进算法(使用静态链表)的时间复杂度分析
- 【算法与数据结构】关于代码运行时间复杂度的计算方法
- 数据挖掘算法的空间复杂度与时间复杂度分析
- 有关算法时间复杂度和空间复杂度的浅析
- 题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。
- 数据结构-算法-时间复杂度计算
- 《编程之美》中买书问题算法。空间复杂度O(n),时间复杂度O(n),求挑战