面试经典150题 day27
题目来源
我的题解
方法一 哈希表
使用哈希表存储每个元素及其位置。
然后遍历过程中判断 哈希表中是否存在 target-numbers[i],若存在,则直接将 当前位置+1 和 map.get(target-numbers[i]) 返回
时间复杂度 :O(n)
空间复杂度:O(n)。哈希表需要的空间
java
public int[] twoSum(int[] numbers, int target) {
Map<Integer,Integer> map=new HashMap<>();
int n=numbers.length;
for(int i=0;i<n;i++){
map.put(numbers[i],i+1);
}
for(int i=0;i<n;i++){
if(map.containsKey(target-numbers[i])){
return new int[]{i+1,map.get(target-numbers[i])};
}
}
return new int[]{-1,-1};
}
方法二 双指针
因为数组本身升序排序,所以可以使用双指针来解决。初始时,一个指针left指向开始位置,一个指针right指向结束位置。若numbers[left]+numbers[right]=target,则直接返回[left+1,right+1];若大于则right--,因为只有right往左移才会使得和更小;若小于则left++,因为只有left往右移才会使得和更大。
时间复杂度:O(n)空间复杂度:O(1)
java
public int[] twoSum(int[] numbers, int target) {
int n=numbers.length;
if(n==2){
return new int[]{1,2};
}
int left=0,right=n-1;
while(left<right){
int t=numbers[left]+numbers[right];
if(t==target){
return new int[]{left+1,right+1};
}else if(t>target){
right--;
}else{
left++;
}
}
return new int[]{-1,-1};
}
方法三 双指针(二分查找优化)
因为数组本身升序排序,所以可以使用双指针来解决。初始时,一个指针left指向开始位置,一个指针right指向结束位置。
若numbers[left]+numbers[right]=target,则直接返回[left+1,right+1];
若numbers[left]+numbers[mid]=target,则直接返回[left+1,mid+1];
若numbers[left]+numbers[mid]>target则right=mid-1,因为只有mid往左移才会使得和更小;
若numbers[left]+numbers[mid]<target则left=mid+1,因为只有left往右移才会使得和更大。
时间复杂度:最好情况O(logN),最坏O(N)空间复杂度:O(1)
java
public int[] twoSum(int[] numbers, int target) {
int left=0,right=numbers.length-1;
while(left<right){
int sum=numbers[left]+numbers[right];
int mid=left+((right-left)>>1);
if(sum==target)
return new int[]{left+1,right+1};
else if(numbers[left]+numbers[mid]>target)
right=mid-1;
else if(numbers[mid]+numbers[right]<target)
left=mid+1;
else if(sum>target)
right--;
else
left++;
}
return new int[]{-1,-1};
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~