1、给定一个整型数组,是否能找出其中的两个数为某个指定的值?假定数组无序,且元素各不相同,但不允许额外的存储空间。
思路:1、将数组排序 2、首尾元素加指针,计算两数之和,大于target尾指针左移一位,小于target头指针右移一位,直到和等于target为止。
时间复杂度为O(nlogn)
private boolean hasSum(int[] A, int target){ boolean res = false; if(A == null || A.length<2) return res; Arrays.sort(A); int i = 0,j = A.length-1; while(i<j){ if(A[i]+A[j] == target) { res =true; break; }else if(A[i]+A[j]>target){ j--; }else{ i++; } } return res; }
2、在1的基础上返回两数 的下标,可使用额外的存储空间。
时间复杂度O(n),空间复杂度O(n)
private int[] twoSum(int[] A,int target){ int[] res = {-1,-1}; if (A == null || A.length<2) return res; HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>(); for (int i = 0; i<A.length;i++){ hashMap.put(A[i],i); } for (int i = 0;i<A.length;i++){ if (hashMap.containsKey(target-A[i])&&target!=2*A[i]){ res[0] = i; res[1] = hashMap.get(target-A[i]); break; } } return res; }3、在2基础上允许集合中出现重复元素。
class TwoSum{ //哈希表里存放<值,个数> HashMap<Integer,Integer> hashMap = new HashMap<Integer, Integer>(); public void save(int input){ int count = 0; if (hashMap.containsKey(input)){ //判断是否已经存在,如果存在则读取个数 count = hashMap.get(input); } hashMap.put(input,count); } public boolean hasSum(int target){ Iterator<Integer> integerIterator = hashMap.keySet().iterator(); while (integerIterator.hasNext()){ int val = integerIterator.next(); if (hashMap.containsKey(target-val)){ boolean isDouble = target==val*2; //如果target值为某元素的两倍,那么只有该元素出现两次或以上才能返回true if (!(isDouble&&hashMap.get(val)==1)){ return true; } } } return false; } }