LeetCode刷题计划——1. 两数之和

之前上大学时搞过一段ACM,虽然没弄出什么大名堂,但搞算法的心一直蠢蠢欲动。所以特开此专栏,每天争取刷一道题,聊以自慰!

刷题平台选定为LeetCode,上去刷了两道题,发现风格和之前各大OJ还是很不同的

  LeetCode OJ
数据量 不会告诉你数据量的多少 会明确告知最大数据量是多少
取值范围  不会告知数据的取值范围 会明确告知数据取值范围
语言   纯中文 英文居多,中文少
题目 比较简单,看完题目就大概知道是考察什么知识点的,主要是应对面试 比较复杂,考察的是解决实际问题的思路,有时候读完题目还是一头雾水(说的就是你,青蛙跳地球)
测试数据     不够严谨,官方给出的题解中没有考虑许多特殊情况        测数数据量很大,并且足够严谨,代码需要考虑到各种特殊情况,否则很容易wrong

最主要的还是LeetCode的结果输出方式太不习惯,必须以函数的形式返回结果,而OJ只需打印出结果即可!

基于以上特点,本专栏将不会讨论具体的代码,而是更多的关注算法的探讨、代码书写规范、解题思路的拓展。


两数之和就是,给定一个数组,求数组中两数之和等于target的数组下标。(下标必须不同)默认只有一组解。

1. 典型思路

嵌套循环遍历,时间复杂度O(n2),空间复杂度O(1)

要想突破O(n2),必须采用空间换时间的思路!

2. 先排序再计算,时间复杂度O(nlogn),空间复杂度O(n)

由于排序会打乱原下标,所以要新建数据结构,保存原数据及其下标,再对新建的数据结构排序。

排序最快的时间复杂度为O(nlogn)

计算的话,可以使用头、尾俩指针,如果大于target,尾指针前移,如果小于target,头指针后移。

3. 使用Hash原理,时间复杂度O(n),空间复杂度O(n)

1).  如果在数据范围确定的情况下,可以使用数组。对于数组数据num[i],首先判断Array[target-num[i]]是否不为0,如果为0,将Array[num[i]]置为i,

如果不为0,直接输出i,Array[target-num[i]]。

2). 如果数据范围不确定的情况下,Java可以使用Map<int,int>。方式同使用数组一致。

注意:这么实现的原理是确保了只有一组解。

拓展:如果有多组解,且要求输出所有解,时间复杂度O(n)的情况下怎么处理?

使用Map<int , int[]>,存储所有hash的key值相同的下标。但要注意,这里就不能使用边判断,边hash,仅遍历一遍这种方式了。

需要先构建完整的Map,然后再重新遍历。

还需要注意的是(i,j)和(j,i)是同一种结果,所以输出Map的value值数组时,使用value数组的第一位作为哨兵位,首次访问此<key,value>时,将哨兵位置特殊值,以后再访问此键值对时,先判断哨兵位是否访问过

如此方可保证时间复杂度为O(n)。

原文地址:https://www.cnblogs.com/AI-U/p/10412568.html