two Sum
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].
两个数求和
给定一个整数数组,返回两个数字的索引,使它们相加到特定目标值。
您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素。
我的思路是:数组中任意两个元素之和等于目标值,并且返回这两个元素的下标。遍历两次数组,第一次取的值当做第一个元素,然后用目标值相减得到另外一个值,然后判断第二个值是否存在于数组中,如果存在就返回两个元素的下标,如果不存在,则返回null。
code:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for(int i=0;i<nums.length;i++){
int other = target - nums[i] ;
for(int j=i+1;j<nums.length;j++){
if(other == nums[j]){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
}
结果分析:
Runtime: 23 ms, faster than 32.78% of Java online submissions for Two Sum.
Memory Usage: 38.6 MB, less than 39.16% of Java online submissions for Two Sum.
code2:
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(target - nums[i] == nums[j]){
return new int[]{i,j};
}
}
}
return null;
}
}
结果分析:
Runtime: 15 ms, faster than 44.10% of Java online submissions for Two Sum.
Memory Usage: 38.4 MB, less than 50.25% of Java online submissions for Two Sum.
上述解法在时间复杂度是O(n),在空间复杂度是O(1)。
下面是别人的解法,利用空间换时间的想法,来实现:
利用hashtable来解决,下面的时间复杂度是O(n),空间复杂度也是O(n),比上面的两种做法效率高了很多,当时自己第一反应就是用数据,并没有想到用hashtable来处理,所以选择合适的数据结构,可以提高程序的运行效率。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
map.put(nums[i],i);
}
for(int i=0;i<nums.length;i++){
int result = target - nums[i];
if(map.containsKey(result) && map.get(result) !=i){
return new int[]{i,map.get(result)};
}
}
throw new IllegalArgumentException("no two sum solution");
}
}
Runtime: 2 ms, faster than 99.93% of Java online submissions for Two Sum.
Memory Usage: 39.2 MB, less than 23.52% of Java online submissions for Two Sum.
在一次循环中做处理:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
int result = target - nums[i];
if(map.containsKey(result) && map.get(result) !=i){
return new int[]{i,map.get(result)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("no two sum solution");
}
}
Runtime: 2 ms, faster than 99.93% of Java online submissions for Two Sum.
Memory Usage: 39.1 MB, less than 24.88% of Java online submissions for Two Sum.
看了讨论区又发现一种效率更高的算法,思路如下:
1.先把原有数组copy到一个新数组中
2.对新数组进行排序,让元素从小到大排列
3.while循环找出两个num值
4.循环原有数组找出值为第3步中找到的值的索引,此处分别讨论了num1和num2相等和不等的情况
5.最后返回
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] num2 = Arrays.copyOf(nums,nums.length);
Arrays.sort(num2);
int start = 0;
int end = num2.length-1;
int a = 0;int b = 0;
while (start<end){
int sum = num2[start] + num2[end];
if(sum < target){
start++;
}else if(sum > target){
end--;
}else{
a = num2[start];
b = num2[end];
break;
}
}
int[] index = new int[2];
for(int i=0;i<nums.length;i++){
if(nums[i] == a){
index[0] = i;
break;
}
}
if(a!=b){
for(int i=0;i<nums.length;i++){
if(nums[i] == b){
index[1] = i;
break;
}
}
}else{
for(int i=0;i<nums.length;i++){
if(nums[i] == b && index[0] != i){
index[1] = i;
break;
}
}
}
return index;
}
}
Runtime: 2 ms, faster than 99.93% of Java online submissions for Two Sum.
Memory Usage: 38.1 MB, less than 73.96% of Java online submissions for Two Sum.