LeetCode(1) Two Sum实现

来源:互联网 发布:grub安装ubuntu 编辑:程序博客网 时间:2024/06/05 13:35

题目:https://oj.leetcode.com/problems/two-sum/

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


解决思路:

(1) 简单粗暴的方式

方法:

先找数组里面的最大值为max,最小值为min,如果min值小于0,则需要参与计算的数据范围为 [ min ,  target-min],如果大于等于0 ,则计算范围为[ min , target ],得到这个范围后再来一次简单粗暴的二维数组遍历

算法复杂度:

O(n^2)

实现:

public int[] twoSum(int[] numbers, int target) {//先找出数组里面的最大最小值,以及需要参数计算的数据最大值int min = Integer.MAX_VALUE;int max = 0;for (int i = 0; i < numbers.length; i++) {int val = numbers[i];if (val < min) {min = val;}if (val > max) {max = val;}}//限定值的范围,超过该值的不参与计算,可减少二维数组运算int limitMax = 0;if (min >= 0) {limitMax = target;} else {limitMax = target - min;}System.out.println("min=" + min);System.out.println("max=" + max);System.out.println("limitMax=" + limitMax);for (int i = 0; i < numbers.length; i++) {int curVal = numbers[i];if (curVal > limitMax) {continue;}for (int j = 0; j < numbers.length; j++) {//自己跟自己就不比了if (j == i) {continue;}int otherVal = numbers[j];if (otherVal > limitMax) {continue;}if (curVal + otherVal == target) {int[] resArr = new int[2];if (curVal <= otherVal) {resArr[0] = curVal;resArr[1] = otherVal;} else {resArr[0] = otherVal;resArr[1] = curVal;}return resArr;}}}return null;}

OJ测试:

不通过,因为运算超过时间限制

建议:

不使用


(2)利用hash表

方法:

先将数组里面的所有数据映射到map中,key为数值,value为值所在数组的位置,然后通过遍历数组,获得target-numbers[i]取得差值,根据差值去map中查找是否有对应的数据存在,有就返回,兼容数组中出现重复的数据,即同一个值可以同时出现多次,所以选择使用了该数据结构:Map<Integer,List<Integer>> ,即可以用list保存多个位置

算法复杂度:

O(2n)

实现:

public int[] twoSum(int[] numbers, int target) {//将所有的数据映射到map中,key为值,value为值所在数组的位置Map<Integer,List<Integer>> valPosMap = new HashMap<Integer,List<Integer>>();for (int i = 0; i < numbers.length; i++) {int curVal = numbers[i];if(valPosMap.get(curVal) == null){List<Integer> posList = new ArrayList<Integer>();valPosMap.put(curVal, posList);}valPosMap.get(curVal).add(i);}for (int i = 0; i < numbers.length; i++) {int curPos = i + 1;int subVal = target - numbers[i];List<Integer> posList = valPosMap.get(subVal);if(posList != null){for(Integer pos : posList){if(pos.intValue() == i){continue;}int otherPos = pos + 1; int[] resArr = new int[2];if (curPos <= otherPos) {resArr[0] = curPos;resArr[1] = otherPos;} else {resArr[0] = otherPos;resArr[1] = curPos;}return resArr;}}}return null;}

OJ测试:

通过

建议:

可以使用,非最优


(3)利用hash表(优化)

方法:

按顺序遍历,如果hash表中没有该数据的位置值,则插入到表中,存在后则找出target与当前数值的差值是否在hash表中存在,存在的话直接找出另外一个值即可,此算法最长路径为遍历全部数组,相对第二种实现,如果不是极端的情况,可以减少内存的使用,而且遍历的数据量也会减少,为最优化算法

算法复杂度:

O(n)

实现:

public int[] twoSum(int[] numbers, int target) {//将所有的数据映射到map中,key为值,value为值所在数组的位置Map<Integer,List<Integer>> valPosMap = new HashMap<Integer,List<Integer>>();for (int i = 0; i < numbers.length; i++) {int curPos = i + 1;int curVal = numbers[i];if(valPosMap.get(curVal) == null){List<Integer> posList = new ArrayList<Integer>();valPosMap.put(curVal, posList);}valPosMap.get(curVal).add(curPos);int subVal = target - curVal;List<Integer> posList = valPosMap.get(subVal);if(posList != null){for(Integer pos : posList){if(pos.intValue() == curPos){continue;}int[] resArr = new int[2];if (curPos <= pos) {resArr[0] = curPos;resArr[1] = pos;} else {resArr[0] = pos;resArr[1] = curPos;}return resArr;}}}return null;}

OJ测试:

通过

建议:

推荐,最优


0 0
原创粉丝点击