数组
哈希表
题目描述
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入: nums = [3,2,4], target = 6
输出: [1,2]
示例 3:
输入: nums = [3,3], target = 6
输出: [0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
进阶: 你可以想出一个时间复杂度小于 O(n2 )
的算法吗?
解法
方法一:哈希表
我们可以使用一个哈希表 $\textit{d}$ 来存储每个元素及其对应的索引。
遍历数组 $\textit{nums}$,对于当前元素 $\textit{nums}[i]$,我们首先判断 $\textit{target} - \textit{nums}[i]$ 是否在哈希表 $\textit{d}$ 中,如果在 $\textit{d}$ 中,说明 $\textit{target}$ 值已经找到,返回 $\textit{target} - \textit{nums}[i]$ 的索引和 $i$ 即可。
时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。
Python3 Java C++ Go TypeScript Rust JavaScript C# PHP Scala Swift Ruby Kotlin Nim Cangjie
class Solution :
def twoSum ( self , nums : List [ int ], target : int ) -> List [ int ]:
d = {}
for i , x in enumerate ( nums ):
y = target - x
if y in d :
return [ d [ y ], i ]
d [ x ] = i
1
2
3
4
5
6
7
8
9
10
11
12
13 class Solution {
public int [] twoSum ( int [] nums , int target ) {
Map < Integer , Integer > d = new HashMap <> ();
for ( int i = 0 ;; ++ i ) {
int x = nums [ i ] ;
int y = target - x ;
if ( d . containsKey ( y )) {
return new int [] { d . get ( y ), i };
}
d . put ( x , i );
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14 class Solution {
public :
vector < int > twoSum ( vector < int >& nums , int target ) {
unordered_map < int , int > d ;
for ( int i = 0 ;; ++ i ) {
int x = nums [ i ];
int y = target - x ;
if ( d . contains ( y )) {
return { d [ y ], i };
}
d [ x ] = i ;
}
}
};
func twoSum ( nums [] int , target int ) [] int {
d := map [ int ] int {}
for i := 0 ; ; i ++ {
x := nums [ i ]
y := target - x
if j , ok := d [ y ]; ok {
return [] int { j , i }
}
d [ x ] = i
}
}
function twoSum ( nums : number [], target : number ) : number [] {
const d = new Map < number , number > ();
for ( let i = 0 ; ; ++ i ) {
const x = nums [ i ];
const y = target - x ;
if ( d . has ( y )) {
return [ d . get ( y ) ! , i ];
}
d . set ( x , i );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 use std :: collections :: HashMap ;
impl Solution {
pub fn two_sum ( nums : Vec < i32 > , target : i32 ) -> Vec < i32 > {
let mut d = HashMap :: new ();
for ( i , & x ) in nums . iter (). enumerate () {
let y = target - x ;
if let Some ( & j ) = d . get ( & y ) {
return vec! [ j as i32 , i as i32 ];
}
d . insert ( x , i );
}
vec! []
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 /**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function ( nums , target ) {
const d = new Map ();
for ( let i = 0 ; ; ++ i ) {
const x = nums [ i ];
const y = target - x ;
if ( d . has ( y )) {
return [ d . get ( y ), i ];
}
d . set ( x , i );
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class Solution {
public int [] TwoSum ( int [] nums , int target ) {
var d = new Dictionary < int , int > ();
for ( int i = 0 , j ; ; ++ i ) {
int x = nums [ i ];
int y = target - x ;
if ( d . TryGetValue ( y , out j )) {
return new [] { j , i };
}
if ( ! d . ContainsKey ( x )) {
d . Add ( x , i );
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 class Solution {
/**
* @param Integer[] $nums
* @param Integer $target
* @return Integer[]
*/
function twoSum($nums, $target) {
$d = [];
foreach ($nums as $i => $x) {
$y = $target - $x;
if (isset($d[$y])) {
return [$d[$y], $i];
}
$d[$x] = $i;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import scala . collection . mutable
object Solution {
def twoSum ( nums : Array [ Int ], target : Int ): Array [ Int ] = {
val d = mutable . Map [ Int , Int ]()
var ans : Array [ Int ] = Array ()
for ( i <- nums . indices if ans . isEmpty ) {
val x = nums ( i )
val y = target - x
if ( d . contains ( y )) {
ans = Array ( d ( y ), i )
} else {
d ( x ) = i
}
}
ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13 class Solution {
func twoSum ( _ nums : [ Int ], _ target : Int ) -> [ Int ] {
var d = [ Int : Int ]()
for ( i , x ) in nums . enumerated () {
let y = target - x
if let j = d [ y ] {
return [ j , i ]
}
d [ x ] = i
}
return []
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13 # @param {Integer[]} nums
# @param {Integer} target
# @return {Integer[]}
def two_sum ( nums , target )
d = {}
nums . each_with_index do | x , i |
y = target - x
if d . key? ( y )
return [ d [ y ] , i ]
end
d [ x ] = i
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14 class Solution {
fun twoSum ( nums : IntArray , target : Int ): IntArray {
val m = mutableMapOf < Int , Int > ()
nums . forEachIndexed { i , x ->
val y = target - x
val j = m . get ( y )
if ( j != null ) {
return intArrayOf ( j , i )
}
m [ x ] = i
}
return intArrayOf ()
}
}
import std / enumerate
import std / tables
proc twoSum ( nums : seq [ int ] , target : int ): seq [ int ] =
var d = initTable [ int , int ] ()
for i , x in nums . pairs ():
let y = target - x
if d . hasKey ( y ):
return @[ d [ y ] , i ]
d [ x ] = i
return @[]
1
2
3
4
5
6
7
8
9
10
11
12 class Solution {
func twoSum(nums: Array<Int64>, target: Int64): Array<Int64> {
let d = HashMap<Int64, Int64>()
for (i in 0..nums.size) {
if (d.contains(target - nums[i])) {
return [d[target - nums[i]], i]
}
d[nums[i]] = i
}
[]
}
}