LeetCode(1) || Two Sum
题记
一直都想好刷下LeetCode的题目,终于在今年工作的第一天晚上启动了,正好为我的算法学习之路开个头。目前LeetCode里面有179道题,争取两个月内刷完。
TwoSum问题描述
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
解题说明
- LeetCode 给了多种的语言,由于现在从事的是Java相关工作且Java调试方便,所以后续都将以Java为主。LeetCode提供了以下的Java函数。
1 public class Solution { 2 public int[] twoSum(int[] numbers, int target) { 3 4 } 5 }
- 题目的意思大致为:给予一个整数数组numbers,以及整数target,要求获取数组内两个相加和为target的数字a和b,且a<b,函数返回a和b在数组中的索引编号(从1开始)。要求计算复杂度尽量小。
- 该题乍一看比较简单,但是考虑到计算复杂度以及多种情况(比如负数,比如相同值的相加)后还是有点小难度的。
- 解出该问题并不难,两个for循环,计算复杂度为ο(n2)的方法就可以得出结果了,但是LeetCode运行代码是有时间限制的。所以我们需要考虑复杂度更低的,即ο(n)的哈希表。解题的核心思想就是如果a+b=target,那么就将a和b哈希到一起,这样就可以在一次循环求出结果。
- 在解题过程中我犯了两次错,第一次是没有考虑到负数情况,第二次是没有考虑到3+3=6这种情况,这也教育我在做算法的时候不仅要考虑效率,也要考虑全面。
解题结果
我使用了Java自带的HashMap来实现了hash。
1 import java.util.HashMap; 2 import java.util.Map; 3 public class Solution { 4 public int[] twoSum(int[] numbers, int target) { 5 int len = numbers.length; 6 Map<Integer,Integer> map = new HashMap<Integer,Integer>(); 7 int[] result = new int [2]; 8 for(int i = 0; i < len; i ++){ 9 10 Integer number = new Integer(numbers[i]); 11 Integer index = new Integer(i+1); 12 13 if(!map.containsKey(target - number)){ 14 map.put(number, index); 15 }else if( map.containsKey(target-number)){ 16 result[0]= map.get(target-number); 17 result[1]=i+1; 18 break; 19 } 20 } 21 return result; 22 } 23 }
运行结果:
看了运行的结果,不难发现Java的运行时间明显大于C和C++,于是相同的方法用C++实现了一遍:
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int> &numbers, int target) { 4 int i, sum; 5 vector<int> results; 6 map<int, int> hmap; 7 for(i=0; i<numbers.size(); i++){ 8 int num = numbers[i]; 9 if(!hmap.count(target-num)){ 10 hmap.insert(pair<int, int>(numbers[i], i+1)); 11 }else if(hmap.count(target-num)){ 12 results.push_back(hmap[target-numbers[i]]); 13 results.push_back(i+1); 14 break; 15 } 16 } 17 return results; 18 } 19 };
由此可见,相同的方法,用C++实现比JAVA快了近10倍。