题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
题目详解
这道题目给我们一个数组,数组里面全是整数,然后再给我们一个数字,需要我们求出在这个数组中哪两个数字的和正好是target。注意,你不能重复利用这个数组中同样的元素,指的是每一个位置上的数字只能被使用一次,比如数组 [3,3,5],你可以使用第一个和第二个 3,但是你不能使用第一个 3 两次。
解题方案
思路1: 时间复杂度: O(N^2) 空间复杂度: O(1)
暴力解法,双重循环遍历:
外层循环从数组中取出下标为 i 的元素 num[i],内层循环取出 i 之后的元素 nums[j] 一一与下标为 i 的元素进行相加操作,判断结果是否为 target。
下面我们来看代码
python beats27.6%
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
# 第一轮遍历
for i in range(len(nums)):
# 第二轮遍历不能重复计算了
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
# 注意 leetcode 中要求返回的是索引位置
return [i, j]
Java beats 36.03%
package com.company;
import java.util.HashMap;
public class sum {
public static void main(String[] args) {
int nums[] = {2,7,11,15};
int target = 9;
sum s = new sum();
int twoIndex[] = new int[2];
twoIndex = s.twoSum(nums,target);
for(int a:twoIndex)
System.out.println(a);
}
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 将原本为两个目标值切换为一个目标值,只需要每次从 map 中寻找目标值即可
int num = target - nums[i];
if (map.containsKey(num)) {
return new int[]{map.get(num), i};
}
// 每次遍历过的值都存储到 map 中,这样之后就能从 map 中寻找需要的目标值
map.put(nums[i], i);
}
return null;
}
}
结果:2 3;
php
<?php
class Solution{
public function two(){
$nums = [2,7,11,15];
$target = 26;
for($i = 0;$i<count($nums);$i++) {
for ($j = $i + 1; $j < count($nums); $j++) {
if ($nums[$i] + $nums[$j] == $target) {
print_r([$i,$j]);
}
}
}
}
}
$res = new Solution();
$res->two();
结果:Array
(
[0] => 2
[1] => 3
)
可以看到上述代码的beats(代码优劣程度)明显较低,这是因为我们的时间复杂度是O(N^2)的。
思路2:时间复杂度: O(N) 空间复杂度: O(N)
上面的思路1时间复杂度太高了,是典型的加快时间的方法,这样做是不可取的。其实我们可以牺牲空间来换取时间。
java
package com.company;
import java.util.HashMap;
public class sum {
public static void main(String[] args) {
int nums[] = {2,7,11,15};
int target = 9;
sum s = new sum();
int twoIndex[] = new int[2];
twoIndex = s.twoSum(nums,target);
for(int a:twoIndex)
System.out.println(a);
}
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 将原本为两个目标值切换为一个目标值,只需要每次从 map 中寻找目标值即可
int num = target - nums[i];
if (map.containsKey(num)) {
return new int[]{map.get(num), i};
}
// 每次遍历过的值都存储到 map 中,这样之后就能从 map 中寻找需要的目标值
map.put(nums[i], i);
}
return null;
}
}
php
<?php
class Solution{
public function two(){
$nums = [2,7,11,15];
$target = 26;
for($i=0;$i<count($nums);$i++){
$num = $target - $nums[$i];
if(in_array($num,$nums)){
echo $i.' ' ;
}
}
}
}
$res = new Solution();
$res->two();