0
点赞
收藏
分享

微信扫一扫

剑指offer06:排序数组中的两个数组之和


**题目:**输入一个递增排序的数组和一个值k,请问如何在数组中找出两个和为k的数字并返回他们的下标, 假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。例如输入数组[1,2,4,6,10], k的值为8,数组中的数字2与6的和为8,它们的下标分别为1与3。
分析:
这道题有和多种做法,一般最简单的做法就是先固定一个数字,然后依次判断和这个数字的和是否为k,如果数组有n个数字,需要对每个数字比较n-1次,时间复杂度为O(n^2)。(代码比较简单就不再上传了)
第二种是用空间换时间,使用哈希表,将数组所有数字都存入哈希表中,然后逐个扫描数组中的数字,扫描到一个数字i,如果哈希表存在数字k-i,那就成功找到一对和为k的数字了,判断哈希表是否存在一个数字的时间复杂度为O(1)。该方法的时间复杂度为O(n),空间复杂度也是O(n)。

package com.wzc;

import java.util.HashMap;

public class TwoSum {
// 输入一个递增排序的数组和一个值k,请问如何在数组中找出两个和为k的数字并返回他们的下标,
// 假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。例如输入数组[1,2,4,6,10]
// k的值为8,数组中的数字2与6的和为8,它们的下标分别为1与3
public static void main(String[] args) {
int[] numbers= {1,2,4,6,10};
int[] ints = twoSum(numbers, 8);
for (int anInt : ints) {
System.out.println(anInt);
}
}
public static int[] twoSum(int[] numbers,int target){
int[] res = new int[2];
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < numbers.length; i++) {
map.put(numbers[i],i);
}
for (int i = 0; i < numbers.length; i++) {
res[0] = i;
int k = target-numbers[i];
if (map.containsKey(k)) {
res[1] = map.get(k);
break;
}

}
return res;
}
}

剑指offer06:排序数组中的两个数组之和_java


那能不能时间复杂度低空间复杂度也低呢,由于数组时递增的,我们可以采用一种双指针的方式,第一个指针指向下标为0的数组,第二个指针指向数组中最后一个数字,如果第一个指针指向的数字和第二个指针指向的数字相加小于目标数字,那么我们可以将第一个指针向右平移一个单位,同理要是相加大于目标数字,右边的指针向左平移一个单位,知道两者和等于目标数字,如下面代码,代码中只用了一个while,时间复杂度为O(n),并且空间复杂度为O(1)。

package com.wzc;

public class TwoSum {
// 输入一个递增排序的数组和一个值k,请问如何在数组中找出两个和为k的数字并返回他们的下标,
// 假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。例如输入数组[1,2,4,6,10]
// k的值为8,数组中的数字2与6的和为8,它们的下标分别为1与3
public static void main(String[] args) {
int[] numbers= {1,2,4,6,10};
int[] ints = twoSum(numbers, 8);
for (int anInt : ints) {
System.out.println(anInt);
}
}
public static int[] twoSum(int[] numbers,int target){
int i = 0;
int j =numbers.length-1;
while (i<j && numbers[i]+numbers[j]!=target){
if (numbers[i]+numbers[j]<target){
i++;
}else {
j--;
}
}
return new int[]{i,j};
}
}

剑指offer06:排序数组中的两个数组之和_数据结构_02


举报

相关推荐

0 条评论