yt neetcode lc704 binary search

URL

https://www.youtube.com/watch?v=s4DPM8ct1pI&list=WL&index=1&t=106s

Read the problem

. . .

1
00:00:00,000 –> 00:00:01,680
hey everyone welcome back and let’s

2
00:00:01,680 –> 00:00:03,439
write some more neat code today so today

3
00:00:03,439 –> 00:00:05,520
let’s solve the problem binary search

4
00:00:05,520 –> 00:00:08,080
we’re given an array of integers nums

5
00:00:08,080 –> 00:00:09,599
which are going to be sorted in

6
00:00:09,599 –> 00:00:12,160
ascending order and we’re also given a

7
00:00:12,160 –> 00:00:13,920
target integer that we’re going to look

8
00:00:13,920 –> 00:00:16,800
for if the target exists in the array

9
00:00:16,800 –> 00:00:18,720
then we can return the index of it if it

10
00:00:18,720 –> 00:00:21,439
does not exist then we return one the

11
00:00:21,439 –> 00:00:23,680
goal is to create an efficient algorithm

12
00:00:23,680 –> 00:00:26,400
that can run in log n time so what

13
00:00:26,400 –> 00:00:28,400
algorithm are we going to use well the

14
00:00:28,400 –> 00:00:30,480
problem pretty much tells you binary

15
00:00:30,480 –> 00:00:33,440
search so while this is self-explanatory

16
00:00:33,440 –> 00:00:35,760
and a pretty basic algorithm i still

17
00:00:35,760 –> 00:00:38,000
think it’s really important because a

18
00:00:38,000 –> 00:00:40,960
lot of problems kind of extend the idea

19
00:00:40,960 –> 00:00:42,800
of binary search and then make it even

20
00:00:42,800 –> 00:00:44,640
harder and this is actually a pretty

21
00:00:44,640 –> 00:00:47,039
common interview question to be asked

22
00:00:47,039 –> 00:00:49,520
some variation of binary search so this

23
00:00:49,520 –> 00:00:51,360
is a very good problem to practice and

24
00:00:51,360 –> 00:00:53,199
your goal should be able to implement

25
00:00:53,199 –> 00:00:55,840
binary search very quickly basically as

26
00:00:55,840 –> 00:00:57,760
if you were doing it in your sleep so

Drawing explanation

27
00:00:57,760 –> 00:00:59,520
i’ll try to explain this quickly but

28
00:00:59,520 –> 00:01:02,399
also in a beginner-friendly way so the

29
00:01:02,399 –> 00:01:05,199
input array is sorted the target value

30
00:01:05,199 –> 00:01:08,400
could exist anywhere in this array or it

31
00:01:08,400 –> 00:01:11,200
might not exist at all when we start we

32
00:01:11,200 –> 00:01:13,840
are considering the entire input array

33
00:01:13,840 –> 00:01:15,280
how are we going to do that well we’re

34
00:01:15,280 –> 00:01:17,600
going to have two pointers one pointer

35
00:01:17,600 –> 00:01:20,479
is going to be at the leftmost index

36
00:01:20,479 –> 00:01:22,720
which is initially index zero another

37
00:01:22,720 –> 00:01:24,400
pointer is going to be at the rightmost

38
00:01:24,400 –> 00:01:27,040
index these pointers mean that we are

39
00:01:27,040 –> 00:01:29,920
considering the entire range now if we

40
00:01:29,920 –> 00:01:33,200
could only look at one of these values

41
00:01:33,200 –> 00:01:35,119
which one should we look at should we

42
00:01:35,119 –> 00:01:38,000
look at the leftmost if we do that and

43
00:01:38,000 –> 00:01:40,159
we see that it’s not equal to the target

44
00:01:40,159 –> 00:01:42,159
then we’ve only eliminated one

45
00:01:42,159 –> 00:01:44,159
possibility and we still have to search

46
00:01:44,159 –> 00:01:47,200
all of these if we look at the rightmost

47
00:01:47,200 –> 00:01:49,119
similarly it’s not the target so we’ve

48
00:01:49,119 –> 00:01:51,040
only eliminated one possibility we still

49
00:01:51,040 –> 00:01:52,720
have to look at the rest of them but if

50
00:01:52,720 –> 00:01:54,720
we look at the midway point and

51
00:01:54,720 –> 00:01:56,240
technically either of these could be the

52
00:01:56,240 –> 00:01:58,479
midway point the way we calculate it

53
00:01:58,479 –> 00:02:00,719
though is going to be literally taking

54
00:02:00,719 –> 00:02:02,960
the left and right indexes and dividing

55
00:02:02,960 –> 00:02:04,960
them by two which i think will lead us

56
00:02:04,960 –> 00:02:07,680
to this position but approximately the

57
00:02:07,680 –> 00:02:10,479
halfway point why should we look here

58
00:02:10,479 –> 00:02:12,480
well we can compare it to the target

59
00:02:12,480 –> 00:02:14,879
it’s not equal to the target so what

60
00:02:14,879 –> 00:02:16,480
does that tell us have we only

61
00:02:16,480 –> 00:02:19,440
eliminated one possibility no because

62
00:02:19,440 –> 00:02:23,120
remember the input array is sorted so if

63
00:02:23,120 –> 00:02:25,520
this is not equal to the target we

64
00:02:25,520 –> 00:02:28,000
should also ask is it smaller than the

65
00:02:28,000 –> 00:02:30,480
target or is it larger than the target

66
00:02:30,480 –> 00:02:32,239
in this case it’s smaller than the

67
00:02:32,239 –> 00:02:34,560
target so if this is smaller than the

68
00:02:34,560 –> 00:02:37,519
target then everything to the left of it

69
00:02:37,519 –> 00:02:40,080
is also going to be smaller than the

70
00:02:40,080 –> 00:02:42,239
target so this was our midway point

71
00:02:42,239 –> 00:02:45,120
we’ll call it m and we found that it’s

72
00:02:45,120 –> 00:02:46,959
smaller than the target so we can

73
00:02:46,959 –> 00:02:49,680
eliminate these three values from

74
00:02:49,680 –> 00:02:52,000
consideration everything over here how

75
00:02:52,000 –> 00:02:53,760
are we gonna you know represent that in

76
00:02:53,760 –> 00:02:55,760
code well we’re gonna take this left

77
00:02:55,760 –> 00:02:58,480
pointer and then shift it to be m

78
00:02:58,480 –> 00:03:01,280
plus one so now our left pointer is

79
00:03:01,280 –> 00:03:03,680
gonna be over here this represents

80
00:03:03,680 –> 00:03:05,840
possible range of solutions is going to

81
00:03:05,840 –> 00:03:08,400
lie within you know these two pointers

82
00:03:08,400 –> 00:03:10,319
so at this point we’re just going to

83
00:03:10,319 –> 00:03:12,400
repeat the algorithm repeat what i

84
00:03:12,400 –> 00:03:14,560
pretty much just did now if we take

85
00:03:14,560 –> 00:03:16,720
these two add them together divide by

86
00:03:16,720 –> 00:03:19,200
two the middle is going to be over here

87
00:03:19,200 –> 00:03:20,800
so then we’re going to check is this

88
00:03:20,800 –> 00:03:22,159
equal to the target that we’re looking

89
00:03:22,159 –> 00:03:25,120
for in this case yes it is so now we can

90
00:03:25,120 –> 00:03:27,440
return the index because that’s what we

91
00:03:27,440 –> 00:03:29,280
were trying to do we can return m

92
00:03:29,280 –> 00:03:30,720
whatever it happened to be i think it’s

93
00:03:30,720 –> 00:03:33,280
4 in this case so that is pretty much

94
00:03:33,280 –> 00:03:36,480
the idea of binary search okay so now

95
00:03:36,480 –> 00:03:38,720
the time complexity if you know binary

96
00:03:38,720 –> 00:03:40,480
search you already know that it runs in

97
00:03:40,480 –> 00:03:42,799
log in time but let’s quickly understand

98
00:03:42,799 –> 00:03:44,560
why so we’re not considering this

99
00:03:44,560 –> 00:03:47,120
example anymore but suppose we had 16

100
00:03:47,120 –> 00:03:49,840
values in the input array every time we

101
00:03:49,840 –> 00:03:53,120
go to the midway point we either find

102
00:03:53,120 –> 00:03:55,360
the target but if we don’t find the

103
00:03:55,360 –> 00:03:56,959
target we know we’re at least going to

104
00:03:56,959 –> 00:04:00,159
eliminate half of the possibilities so

105
00:04:00,159 –> 00:04:02,239
we would eliminate this down to a now

106
00:04:02,239 –> 00:04:04,239
we’re only looking at eight values we

107
00:04:04,239 –> 00:04:06,159
still don’t find the result we keep

108
00:04:06,159 –> 00:04:09,200
dividing it by two make it two remaining

109
00:04:09,200 –> 00:04:12,000
and then finally there would only be

110
00:04:12,000 –> 00:04:15,040
one value remaining and either that’s

111
00:04:15,040 –> 00:04:16,959
going to be the target or it’s not going

112
00:04:16,959 –> 00:04:18,639
to be the target and then we’re pretty

113
00:04:18,639 –> 00:04:20,798
much done with the algorithm anyway so

114
00:04:20,798 –> 00:04:23,840
the question is if we have a while loop

115
00:04:23,840 –> 00:04:26,400
the while loop is going to run as many

116
00:04:26,400 –> 00:04:29,680
times as we can divide the length of the

117
00:04:29,680 –> 00:04:32,720
input array by two how many times can we

118
00:04:32,720 –> 00:04:34,880
divide it by two well if you remember

119
00:04:34,880 –> 00:04:37,440
from your math class that is a math

120
00:04:37,440 –> 00:04:41,919
equation called log base two of n this

121
00:04:41,919 –> 00:04:44,320
evaluates to how many times can we

122
00:04:44,320 –> 00:04:48,000
divide n by 2. and you know suppose it

123
00:04:48,000 –> 00:04:50,400
evaluates to be x that’s equivalent to

124
00:04:50,400 –> 00:04:52,320
saying that 2 to the power of x is going

125
00:04:52,320 –> 00:04:54,000
to be equal to n okay but this is too

126
00:04:54,000 –> 00:04:55,759
much math maybe you don’t even care but

127
00:04:55,759 –> 00:04:58,080
that’s pretty much the idea that’s why

128
00:04:58,080 –> 00:05:00,639
our loop is going to run x times which

129
00:05:00,639 –> 00:05:02,720
is going to be equal to log n so it’s

130
00:05:02,720 –> 00:05:05,440
not a big o of n algorithm it’s a log

131
00:05:05,440 –> 00:05:09,360
base 2 n algorithm which is much much

132
00:05:09,360 –> 00:05:10,560
more efficient

Coding explanation

133
00:05:10,560 –> 00:05:13,280
okay so now let’s code it up and like i

134
00:05:13,280 –> 00:05:14,880
did in the drawing initially we’re

135
00:05:14,880 –> 00:05:18,080
considering the entire input array as

136
00:05:18,080 –> 00:05:20,560
our search area so our left pointer is

137
00:05:20,560 –> 00:05:22,240
going to be at zero our right pointer is

138
00:05:22,240 –> 00:05:24,080
going to be at the last index which is

139
00:05:24,080 –> 00:05:26,560
just the length of the array minus 1.

140
00:05:26,560 –> 00:05:28,960
now we want to continue going until

141
00:05:28,960 –> 00:05:31,440
there’s no more possibilities left or we

142
00:05:31,440 –> 00:05:33,520
have maybe found the result so the way

143
00:05:33,520 –> 00:05:35,199
to do that is to basically say that

144
00:05:35,199 –> 00:05:37,759
while our left pointer is less than or

145
00:05:37,759 –> 00:05:40,240
equal to our right pointer because i

146
00:05:40,240 –> 00:05:41,680
didn’t show it in the drawing picture

147
00:05:41,680 –> 00:05:43,840
but suppose we just had a very small

148
00:05:43,840 –> 00:05:45,360
input array just to illustrate the

149
00:05:45,360 –> 00:05:47,199
example our left and right pointers

150
00:05:47,199 –> 00:05:49,840
would both point here our midpointer

151
00:05:49,840 –> 00:05:52,880
would also point here but suppose our

152
00:05:52,880 –> 00:05:55,759
target is actually equal to two okay

153
00:05:55,759 –> 00:05:58,080
we’d say okay this is too small for our

154
00:05:58,080 –> 00:06:00,479
target so we’re gonna set our left

155
00:06:00,479 –> 00:06:04,000
pointer to be equal to mid plus one so

156
00:06:04,000 –> 00:06:06,240
that means our left pointer would be one

157
00:06:06,240 –> 00:06:08,639
and our right pointer would be zero that

158
00:06:08,639 –> 00:06:10,560
basically means our left pointer has

159
00:06:10,560 –> 00:06:12,639
crossed our right pointer and that’s how

160
00:06:12,639 –> 00:06:15,120
you know that we have no more values

161
00:06:15,120 –> 00:06:17,039
left to search we did not find the

162
00:06:17,039 –> 00:06:19,360
result so that’s why we’re doing less

163
00:06:19,360 –> 00:06:21,280
than or equal if they’re both equal

164
00:06:21,280 –> 00:06:22,880
though if they’re both pointing at this

165
00:06:22,880 –> 00:06:24,800
value that means we haven’t looked at

166
00:06:24,800 –> 00:06:27,520
this value yet so that’s the idea so

167
00:06:27,520 –> 00:06:28,880
each iteration of the loop we’re just

168
00:06:28,880 –> 00:06:30,560
going to find the midway point which we

169
00:06:30,560 –> 00:06:34,479
can get by taking l plus r and dividing

170
00:06:34,479 –> 00:06:38,400
by two if the value that this index is

171
00:06:38,400 –> 00:06:41,199
at is greater than the target then we

172
00:06:41,199 –> 00:06:43,280
want to look at all values to the left

173
00:06:43,280 –> 00:06:44,880
of it so we’re gonna take our right

174
00:06:44,880 –> 00:06:47,199
pointer and set it to m minus one we

175
00:06:47,199 –> 00:06:49,360
wanna look at all values to the left

176
00:06:49,360 –> 00:06:51,840
we’re basically shrinking our criteria

177
00:06:51,840 –> 00:06:54,880
and in the other case else if that num

178
00:06:54,880 –> 00:06:56,880
is smaller than our target then we’re

179
00:06:56,880 –> 00:06:58,319
gonna do the opposite we’re gonna set

180
00:06:58,319 –> 00:07:00,960
left equal to mid plus one just like in

181
00:07:00,960 –> 00:07:03,440
the drawing explanation the last case is

182
00:07:03,440 –> 00:07:05,680
if neither of those are true that must

183
00:07:05,680 –> 00:07:07,840
mean that we found the target if it’s

184
00:07:07,840 –> 00:07:10,080
not greater and not smaller that means

185
00:07:10,080 –> 00:07:12,000
it must be equal that means we can

186
00:07:12,000 –> 00:07:14,639
return m which is the result but if we

187
00:07:14,639 –> 00:07:16,639
went through every iteration of the loop

188
00:07:16,639 –> 00:07:18,560
and we didn’t find the result then

189
00:07:18,560 –> 00:07:21,199
outside of it we are told that we should

190
00:07:21,199 –> 00:07:23,280
return negative one to indicate we did

191
00:07:23,280 –> 00:07:25,680
not find a result so that’s the solution

192
00:07:25,680 –> 00:07:27,520
let’s run it to make sure that it works

193
00:07:27,520 –> 00:07:29,280
and as you can see on the left yes it

194
00:07:29,280 –> 00:07:31,120
does and it’s very efficient there’s one

195
00:07:31,120 –> 00:07:32,720
more thing though that i want to mention

196
00:07:32,720 –> 00:07:34,800
to you which probably won’t come up in

197
00:07:34,800 –> 00:07:36,639
your interview to be honest it’s never

198
00:07:36,639 –> 00:07:38,880
come up in mine but there’s actually one

199
00:07:38,880 –> 00:07:41,120
little bug here i mean technically the

200
00:07:41,120 –> 00:07:43,440
bug doesn’t exist in python because

201
00:07:43,440 –> 00:07:44,479
python

202
00:07:44,479 –> 00:07:46,560
integers are unbounded they can pretty

203
00:07:46,560 –> 00:07:48,960
much be infinitely large but in most

204
00:07:48,960 –> 00:07:51,599
languages like java and c plus plus you

205
00:07:51,599 –> 00:07:54,400
might encounter an overflow because

206
00:07:54,400 –> 00:07:57,440
suppose we had a very large input array

207
00:07:57,440 –> 00:08:00,639
and then these two integers were very

208
00:08:00,639 –> 00:08:04,000
close to the 32-bit integer max which is

209
00:08:04,000 –> 00:08:05,120
something like

210
00:08:05,120 –> 00:08:07,840
2 to the power of 31 suppose they were

211
00:08:07,840 –> 00:08:09,599
both close to that then adding them

212
00:08:09,599 –> 00:08:12,879
together would possibly overflow and

213
00:08:12,879 –> 00:08:15,599
then we would get the wrong result in

214
00:08:15,599 –> 00:08:16,400
this

215
00:08:16,400 –> 00:08:18,800
value so possibly your interviewer might

216
00:08:18,800 –> 00:08:20,479
ask you something about that and how

217
00:08:20,479 –> 00:08:22,479
would you go about fixing that well

218
00:08:22,479 –> 00:08:24,639
there’s actually a way to do that we can

219
00:08:24,639 –> 00:08:26,879
still calculate the midway point between

220
00:08:26,879 –> 00:08:28,879
left and right without adding them

221
00:08:28,879 –> 00:08:31,360
together because we can take the

222
00:08:31,360 –> 00:08:34,000
distance between them we can get the

223
00:08:34,000 –> 00:08:36,479
distance between them by taking right

224
00:08:36,479 –> 00:08:40,958
minus left and then dividing that by two

225
00:08:40,958 –> 00:08:42,958
right that will give us half of the

226
00:08:42,958 –> 00:08:45,519
distance between them and we can take

227
00:08:45,519 –> 00:08:49,279
that and add it to the left index

228
00:08:49,279 –> 00:08:51,200
because if this is halfway of the

229
00:08:51,200 –> 00:08:53,120
distance between them and then this is

230
00:08:53,120 –> 00:08:55,680
the left index by adding these together

231
00:08:55,680 –> 00:08:58,080
we are getting the midway point this is

232
00:08:58,080 –> 00:09:00,000
just a way to do the exact same

233
00:09:00,000 –> 00:09:03,440
calculation but this way it will never

234
00:09:03,440 –> 00:09:05,760
overflow because right is always going

235
00:09:05,760 –> 00:09:08,320
to be greater than or equal to left and

236
00:09:08,320 –> 00:09:09,920
in this case we’re not adding them

237
00:09:09,920 –> 00:09:11,680
together we’re subtracting them so this

238
00:09:11,680 –> 00:09:13,680
will always be positive or it will be

239
00:09:13,680 –> 00:09:16,240
zero so i’ll run it and it does work

240
00:09:16,240 –> 00:09:18,399
pretty much exactly the same as you can

241
00:09:18,399 –> 00:09:19,920
see on the left but this is just

242
00:09:19,920 –> 00:09:21,360
something i think a lot of people don’t

243
00:09:21,360 –> 00:09:22,800
talk about and actually i pretty much

244
00:09:22,800 –> 00:09:24,720
never implement it this way people have

245
00:09:24,720 –> 00:09:26,320
actually mentioned that in my comments

246
00:09:26,320 –> 00:09:27,680
before which is kind of why i’m talking

247
00:09:27,680 –> 00:09:29,200
about it today but i really hope that

248
00:09:29,200 –> 00:09:31,200
this was helpful if it was please like

249
00:09:31,200 –> 00:09:32,640
and subscribe it really supports the

250
00:09:32,640 –> 00:09:34,240
channel a lot consider checking out my

251
00:09:34,240 –> 00:09:35,600
patreon where you can further support

252
00:09:35,600 –> 00:09:37,440
the channel and hopefully i’ll see you

253
00:09:37,440 –> 00:09:41,040
pretty soon thanks for watching

中文翻译

Read the problem

1
00:00:00,000 –> 00:00:01,680
嘿大家欢迎回来,今天让我们

2
00:00:01,680 –> 00:00:03,439
写一些更简洁的代码,所以今天

3
00:00:03,439 –> 00:00:05,520
让我们解决二分搜索问题,

4
00:00:05,520 –> 00:00:08,080
我们给出了一个整数数组 nums ,

5
00:00:08,080 –> 00:00:09,599
这些整数将按

6
00:00:09,599 –> 00:00:12,160
升序排序,我们还给出了一个

7
00:00:12,160 –> 00:00:13,920
目标整数,我们’ 我们将

8
00:00:13,920 –> 00:00:16,800
查找目标是否存在于数组中,

9
00:00:16,800 –> 00:00:18,720
然后我们可以返回它的索引,如果它

10
00:00:18,720 –> 00:00:21,439
不存在,那么我们返回一个

11
00:00:21,439 –> 00:00:23,680
目标是创建一种

12
00:00:23,680 –> 00:00:26,400
可以在 log n 时间内运行的高效算法,那么

13
00:00:26,400 –> 00:00:28,400
我们要采用什么算法 很好地使用这个

14
00:00:28,400 –> 00:00:30,480
问题几乎告诉你二分

15
00:00:30,480 –> 00:00:33,440
搜索,所以虽然这是不言自明的,

16
00:00:33,440 –> 00:00:35,760
也是一个非常基本的算法,但我仍然

17
00:00:35,760 –> 00:00:38,000
认为它非常重要,因为

18
00:00:38,000 –> 00:00:40,960
很多问题都扩展了

19
00:00:40,960 –> 00:00:42,800
二分搜索的想法,然后使它变得更加

20
00:00:42,800 –> 00:00:44,640
困难,这 实际上是一个非常

21
00:00:44,640 –> 00:00:47,039
常见的面试问题,会被问到

22
00:00:47,039 –> 00:00:49,520
一些二分搜索的变体,所以这

23
00:00:49,520 –> 00:00:51,360
是一个非常好的练习问题,

24
00:00:51,360 –> 00:00:53,199
你的目标应该能够

25
00:00:53,199 –> 00:00:55,840
非常快地实现二分搜索,基本上就像

26
00:00:55,840 –> 00:00:57,760
你在睡觉时做的那样,所以

Drawing explanation

27
00:00:57,760 –> 00:00:59,520
我会 尝试

28
00:00:59,520 –> 00:01:02,399
以初学者友好的方式快速解释这一点,以便对

29
00:01:02,399 –> 00:01:05,199
输入数组进行排序,目标值

30
00:01:05,199 –> 00:01:08,400
可能存在于该数组中的任何位置,或者

31
00:01:08,400 –> 00:01:11,200
可能根本不存在,当我们开始时,我们

32
00:01:11,200 –> 00:01:13,840
正在考虑整个输入数组,

33
00:01:13,840 –> 00:01:15,280
我们将如何 做得好,我们

34
00:01:15,280 –> 00:01:17,600
将有两个指针,一个指针

35
00:01:17,600 –> 00:01:20,479
将位于最左边的索引,

36
00:01:20,479 –> 00:01:22,720
最初索引为零,另一个

37
00:01:22,720 –> 00:01:24,400
指针将位于最右边的索引,

38
00:01:24,400 –> 00:01:27,040
这些指针意味着我们

39
00:01:27,040 –> 00:01:29,920
现在正在考虑整个范围,如果我们

40
00:01:29,920 –> 00:01:33,200
可以的话 只看这些值之一,

41
00:01:33,200 –> 00:01:35,119
我们应该看哪一个,我们应该

42
00:01:35,119 –> 00:01:38,000
看最左边的值吗?如果我们这样做,并且

43
00:01:38,000 –> 00:01:40,159
发现它不等于目标,

44
00:01:40,159 –> 00:01:42,159
那么我们只消除了一种

45
00:01:42,159 –> 00:01:44,159
可能性,我们仍然需要搜索

46
00:01:44,159 –> 00:01:47,200
所有这些值 如果我们看最右边的

47
00:01:47,200 –> 00:01:49,119
类似,它不是目标,所以我们

48
00:01:49,119 –> 00:01:51,040
只消除了一种可能性,我们仍然

49
00:01:51,040 –> 00:01:52,720
必须看其余的,但如果

50
00:01:52,720 –> 00:01:54,720
我们看中间点,从

51
00:01:54,720 –> 00:01:56,240
技术上讲,其中任何一个都可能是

52
00:01:56,240 –> 00:01:58,479
我们的中间点 计算它

53
00:01:58,479 –> 00:02:00,719
实际上是取

54
00:02:00,719 –> 00:02:02,960
左索引和右索引并将

55
00:02:02,960 –> 00:02:04,960
它们除以二,我认为这将导致我们

56
00:02:04,960 –> 00:02:07,680
到达这个位置,但大约是

57
00:02:07,680 –> 00:02:10,479
中间点为什么我们应该在这里

58
00:02:10,479 –> 00:02:12,480
仔细观察我们可以将它与

59
00:02:12,480 –> 00:02:14,879
它不等于的目标进行比较 目标那么这

60
00:02:14,879 –> 00:02:16,480
告诉我们我们是否

61
00:02:16,480 –> 00:02:19,440
只消除了一种可能性“否”,因为

62
00:02:19,440 –> 00:02:23,120
记住输入数组是排序的,所以如果

63
00:02:23,120 –> 00:02:25,520
它不等于目标,我们

64
00:02:25,520 –> 00:02:28,000
还应该问它是小于

65
00:02:28,000 –> 00:02:30,480
目标还是大

66
00:02:30,480 –> 00:02:32,239
于此中的目标 如果它小于

67
00:02:32,239 –> 00:02:34,560
目标,那么如果它小于

68
00:02:34,560 –> 00:02:37,519
目标,那么它左边的所有内容

69
00:02:37,519 –> 00:02:40,080
也将小于

70
00:02:40,080 –> 00:02:42,239
目标,所以这是我们的中点,

71
00:02:42,239 –> 00:02:45,120
我们将其称为 m,我们发现它

72
00:02:45,120 –> 00:02:46,959
小于 目标,这样我们就可以

73
00:02:46,959 –> 00:02:49,680
从考虑这里的所有内容中消除这三个值,

74
00:02:49,680 –> 00:02:52,000

75
00:02:52,000 –> 00:02:53,760
我们如何知道在代码中表示,

76
00:02:53,760 –> 00:02:55,760
我们将采用这个左

77
00:02:55,760 –> 00:02:58,480
指针,然后将其移动为 m

78
00:02:58,480 –> 00:03:01,280
加一,所以现在我们的左指针

79
00:03:01,280 –> 00:03:03,680
将结束 这里这表示

80
00:03:03,680 –> 00:03:05,840
可能的解决方案范围将

81
00:03:05,840 –> 00:03:08,400
位于您知道这两个指针的范围内,

82
00:03:08,400 –> 00:03:10,319
因此此时我们只需

83
00:03:10,319 –> 00:03:12,400
重复该算法,重复我

84
00:03:12,400 –> 00:03:14,560
现在所做的,如果我们将这

85
00:03:14,560 –> 00:03:16,720
两个值相加,然后除以

86
00:03:16,720 –> 00:03:19,200
二 中间将在这里,

87
00:03:19,200 –> 00:03:20,800
所以我们将检查这是否

88
00:03:20,800 –> 00:03:22,159
等于我们

89
00:03:22,159 –> 00:03:25,120
在本例中寻找的目标,是的,所以现在我们可以

90
00:03:25,120 –> 00:03:27,440
返回索引,因为这就是我们

91
00:03:27,440 –> 00:03:29,280
想要做的,我们可以 返回 m

92
00:03:29,280 –> 00:03:30,720
无论它发生了什么我认为

93
00:03:30,720 –> 00:03:33,280
在这种情况下它是 4 所以这几乎是

94
00:03:33,280 –> 00:03:36,480
二分搜索的想法好吧所以现在

95
00:03:36,480 –> 00:03:38,720
时间复杂度如果你知道二分

96
00:03:38,720 –> 00:03:40,480
搜索你已经知道它在

97
00:03:40,480 –> 00:03:42,799
登录时间内运行但让我们快速理解

98
00:03:42,799 –> 00:03:44,560
为什么 所以我们不再考虑这个

99
00:03:44,560 –> 00:03:47,120
例子,但假设

100
00:03:47,120 –> 00:03:49,840
每次我们到达中点时,输入数组中有 16 个值,

101
00:03:49,840 –> 00:03:53,120
我们要么找到

102
00:03:53,120 –> 00:03:55,360
目标,但如果找不到

103
00:03:55,360 –> 00:03:56,959
目标,我们知道我们至少会去

104
00:03:56,959 –> 00:04:00,159
消除一半的可能性,所以

105
00:04:00,159 –> 00:04:02,239
我们将消除这种情况现在

106
00:04:02,239 –> 00:04:04,239
我们只查看八个值我们

107
00:04:04,239 –> 00:04:06,159
仍然找不到结果我们继续将

108
00:04:06,159 –> 00:04:09,200
其除以二使其剩下两个

109
00:04:09,200 –> 00:04:12,000
然后最后只剩下

110
00:04:12,000 –> 00:04:15,040
一个值 要么这

111
00:04:15,040 –> 00:04:16,959
将成为目标,要么它不会

112
00:04:16,959 –> 00:04:18,639
成为目标,然后我们就基本上

113
00:04:18,639 –> 00:04:20,798
完成了算法,所以

114
00:04:20,798 –> 00:04:23,840
问题是,如果我们有一个 while 循环,那么

115
00:04:23,840 –> 00:04:26,400
while 循环将运行与

116
00:04:26,400 –> 00:04:29,680
我们一样多的次数 可以将

117
00:04:29,680 –> 00:04:32,720
输入数组的长度除以二

118
00:04:32,720 –> 00:04:34,880
如果你记得

119
00:04:34,880 –> 00:04:37,440
数学课上有一个数学

120
00:04:37,440 –> 00:04:41,919
方程,称为对数以 n 为底的二,那么我们可以将它除以多少次,它的

121
00:04:41,919 –> 00:04:44,320
计算结果是我们可以

122
00:04:44,320 –> 00:04:48,000
将 n 除以 2 多少次 你知道,假设它的

123
00:04:48,000 –> 00:04:50,400
计算结果是 x,这相当于

124
00:04:50,400 –> 00:04:52,320
说 2 的 x 次方将

125
00:04:52,320 –> 00:04:54,000
等于 n 好吧,但这

126
00:04:54,000 –> 00:04:55,759
太多了,也许你甚至不关心,但这

127
00:04:55,759 –> 00:04:58,080
就是为什么的想法。

128
00:04:58,080 –> 00:05:00,639
我们的循环将运行 x 次,这

129
00:05:00,639 –> 00:05:02,720
将等于 log n,所以它

130
00:05:02,720 –> 00:05:05,440
不是一个很大的 o of n 算法,而是一个以 log

131
00:05:05,440 –> 00:05:09,360
为底的 2 n 算法,

132
00:05:09,360 –> 00:05:10,560
效率要高得多,

Coding explanation

133
00:05:10,560 –> 00:05:13,280
好吧,现在让我们像我一样对其进行编码

134
00:05:13,280 –> 00:05:14,880
在图中,最初我们将

135
00:05:14,880 –> 00:05:18,080
整个输入数组视为

136
00:05:18,080 –> 00:05:20,560
我们的搜索区域,因此我们的左指针

137
00:05:20,560 –> 00:05:22,240
将为零,我们的右指针

138
00:05:22,240 –> 00:05:24,080
将位于最后一个索引,

139
00:05:24,080 –> 00:05:26,560
即数组的长度减 1。

140
00:05:26,560 –> 00:05:28,960
现在我们 想要继续下去,直到

141
00:05:28,960 –> 00:05:31,440
没有更多的可能性,或者我们

142
00:05:31,440 –> 00:05:33,520
可能找到了结果,所以

143
00:05:33,520 –> 00:05:35,199
这样做的方法基本上是说,

144
00:05:35,199 –> 00:05:37,759
虽然我们的左指针小于或

145
00:05:37,759 –> 00:05:40,240
等于我们的右指针,因为我

146
00:05:40,240 –> 00:05:41,680
没有在 画图

147
00:05:41,680 –> 00:05:43,840
但是假设我们只有一个非常小的

148
00:05:43,840 –> 00:05:45,360
输入数组只是为了说明这个

149
00:05:45,360 –> 00:05:47,199
例子我们的左指针和右指针

150
00:05:47,199 –> 00:05:49,840
都会指向这里我们的中指针

151
00:05:49,840 –> 00:05:52,880
也会指向这里但是假设我们的

152
00:05:52,880 –> 00:05:55,759
目标实际上等于二好吧

153
00:05:55,759 –> 00:05:58,080
我们会说好吧这也是 对于我们的目标来说很小,

154
00:05:58,080 –> 00:06:00,479
所以我们将把左

155
00:06:00,479 –> 00:06:04,000
指针设置为等于 mid 加一,

156
00:06:04,000 –> 00:06:06,240
这意味着我们的左指针将是 1

157
00:06:06,240 –> 00:06:08,639
,我们的右指针将是 0,这

158
00:06:08,639 –> 00:06:10,560
基本上意味着我们的左指针已经

159
00:06:10,560 –> 00:06:12,639
穿过了我们的右指针,这就是如何

160
00:06:12,639 –> 00:06:15,120
你知道我们没有更多的值可供

161
00:06:15,120 –> 00:06:17,039
搜索,我们没有找到

162
00:06:17,039 –> 00:06:19,360
结果,所以这就是为什么

163
00:06:19,360 –> 00:06:21,280
如果它们都相等,我们就会做小于或等于,

164
00:06:21,280 –> 00:06:22,880
但如果它们都指向这个

165
00:06:22,880 –> 00:06:24,800
值,这意味着我们还没有 查看了

166
00:06:24,800 –> 00:06:27,520
这个值,这就是想法,因此

167
00:06:27,520 –> 00:06:28,880
循环的每次迭代我们只需

168
00:06:28,880 –> 00:06:30,560
找到中间点,

169
00:06:30,560 –> 00:06:34,479

170
00:06:34,479 –> 00:06:38,400
如果该索引所在的值

171
00:06:38,400 –> 00:06:41,199
大于 目标然后我们

172
00:06:41,199 –> 00:06:43,280
想要查看它左侧的所有值,

173
00:06:43,280 –> 00:06:44,880
因此我们将使用右

174
00:06:44,880 –> 00:06:47,199
指针并将其设置为 m 减一我们

175
00:06:47,199 –> 00:06:49,360
想要查看左侧的所有值

176
00:06:49,360 –> 00:06:51,840
我们基本上缩小了我们的标准,

177
00:06:51,840 –> 00:06:54,880
而在另一个 否则,如果该 num

178
00:06:54,880 –> 00:06:56,880
小于我们的目标,那么我们

179
00:06:56,880 –> 00:06:58,319
将做相反的事情,我们将设置

180
00:06:58,319 –> 00:07:00,960
left 等于 mid 加一,就像

181
00:07:00,960 –> 00:07:03,440
绘图中的解释一样,最后一种情况是,

182
00:07:03,440 –> 00:07:05,680
如果这两个都不成立,那一定

183
00:07:05,680 –> 00:07:07,840
意味着我们 找到目标,如果它

184
00:07:07,840 –> 00:07:10,080
不大于也不小于,这意味着

185
00:07:10,080 –> 00:07:12,000
它必须相等,这意味着我们可以

186
00:07:12,000 –> 00:07:14,639
返回 m,它是结果,但如果我们

187
00:07:14,639 –> 00:07:16,639
经历了循环的每次迭代

188
00:07:16,639 –> 00:07:18,560
并且我们没有找到结果,那么

189
00:07:18,560 –> 00:07:21,199
我们就在它之外 告诉我们应该

190
00:07:21,199 –> 00:07:23,280
返回负数以表明我们

191
00:07:23,280 –> 00:07:25,680
没有找到结果,这就是解决方案

192
00:07:25,680 –> 00:07:27,520
让我们运行它以确保它有效,

193
00:07:27,520 –> 00:07:29,280
正如您在左侧看到的那样,是

194
00:07:29,280 –> 00:07:31,120
的,它确实有效,而且非常有效,

195
00:07:31,120 –> 00:07:32,720
但还有一件事我 我想向

196
00:07:32,720 –> 00:07:34,800
你提一下,这可能不会在

197
00:07:34,800 –> 00:07:36,639
你的面试中出现,说实话,它从来没有

198
00:07:36,639 –> 00:07:38,880
出现在我的面试中,但这里实际上有一个

199
00:07:38,880 –> 00:07:41,120
小错误,我的意思是从技术上讲,这个

200
00:07:41,120 –> 00:07:43,440
错误在 python 中不存在,因为

201
00:07:43,440 –> 00:07:44,479
python

202
00:07:44,479 –> 00:07:46,560
整数是无界的,它们可以很漂亮。

203
00:07:46,560 –> 00:07:48,960
很多是无限大的,但在大多数

204
00:07:48,960 –> 00:07:51,599
语言中,如 java 和 c plus plus,你

205
00:07:51,599 –> 00:07:54,400
可能会遇到溢出,因为

206
00:07:54,400 –> 00:07:57,440
假设我们有一个非常大的输入数组

207
00:07:57,440 –> 00:08:00,639
,然后这两个整数非常

208
00:08:00,639 –> 00:08:04,000
接近 32 位整数最大值,类似于

209
00:08:04,000 –> 00:08:05,120

210
00:08:05,120 –> 00:08:07,840
2 的 31 的幂假设它们都

211
00:08:07,840 –> 00:08:09,599
接近这个值,那么将它们加

212
00:08:09,599 –> 00:08:12,879
在一起可能会溢出,

213
00:08:12,879 –> 00:08:15,599
然后我们会得到

214
00:08:15,599 –> 00:08:16,400
这个

215
00:08:16,400 –> 00:08:18,800
值的错误结果,所以你的面试官可能会

216
00:08:18,800 –> 00:08:20,479
问你一些关于这个的问题,

217
00:08:20,479 –> 00:08:22,479
你会如何解决这个问题,

218
00:08:22,479 –> 00:08:24,639
实际上有一个 为此,我们

219
00:08:24,639 –> 00:08:26,879
仍然可以计算

220
00:08:26,879 –> 00:08:28,879
左和右之间的中点,而无需将它们加

221
00:08:28,879 –> 00:08:31,360
在一起,因为我们可以计算

222
00:08:31,360 –> 00:08:34,000
它们之间的距离,我们可以

223
00:08:34,000 –> 00:08:36,479
通过右

224
00:08:36,479 –> 00:08:40,958
减左,然后除以

225
00:08:40,958 –> 00:08:42,958
右二来得到它们之间的距离

226
00:08:42,958 –> 00:08:45,519
它们之间距离的一半,我们可以将

227
00:08:45,519 –> 00:08:49,279
其添加到左侧索引,

228
00:08:49,279 –> 00:08:51,200
因为如果这是

229
00:08:51,200 –> 00:08:53,120
它们之间距离的一半,那么这是

230
00:08:53,120 –> 00:08:55,680
左侧索引,通过将它们加在一起,

231
00:08:55,680 –> 00:08:58,080
我们得到中点,这

232
00:08:58,080 –> 00:09:00,000
只是一种方法 进行完全相同的

233
00:09:00,000 –> 00:09:03,440
计算,但这样它就永远不会

234
00:09:03,440 –> 00:09:05,760
溢出,因为右总是

235
00:09:05,760 –> 00:09:08,320
大于或等于左,

236
00:09:08,320 –> 00:09:09,920
在这种情况下,我们不会将它们加

237
00:09:09,920 –> 00:09:11,680
在一起,而是将它们相减,所以这

238
00:09:11,680 –> 00:09:13,680
将始终是正数,或者它 将

239
00:09:13,680 –> 00:09:16,240
为零,所以我将运行它,它的工作原理与

240
00:09:16,240 –> 00:09:18,399

241
00:09:18,399 –> 00:09:19,920
在左侧看到的几乎完全相同,但这只是

242
00:09:19,920 –> 00:09:21,360
我认为很多人不会

243
00:09:21,360 –> 00:09:22,800
谈论的事情,实际上我几乎

244
00:09:22,800 –> 00:09:24,720
从未实现过它 人们

245
00:09:24,720 –> 00:09:26,320
实际上在我之前的评论中提到过这一点,

246
00:09:26,320 –> 00:09:27,680
这就是我

247
00:09:27,680 –> 00:09:29,200
今天谈论它的原因,但我真的希望

248
00:09:29,200 –> 00:09:31,200
这会有所帮助,如果它是请喜欢

249
00:09:31,200 –> 00:09:32,640
并订阅它真的支持该

250
00:09:32,640 –> 00:09:34,240
频道,请考虑查看我的

251
00:09:34,240 –> 00:09:35,600
赞助人在哪里 您可以进一步支持

252
00:09:35,600 –> 00:09:37,440
该频道,希望很快就能见到您,

253
00:09:37,440 –> 00:09:41,040
感谢您的观看