Two Sum - Leetcode 1 - HashMap - Python

NeetCode
9 Jun 202008:26

Takeaways

  • 😀 Дано массив чисел и целевое число, необходимо найти два значения в массиве, сумма которых равна целевому числу.
  • 😀 Возвращаем индексы этих двух значений.
  • 😀 Имеется гарантированное одно решение, не нужно беспокоиться о множественных решениях.
  • 😀 Базовое решение - проверка всех возможных пар значений, что приводит к сложности O(N^2).
  • 😀 Более эффективное решение - использование хеш-таблицы для хранения значений и их индексов.
  • 😀 При использовании хеш-таблицы проверяется, существует ли нужное значение (разница между целевым числом и текущим значением) в хеш-таблице.
  • 😀 Если нужное значение найдено в хеш-таблице, возвращаются индексы двух значений.
  • 😀 Проход по массиву выполняется за один раз, добавляя значения в хеш-таблицу по мере их обхода.
  • 😀 Алгоритм имеет временную сложность O(N) и требует дополнительной памяти O(N) для хеш-таблицы.
  • 😀 Код решения состоит из создания хеш-таблицы, итерации по массиву, проверки наличия нужного значения в хеш-таблице и возврата индексов.

Q & A

  • Какова основная цель задачи, обсуждаемой в видео?

    -Найти два значения в заданном массиве, которые в сумме дают целевое значение (в данном случае 9), и вернуть их индексы.

  • Какой самый интуитивный способ решения этой задачи?

    -Самый интуитивный способ решения - это перебор всех возможных комбинаций двух значений и проверка, дают ли они в сумме целевое значение.

  • Какова временная сложность алгоритма полного перебора?

    -Временная сложность алгоритма полного перебора составляет O(n^2), где n - длина массива.

  • Какой более эффективный способ решения предложен в видео?

    -Более эффективный способ решения - использовать хэш-таблицу (hash map) для хранения значений и их индексов, чтобы проверять наличие необходимого значения за константное время.

  • Какую структуру данных рекомендуется использовать для улучшения эффективности алгоритма?

    -Рекомендуется использовать хэш-таблицу (hash map).

  • Какова временная сложность предложенного в видео алгоритма с использованием хэш-таблицы?

    -Временная сложность предложенного алгоритма составляет O(n), где n - длина массива.

  • Какова пространственная сложность алгоритма с использованием хэш-таблицы?

    -Пространственная сложность алгоритма составляет O(n), так как в хэш-таблицу может быть добавлено до n элементов.

  • Почему хэш-таблицу можно изначально оставить пустой?

    -Хэш-таблицу можно оставить пустой, так как элементы добавляются в неё по мере их обработки, и нужные пары будут найдены в процессе одной итерации по массиву.

  • Как хэш-таблица помогает избежать повторного использования одного и того же элемента?

    -Хэш-таблица помогает, так как при поиске пары для текущего элемента проверяется, существует ли разность между целевым значением и текущим элементом в хэш-таблице, но при этом текущий элемент ещё не добавлен в неё.

  • Каковы основные шаги алгоритма с использованием хэш-таблицы?

    -1. Инициализация пустой хэш-таблицы. 2. Проход по массиву. 3. Для каждого элемента проверка, есть ли в хэш-таблице элемент, равный разности между целевым значением и текущим элементом. 4. Если такой элемент найден, вернуть индексы. 5. Если не найден, добавить текущий элемент в хэш-таблицу.

Transcripts

play00:00

let's all leak code one to some the most

play00:02

popular leak code question so we're

play00:04

given an input array and some target in

play00:07

this case 9 and we want to find the two

play00:10

values in this input array that sum to 9

play00:12

so in this case it's 2 & 7 now we want

play00:15

to return the indices of these two

play00:17

values so the index of zero of the index

play00:20

of two is zero the index of 7 is 1 so we

play00:22

return 0 & 1

play00:24

we're guaranteed that there's exactly

play00:26

one solution so we don't have to worry

play00:27

about not finding a solution and we

play00:30

don't have to worry about multiple

play00:31

solutions now the most intuitive way to

play00:33

solve this problem is basically just

play00:35

check every combination of two values

play00:38

and see if they can sum up to our target

play00:40

so we start at 2 we check every

play00:43

combination we can make that includes 2

play00:45

so we scan through the remainder of the

play00:48

array 1 5 3 and check if any of those

play00:51

numbers added to 2 some store target for

play00:54

in this case none of them do so next we

play01:00

can repeat the process

play01:01

let's check every combination including

play01:04

one that sums up the target for so we

play01:06

scan through every element that comes

play01:08

after at 5 & 3 and we find that one

play01:12

added with 3 sums up to our target 4

play01:15

notice that we didn't have to check the

play01:18

values that came before 1 because we

play01:20

already checked the combination 2 & 1

play01:22

when we were up over here remember when

play01:24

we checked every combination with 2 so

play01:27

we didn't have to repeat that work down

play01:29

here we only had to check the numbers

play01:30

that came after 1

play01:32

so the runtime of this algorithm isn't

play01:34

super efficient this is basically brute

play01:36

force we're going through the entire

play01:38

array of length and and we're gonna do

play01:40

that worst case n times for each number

play01:43

this means that over all worst case time

play01:46

complexity will be O of N squared so can

play01:49

we do better now the thing to notice is

play01:51

that for each number for example 1 the

play01:56

value we're looking for is the

play01:58

difference between the target and this

play02:00

value 1 so we're looking for 4 minus 1

play02:03

which is equal to 3 so that means this

play02:06

is the only value we can add to one

play02:09

that'll equal the target so we don't

play02:11

have to check every number we just want

play02:12

to know if

play02:13

resist s-- now the easiest way we can do

play02:15

this the most efficient is by making a

play02:17

hash map of every value in our input

play02:20

array so we can instantly check if the

play02:22

value 3 exists now let's try the same

play02:27

problem except let's use a hash map this

play02:29

time now in our hash map we're going to

play02:36

be mapping each value to the index of

play02:39

each value so the index of 2 is 0 the

play02:42

index of 1 is 1 the index of 5 is 2 the

play02:44

index of 3 is 3 so let's so in our hash

play02:47

map we're going to be mapping the value

play02:49

to the index

play02:55

now we could add every value in this

play02:59

array into the hash map before we start

play03:02

iterating through it but there's

play03:03

actually an easier way to do it if we

play03:06

added the entire array into the hash map

play03:08

initially then we would get to the value

play03:10

2 first right we would want to checked

play03:12

as the difference between target 4 minus

play03:15

this value 2 which is equal to 2 exists

play03:18

in our hash map and we would find that 2

play03:21

does exist in our hash map but we're not

play03:23

allowed to reuse the same one right

play03:26

because they're both at the same index

play03:28

we can't use the same value twice so we

play03:30

would have to compare the index of our

play03:32

current 2 with the index of the 2 that's

play03:35

in our hash map there's actually an

play03:38

easier way to do this though and it's a

play03:39

little clever and let me show you how to

play03:41

do it that way so doing it this clever

play03:43

way initially we say our hash map is

play03:46

empty so we get to the value 2 first of

play03:48

all right and we want to look for the

play03:50

difference 4 minus 2 in our hash map our

play03:54

hash map is empty so we don't find 2 so

play03:57

then after we visited this element then

play04:00

we can add it to our hash map so now

play04:02

that I'm done visiting it I'm gonna move

play04:04

to the second element 1 and before I do

play04:07

that I'm gonna add this value 2 to our

play04:09

hash map and the index of this value is

play04:12

gonna be 0 now I'm at 1 I'm looking for

play04:15

4 minus 1 which is 3

play04:18

I see 3 isn't in our hash map but it

play04:21

actually is in our array so what's the

play04:23

problem well for now we're going to say

play04:25

we don't find our find

play04:27

three so we add one to our hash map the

play04:29

index of this one is one and now we move

play04:33

to the next element five we check does

play04:36

four minus five it's four minus five

play04:39

exists in our hash map that's negative

play04:42

one so no it does not then we add this

play04:44

five to our hash map and it's index

play04:47

which is two and we move to the last

play04:51

value in the array three we checked this

play04:54

four minus three e

play04:56

exists in our hash map now that's one so

play04:59

we see it does exist right right over

play05:03

here it exists the value exists and it's

play05:06

index is one so now we found our two

play05:10

values that sum to the target and we

play05:12

want to return their indexes their

play05:14

indices which are going to be one and

play05:16

three so with this algorithm we don't

play05:21

have to initialize our hash map it can

play05:23

be initially empty and then we can just

play05:25

iterate through this array in one pass

play05:28

now the reason the algorithm can work in

play05:30

that way with just one pass is this so

play05:34

let's say we had a giant array right we

play05:37

know for sure that there are two

play05:40

elements in this array that sum to our

play05:43

target right we don't know where they

play05:45

are they're at some arbitrary location

play05:47

when we visit the first one of those

play05:49

elements our hash map is only going to

play05:52

be this portion of the array it's only

play05:55

going to have the values that came

play05:57

before the first value so we're gonna

play05:59

we're gonna notice that the second value

play06:02

that can sum to the target is no is not

play06:05

going to be in our hash map yet but once

play06:08

we get to the second value our hash map

play06:11

is going to be this portion so every

play06:14

value that comes before this right so

play06:17

we're gonna be guaranteed that once we

play06:20

visit the second element that sums up to

play06:22

the target we're gonna be guaranteed

play06:24

that the first one is already in our

play06:26

hash map so we're guaranteed to find the

play06:29

solution now since we only have to

play06:31

iterate through the array once and we're

play06:34

adding each value to our hash map which

play06:36

is a constant time operation and we're

play06:38

checking if a value exists in our hash

play06:40

which is also a constant time operation

play06:43

the time complexity is going to be Big O

play06:45

of n we are using extra memory right

play06:47

that hash map isn't free so the memory

play06:50

complexity is also going to be O of n

play06:52

because we could potentially add every

play06:54

value to the hash map

play06:55

so now let's code the solution so

play06:57

remember we need a hash map right I'm

play06:58

going to call this previous map because

play07:00

it's basically every element that comes

play07:02

before the current home that every

play07:04

previous element is going to be stored

play07:05

in this map where it can be mapping the

play07:07

value to the index of that value

play07:10

so now let's iterate through every value

play07:13

in this array we need the index as well

play07:15

as the actual number so let's do it like

play07:18

this and Python before we add this to

play07:24

our map let's check if the difference

play07:26

which is equal to target minus n now

play07:30

let's check if this difference is

play07:32

already in the hash map if it is then we

play07:40

can return the solution which is going

play07:42

to be a pair of the indices so I can get

play07:49

the first index like this and the second

play07:52

index is just AI now if we don't find

play07:54

the solution then we have to update our

play07:56

hash map so for this value n I'm gonna

play08:00

say the index is I and then we're going

play08:03

to continue since we're guaranteed that

play08:05

a solution exists we don't have to

play08:07

return anything out here right but I'll

play08:09

just put a return for no reason now

play08:11

let's see if it works and it works

play08:14

perfectly so with this kind of neat

play08:16

little trick but just doing it in one

play08:18

pass you can reduce the amount of code

play08:20

you have to write and not have to worry

play08:21

about like edge cases and comparisons

play08:24

and things like that