-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinarySearch.py
More file actions
129 lines (109 loc) · 3.96 KB
/
Copy pathbinarySearch.py
File metadata and controls
129 lines (109 loc) · 3.96 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
# -*- coding: utf-8 -*-
"""
binary search二分查找
@author: qinliu
keypoints:
1. start+1 < end --->这样的写法比较通用,还适合于找到数值插入位置,不会死循环
2. mid = int(start + (end - start)/2) --->当start与end较大时,start + end可能会溢出
3. nums[mid] =>< target ---> 判断目标值与mid
4. nums[start]nums[end] ?= target --->从while循环出来之后不是相交就是相邻
"""
# 704. 二分查找 [1,2,3,4] 3 --> 2
# https://leetcode-cn.com/problems/binary-search/
class Solution:
def search(self, nums, target):
if len(nums) == 0:
return -1
start = 0
end = len(nums) - 1
while start+1 < end:
mid = int(start + (end - start)/2)
if nums[mid] == target:
return mid
elif nums[mid] > target:
end = mid
elif nums[mid] < target:
start = mid
if nums[start] == target:
return start
if nums[end] == target:
return end
# 4. 寻找两个有序数组的中位数
# https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
class Solution:
"""找到两个数组中的第k大的元素,当nums1[k//2 - 1]<nums2[k//2 - 1]时,
说明nums1[k//2 - 1]前面的数都位于合并数组的前k个,所以可挪动nums1的起始位置"""
def findMedianSortedArrays(self, nums1, nums2):
n = len(nums1) + len(nums2)
if n % 2 ==1:
return self.findKth(nums1, nums2, n//2 + 1)
else:
left = self.findKth(nums1, nums2, n//2)
right = self.findKth(nums1, nums2, n//2 + 1)
return (left + right)/2.0
def findKth(self, nums1, nums2, k):
if len(nums1) == 0:
return nums2[k-1]
if len(nums2) == 0:
return nums1[k-1]
if k ==1:
return min(nums1[0], nums2[0])
a = nums1[k//2 - 1] if len(nums1) >= k//2 else None
b = nums2[k//2 - 1] if len(nums2) >= k//2 else None
if b is None or (a is not None and a<b):
return self.findKth(nums1[k//2:], nums2, k - k//2)
return self.findKth(nums1, nums2[k//2:], k - k//2)
# 35. 搜索插入位置
# https://leetcode-cn.com/problems/search-insert-position/
class Solution:
def searchInsert(self, nums, target) :
start = 0
end = len(nums) - 1
if len(nums) == 0:
return 0
while start + 1 < end:
mid = start + (end - start)//2
if nums[mid] >= target:
end = mid
else:
start = mid
if nums[start] >= target:
return start
if nums[end] >= target:
return end
return len(nums)
# 34. 在排序数组中查找元素的第一个和最后一个位置
# https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
class Solution:
# 用两次二分法,找到左右边界
def searchRange(self, nums, target):
if not nums:
return [-1,-1]
start, end = 0, len(nums) - 1
left, right = -1, -1
# 找右边界
while start +1 < end:
mid = start + (end - start)//2
if nums[mid] <= target:
start = mid
else:
end = mid
if nums[start] == target:
right = start
if nums[end] == target:
right = end
# 找左边界
start, end = 0, len(nums) - 1
while start +1 < end:
mid = start + (end - start)//2
if nums[mid] >= target:
end = mid
else:
start = mid
if nums[end] == target:
left = end
if nums[start] == target:
left = start
if left == -1 and right == -1:
return [-1,-1]
return [left,right]