Two Sum (leetcode1)

来源:互联网 发布:c语言中的贪心算法 编辑:程序博客网 时间:2024/06/07 09:10

题目描述:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

基本结题思路:一开始直接想到的是先快排,然后迭代排序后的数组的每一个元素nums[i],使得num2 = target-nums[i],然后再在数组对num2进行二分查找,这种思路的时间复杂度为O(nlogn),但是也过了。直接贴代码:

/*1.类A为封装数组元素的值和下标,可以用Map代替2.因为可能出现target = n 其中数组存在两个 n/2的情况存在,直接找下一个元素,若值相等则得到答案,否则继续迭代  */import java.util.ArrayList;import java.util.Collections;public class Solution {    /*public static void main(String[] args) {        Solution solution = new Solution();        int[] ans = solution.twoSum(new int[]{3,2,3},6);        System.out.println(ans[0]+","+ans[1]);    }*/    public int[] twoSum(int[] nums, int target) {         ArrayList<A> list = new ArrayList<A>();         for(int i=0;i<nums.length;i++){                list.add(new A(i,nums[i]));         }         Collections.sort(list);         for(int i=0;i<list.size();i++){             A a = list.get(i);             int num2 = target - a.num;             //情况2,见顶部注释             if(num2==a.num){                 if(list.get(i+1).num==num2){                     return new int[]{a.index,list.get(i+1).index};                 }                 continue;             }             //binarySearch返回-1时表示查找失败             int index2 = binarySearch(list,num2);             if(index2!=-1){                 return new int[]{a.index,index2};             }         }         return null;     }    //二分查找    private int binarySearch(ArrayList<A> list, int num2) {        int left = 0;        int right = list.size()-1;        while(left<=right){            int mid = (left+right)/2;            if(list.get(mid).num==num2) return list.get(mid).index;            else if(list.get(mid).num<num2) left = mid + 1;            else right = mid - 1;        }        return -1;    }}class A implements Comparable<A>{    int index;    int num;    public A(int index,int num){        this.index = index;        this.num = num;    }    @Override    public int compareTo(A a) {        return num - a.num;    }    public String toString(){        return index+","+num;    }}

做完后对比别人的方法,学习到了多两种方法:
1.一种O(nlogn)的解法,先对数组进行快排,然后通过首尾指针对整个数组进行查找,记首指针的值为first,尾指针的值为last,
if(nums[first]+nums[last]大于target) last–;
else if(nums[first]+nums[last]小于target) first++;
else 相等 return 答案

2.一种O(n)的解法,用到了hash的方法,使得可以通过关键值在常数的时间内在数组里寻找,值得注意的是需要判断一下target/2的值对应的位置是否存在2个以上,在迭代的时候若发现当前元素对应hash的位置被占领,则相加判断是否等于target,若相等则直接返回,上一下写的代码:

import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;public class Solution {    /*public static void main(String[] args) {        Solution solution = new Solution();        int[] ans = solution.twoSum(new int[]{3,2,3},6);        System.out.println(ans[0]+","+ans[1]);    }*/    public int[] twoSum(int[] nums, int target) {         HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();         for(int i=0;i<nums.length;i++){             if(map.get(nums[i])==null){                 map.put(nums[i], i);             }             else{                 //若该元素已存在并且刚好等于target/2,直接返回答案                 if(nums[i]*2==target){                     return new int[]{map.get(nums[i]),i};                 }             }         }         for(int i=0;i<nums.length;i++){             Integer index = map.get(target-nums[i]);             //target-nums[i]!=nums[i]是为了解决数组只有一个值为target/2元素的情况             if(index!=null&&target-nums[i]!=nums[i]){                 return new int[]{i,index};             }         }         return null;     }}
原创粉丝点击