Skip to content

Commit 4e694d3

Browse files
author
Chris Wu
committed
no message
1 parent 9c99683 commit 4e694d3

6 files changed

+193
-13
lines changed

problems/find-minimum-in-rotated-sorted-array.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def findMin(self, nums):
4444
If the list is already sorted, return the left most element. [1]
4545
4646
Now, we cut the rotated array into half. l~m and m~r.
47-
Normally, one part will be sorted, the other half is not.
47+
One part will be sorted, the other half is not.
4848
The min must be in the unsorted part.
4949
So we move the pointer and do the same thing on the unsorted part. [2]
5050
@@ -72,4 +72,39 @@ def findMin(self, nums):
7272
l = m+1 #[2]
7373
else:
7474
r = m-1 #[2]
75-
return 0
75+
return 0
76+
77+
78+
#2021/7/18
79+
"""
80+
Pointer l and r is at the start and at the end of the list.
81+
We only consider the numbers between l and r.
82+
83+
If the list is already sorted, return the left most element. [0]
84+
If the list is unsorted, one of the part l~m or m~r will be sorted and the other will be unsorted.
85+
86+
The MIN will be in the unsorted part.
87+
Adjust l and r and repeat the above process.
88+
89+
Time: Log(N)
90+
Space: O(1)
91+
"""
92+
class Solution(object):
93+
def findMin(self, nums):
94+
N = len(nums)
95+
96+
l = 0
97+
r = N-1
98+
99+
while l<=r:
100+
m = (l+r)/2
101+
102+
if nums[l]<=nums[m] and nums[m]<=nums[r]: return nums[l] #[0]
103+
104+
if nums[l]>nums[m]:
105+
#l~m is unsorted
106+
r = m
107+
else:
108+
#m~r is unsorted
109+
#in this case, we already sure that current m is not the MIN, so we can +1 to speed up and avoid infinitive loop
110+
l = m+1

problems/longest-common-prefix.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,20 @@ def longestCommonPrefix(self, strs):
2121
for s in strs:
2222
if s[:i]!=common_substring: #[2]
2323
return bench_mark[:i-1]
24-
return bench_mark #[3]
24+
return bench_mark #[3]
25+
26+
# 2021/7/10
27+
class Solution(object):
28+
def longestCommonPrefix(self, strs):
29+
j = 0
30+
minLen = float('inf')
31+
for s in strs: minLen = min(minLen, len(s))
32+
if minLen==float('inf'): return ""
33+
34+
while j<minLen:
35+
c = strs[0][j]
36+
for i in xrange(1, len(strs)):
37+
if strs[i][j]!=c: return strs[i][:j]
38+
j += 1
39+
40+
return strs[0][:j]

problems/median-of-two-sorted-arrays.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
```python
2525
max_left_A<=min_right_B and max_left_B<=min_right_A
2626
```
27-
And if `min_right_B<max_left_A`, it means that `i` is too large, so we adjust the upper limit of `i`, that is `h = i-1`.
27+
And if `min_right_B<max_left_A`, it means that `i` is too large, so we adjust the upper limit of `i`, that is `r = i-1`.
2828
Otherwise it means that `i` is too small, so we adjust the lower limit of `i`, that is `l = i+1`.
2929
3030
Edge cases.
@@ -55,10 +55,10 @@ def findMedianSortedArrays(self, A, B):
5555
if len(A)>len(B): A, B = B, A #[0]
5656

5757
M, N = len(A), len(B)
58-
l, h = 0, M
58+
l, r = 0, M
5959

60-
while l<=h:
61-
i = (h+l)/2
60+
while l<=r:
61+
i = (r+l)/2
6262
j = (M+N)/2-i #[1]
6363

6464
max_left_A = A[i-1] if i>0 else float('-inf') #[2]
@@ -73,7 +73,7 @@ def findMedianSortedArrays(self, A, B):
7373
else:
7474
return min(min_right_A, min_right_B) #[1]
7575
elif min_right_B<max_left_A:
76-
h = i-1
76+
r = i-1
7777
else:
7878
l = i+1
7979
return None
@@ -130,12 +130,12 @@ def findMedianSortedArrays(self, X, Y):
130130
M, N = len(X), len(Y)
131131

132132
after = (M+N-1)/2
133-
l, h = 0, M
133+
l, r = 0, M
134134

135-
while l<h:
136-
i = (l+h)/2
135+
while l<r:
136+
i = (l+r)/2
137137
if after-i-1 < 0 or X[i] >= Y[after-i-1]:
138-
h = i
138+
r = i
139139
else:
140140
l = i + 1
141141
i = l

problems/next-permutation.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
This answer is the python version of the offical answer.
3+
4+
Time: O(N)
5+
Space: O(1)
6+
"""
7+
class Solution(object):
8+
def nextPermutation(self, nums):
9+
def reverse(start):
10+
end = len(nums)-1
11+
12+
while start<end:
13+
swap(start, end)
14+
start += 1
15+
end -= 1
16+
17+
def swap(i, j):
18+
nums[i], nums[j] = nums[j], nums[i]
19+
20+
21+
i = len(nums)-2
22+
23+
while i>=0 and nums[i+1]<=nums[i]:
24+
i -= 1
25+
26+
if i>=0:
27+
j = len(nums)-1
28+
while nums[j]<=nums[i]: j -= 1
29+
swap(i, j)
30+
31+
reverse(i+1)
32+
return nums

problems/search-in-rotated-sorted-array-ii.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,63 @@ def helper(l, r):
6969
return False
7070

7171
if not nums: return False
72-
return helper(0, len(nums)-1)
72+
return helper(0, len(nums)-1)
73+
74+
75+
"""
76+
Time: O(LogN). Worse Case: O(N).
77+
Space: O(1)
78+
79+
The key idea for most rotated array question is that
80+
If you cut the array into half,
81+
One of the half will be rotated and one half will be in-order.
82+
OR
83+
Both of them are in-order (if you are lucky)
84+
"""
85+
class Solution(object):
86+
def search(self, A, T):
87+
N = len(A)
88+
l = 0
89+
r = N-1
90+
91+
while l<=r:
92+
93+
#skip repeated numbers
94+
while r>0 and A[r]==A[r-1]: r -= 1
95+
while l<N-1 and A[l]==A[l+1]: l += 1
96+
while r>0 and A[l]==A[r]: r -= 1
97+
while l<N-1 and A[l]==A[r]: l += 1
98+
99+
m = (l+r)/2
100+
101+
if A[l]==T or A[m]==T or A[r]==T: return True
102+
103+
if A[l]<=A[m] and A[m]<=A[r]:
104+
#l~r is in-order, standard binary search.
105+
if T<A[l] or T>A[r]: return False #out of range l~r
106+
107+
if A[m]<T:
108+
l = m+1
109+
else:
110+
r = m-1
111+
elif A[l]<=A[m]:
112+
#l~m is in-order
113+
114+
if A[l]<T and T<A[m]:
115+
#T is in l~m, so search in l~m
116+
r = m-1
117+
else:
118+
#T is not in l~m, so search in m~r
119+
l = m+1
120+
else:
121+
#m~r is in-order
122+
123+
if A[m]<T and T<A[r]:
124+
#T is in m~r, so search m~r
125+
l = m+1
126+
else:
127+
#T is not in m~r, so search in l~m
128+
r = m-1
129+
130+
return False
131+

problems/search-insert-position.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,44 @@ def searchInsert(self, nums, target):
7676
return 0
7777

7878

79+
#2021/7/17
80+
"""
81+
Time: O(logN)
82+
Space: O(1)
83+
"""
84+
class Solution(object):
85+
def searchInsert(self, A, T):
86+
if not A: return 0
87+
88+
N = len(A)
89+
r = N-1
90+
l = 0
7991

92+
#we are going to check the element within l and r by constantly narrow down l and r.z
93+
while l<=r:
94+
m = (l+r)/2
95+
96+
if A[l]==T: return l
97+
if A[m]==T: return m
98+
if A[r]==T: return r
99+
100+
#check if the target is out of range.
101+
if A[r]<T: return r+1
102+
if T<A[l]: return l
103+
104+
#using `m` to navigate `l` and `r`.
105+
#if the value on the pivot is larger then the target, we search the left-half.
106+
#if the value on the pivot is smaller then the target, we search the right-half.
107+
if T<A[m]:
108+
r = m-1
109+
else:
110+
l = m+1
111+
112+
return "Error"
113+
114+
115+
class Solution(object):
116+
def searchInsert(self, A, T):
117+
return bisect.bisect_left(A, T)
80118

81119

0 commit comments

Comments
 (0)