-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfindMinimumInRotatedSortedArray.py
More file actions
268 lines (207 loc) Β· 7.03 KB
/
findMinimumInRotatedSortedArray.py
File metadata and controls
268 lines (207 loc) Β· 7.03 KB
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#neetcode!7
class Solution(object):
def findMin(self, nums):
l, r = 0, len(nums) - 1
result = nums[0]
# Checking if the loop is sorted, so if the left index's element is shorter than the right index's element it means it is sorted and then we break the loop
while l <= r:
if nums[l] < nums[r]:
result = min(result, nums[l])
break
# Now in this loop we set a middle element and check if the middle elemnet is greater than or equal to the left most element and if it is we know that the minimum element is at the right side of the array if not we check the left side of the array
mid = (l + r) // 2
result = min(result, nums[mid])
if nums[mid] >= nums[l]:
l = mid + 1
else:
r = mid - 1
return result
if __name__ == "__main__":
nums = [3,4,5,6,1,2]
sol = Solution()
answer = sol.findMin(nums)
print(answer)
# I'm gonna break this thing **line by line**, **concept by concept**, as if I'm explaining it to someone who's totally new. You ready? Let's roll! π
# ---
# ## π¦ What's This Code Doing?
# This code is trying to **find the smallest number** (minimum) in a **rotated sorted array**.
# Example of a rotated sorted array:
# ```
# Original sorted array: [1, 2, 3, 4, 5, 6, 7]
# Rotated sorted array: [4, 5, 6, 7, 1, 2, 3]
# ```
# We need to find the **minimum element** (`1` in this example), and we do it **without** going through every single number. We use **binary search**, which makes it much faster.
# ---
# ## π¨ Step-by-Step Code Breakdown (Like I'm Explaining to Myself)
# ```python
# class Solution:
# ```
# - We're making a **blueprint** (class) called `Solution`. It's just a container for our method (function).
# ```python
# def findMin(self, nums: List[int]) -> int:
# ```
# - Inside our `Solution` class, we make a **function** called `findMin`.
# - It accepts `nums`, which is the **list of numbers** (our rotated sorted array).
# - `List[int]` means the input is a list of integers.
# - It will **return an integer**, the smallest number in the list.
# ---
# ## π The Core Logic Begins!
# ### Line 1
# ```python
# res = nums[0]
# ```
# - We start by assuming the **first number** in the array (`nums[0]`) is the **smallest**.
# - `res` holds the **current smallest number we've seen so far**.
# ---
# ### Line 2
# ```python
# l, r = 0, len(nums) - 1
# ```
# - `l` is the **left pointer**, starting at index `0` (beginning of the array).
# - `r` is the **right pointer**, starting at the **last index** (`len(nums) - 1`).
# Imagine your array is:
# ```
# [4, 5, 6, 7, 1, 2, 3]
# ```
# - `l = 0` points at `4`.
# - `r = 6` points at `3`.
# ---
# ## π Time to Loop! (While Loop)
# ```python
# while l <= r:
# ```
# - We are going to keep looping **while left is less than or equal to right**.
# - This ensures we are still looking at a valid portion of the array.
# ---
# ### First Check Inside the Loop
# ```python
# if nums[l] < nums[r]:
# ```
# - **What are we checking?**
# If the **left number** is **less than the right number**.
# - **Why?**
# If this happens, it means the **current portion of the array is already sorted**, so the smallest number must be at `nums[l]`.
# Example:
# ```
# If nums[l] = 1 and nums[r] = 3 (like in [1, 2, 3])
# The whole thing is sorted, and `1` is the smallest.
# ```
# ---
# ### Update the Result
# ```python
# res = min(res, nums[l])
# ```
# - We take the **smaller** of `res` and `nums[l]`.
# - `res` is keeping track of the **smallest number we've found so far**.
# ---
# ### Break If Already Sorted
# ```python
# break
# ```
# - If we just found a **sorted chunk**, and we updated `res`, there's **no need to keep looking**, so we **break out** of the loop.
# ---
# ## π§ Now We Go Binary Search Mode
# If the array isn't sorted, we have to go deeper!
# ### Find the Middle
# ```python
# m = (l + r) // 2
# ```
# - We find the **middle index** between `l` and `r`.
# - `// 2` just means **integer division** (we don't want decimal numbers).
# - Think of `m` as our **middle finger**, pointing at the middle of our search area!
# Example:
# ```
# l = 0 (pointing at 4)
# r = 6 (pointing at 3)
# m = (0 + 6) // 2 = 3
# nums[m] = 7
# ```
# ---
# ### Update the Result with the Middle Element
# ```python
# res = min(res, nums[m])
# ```
# - We compare the **current smallest** (`res`) with `nums[m]` (middle value).
# - `min()` picks the **smaller one**.
# ---
# ### Now Decide Where to Search Next
# ```python
# if nums[m] >= nums[l]:
# ```
# - **What are we checking?**
# Is the middle value `nums[m]` **greater than or equal to** the left value `nums[l]`?
# - **Why?**
# If the middle is bigger, it means the **smallest number is in the right half**.
# The left side (from `l` to `m`) is **sorted**, and the minimum can't be there (we've already checked).
# Example:
# ```
# nums[m] = 7
# nums[l] = 4
# Since 7 >= 4, we search the **right half**.
# ```
# ---
# ### Move the Left Pointer
# ```python
# l = m + 1
# ```
# - We **shift the left pointer** to `m + 1`.
# - We're ignoring the left side, and moving our search to the **right half**.
# ---
# ### Else: Search Left Half
# ```python
# else:
# r = m - 1
# ```
# - If `nums[m]` **isn't** greater than `nums[l]`,
# It means the **smallest number is on the left half**,
# So we **shift the right pointer** to `m - 1`.
# ---
# ## β
After the Loop Ends...
# ```python
# return res
# ```
# - `res` now holds the **smallest number** we found!
# - We **return** it!
# ---
# ## ποΈβπ¨οΈ Let's Walk Through a Full Example
# Array:
# ```
# [4, 5, 6, 7, 0, 1, 2]
# ```
# - `res = 4`
# - `l = 0`
# - `r = 6`
# ### First Loop:
# - `nums[l] = 4`
# - `nums[r] = 2`
# - `nums[l]` is **not** less than `nums[r]`, so keep going.
# - `m = (0 + 6) // 2 = 3`
# - `nums[m] = 7`
# - `res = min(4, 7) = 4`
# - Since `nums[m] = 7 >= nums[l] = 4`,
# Move `l` to `m + 1 = 4`.
# ### Second Loop:
# - `l = 4`, `r = 6`
# - `nums[l] = 0`
# - `nums[r] = 2`
# - `nums[l] < nums[r]`!
# This means **sorted chunk**.
# - `res = min(4, 0) = 0`
# - Break out of the loop.
# ### Return `res = 0`.
# ---
# ## π What Did We Do?
# We found `0`, the **smallest number**, in **logarithmic time** (`O(log n)`), by using **binary search** instead of going one by one.
# ---
# ## β¨ Super Simple Visualization
# Imagine a **pizza slice**.
# - The crust side is sorted.
# - But the **cheese dripped down and rotated the slice**!
# - You keep **cutting the slice in half**, checking which side is lower.
# - You find the **cheesiest, lowest point** β that's your **minimum**.
# ---
# ## π§ Key Takeaways:
# 1. We're finding the **smallest number in a rotated sorted array**.
# 2. We use **binary search** to cut down the time.
# 3. We **compare** the left, middle, and right to decide where to search next.
# 4. **Efficiency**: `O(log n)` time instead of `O(n)`.