Array
Hash Table
Description
Given an array of integers nums
and an integer target
, return indices of the two numbers such that they add up to target
.
You may assume that each input would have exactly one solution , and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
Constraints:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
Only one valid answer exists.
Follow-up: Can you come up with an algorithm that is less than O(n2 )
time complexity?
Solutions
Solution 1: Hash Table
We can use a hash table \(\textit{d}\) to store each element and its corresponding index.
Traverse the array \(\textit{nums}\) , for the current element \(\textit{nums}[i]\) , we first check if \(\textit{target} - \textit{nums}[i]\) is in the hash table \(\textit{d}\) . If it is in \(\textit{d}\) , it means the \(\textit{target}\) value has been found, and we return the indices of \(\textit{target} - \textit{nums}[i]\) and \(i\) .
Time complexity is \(O(n)\) , and space complexity is \(O(n)\) , where \(n\) is the length of the array \(\textit{nums}\) .
Python3 Java C++ Go TypeScript Rust JavaScript C# PHP Scala Swift Ruby Kotlin Nim Cangjie C
class Solution :
def twoSum ( self , nums : List [ int ], target : int ) -> List [ int ]:
d = {}
for i , x in enumerate ( nums ):
if ( y := target - x ) 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
}
[]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include <stdlib.h>
int * twoSum ( int * nums , int numsSize , int target , int * returnSize ) {
int capacity = 1 ;
while ( capacity < numsSize * 2 ) capacity <<= 1 ;
int * keys = malloc ( capacity * sizeof ( int ));
int * vals = malloc ( capacity * sizeof ( int ));
char * used = calloc ( capacity , sizeof ( char ));
if ( ! keys || ! vals || ! used ) {
free ( keys );
free ( vals );
free ( used );
* returnSize = 0 ;
return NULL ;
}
for ( int i = 0 ; i < numsSize ; ++ i ) {
int x = nums [ i ];
int y = target - x ;
unsigned int h = ( unsigned int ) y & ( capacity - 1 );
while ( used [ h ]) {
if ( keys [ h ] == y ) {
int * res = malloc ( 2 * sizeof ( int ));
res [ 0 ] = vals [ h ];
res [ 1 ] = i ;
* returnSize = 2 ;
free ( keys );
free ( vals );
free ( used );
return res ;
}
h = ( h + 1 ) & ( capacity - 1 );
}
unsigned int h2 = ( unsigned int ) x & ( capacity - 1 );
while ( used [ h2 ]) h2 = ( h2 + 1 ) & ( capacity - 1 );
used [ h2 ] = 1 ;
keys [ h2 ] = x ;
vals [ h2 ] = i ;
}
* returnSize = 0 ;
free ( keys );
free ( vals );
free ( used );
return NULL ;
}