34. 在排序数组中查找元素的第一个和最后一个位置
class Solution:
def searchRange(self, nums, target):
# 左边界搜索
left = 0
right = len(nums) -1
while(left <= right): # 终止条件 left == (right+1)
mid =left + (right-left) // 2
if nums[mid] == target:
right = mid-1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid -1
# 检查左侧是否右越界
left_border = -1 if left>= len(nums) or nums[left] != target else left
# 右边界搜索
left = 0
right = len(nums) - 1
while(left <= right): # 终止条件 left == (right+1)
mid =left + (right - left) // 2
if nums[mid] == target:
left = mid +1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid -1
right_border = -1 if right < 0 or nums[right] != target else right
return [left_border, right_border]
153. 寻找旋转排序数组中的最小值
import math
class Solution:
def findMin(self, nums):
left = 0
right = len(nums)-1
if right == 0:return nums[0]
if nums[right] > nums[left]:return nums[left]
for i in range(right):
if nums[i] - nums[i+1] > 0:return nums[i+1]
if nums[right-i] - nums[right-i-1] < 0:return nums[right-i]
162. 寻找峰值
class Solution:
def findPeakElement(self, nums) -> int:
# return 1
left = 0
right = len(nums) - 1
if right == 0:return 0
while left<=right:
mid = left + (right - left) // 2
if mid == right: #如果是递增序列返回最后一个元素下标
return mid
elif nums[mid] < nums[mid+1]: # 在上升曲线上,往右搜索
left = mid + 1
elif nums[mid] < nums[mid-1]: # 在下降曲线上,往左搜索
right = mid - 1
else:
return mid #峰谷元素不满足上面两个条件
81. 搜索旋转排序数组 II ps:答案不对
class Solution:
def search(self, nums, target):
left = 0
right = len(nums) - 1
min_index = 0
if right < 0:return False
def binarySearch(field):
# print(field)
left = 0
right = len(field) - 1
while left <= right:
mid = left + (right - left) // 2
# print(mid)
if field[mid] > target:
right = mid - 1
elif field[mid] < target:
left = mid + 1
elif field[mid] == target:
return True
return False
if nums[-1] > nums[0] or len(nums)<2: # 如果未旋转
return binarySearch(nums)
while left <= right:
mid = left + (right - left) // 2
print(mid)
if nums[mid - 1] >= nums[mid]:
min_index = mid
# break
elif nums[mid] >= nums[mid + 1]: # 是elif 不是if
min_index = mid + 1
# break
if nums[mid] >= nums[0]: #是>=不是>
left = mid + 1
else:
right = mid - 1
print(min_index)
if nums[min_index:][-1] >= target:
return binarySearch(nums[min_index:])
else:
return binarySearch(nums[:min_index])
74. 搜索二维矩阵
#每次行缩进一行,列进行折半
import numpy as np
class Solution:
def searchMatrix(self, matrix, target):
if len(matrix) ==0:return False
matrix = np.array(matrix)
height, width = matrix.shape
left_x, left_y =0, 0
right_x, right_y = height -1, width -1
while left_x<= right_x and left_y <= right_y:
mid_x = left_x
mid_y = left_y + (right_y - left_y) // 2
if matrix[mid_x, mid_y] > target: # 往左上搜索
if mid_y - 1 >= 0:
right_x, right_y = mid_x, mid_y -1 #中间位置的前一个元素
elif mid_x - 1>= 0:
right_x, right_y = mid_x - 1, width - 1#如果中间位置位于某行的开始位置,则边界调整到上一行的最后一个位置
else:
right_x, right_y = 0,0
mid_x = right_x
elif matrix[mid_x, mid_y] < target: # 往右下搜索
if mid_y + 1 < width:
left_x, left_y = mid_x, mid_y + 1
elif mid_x + 1 < height:
left_x, left_y = mid_x + 1, 0
else:
left_x,left_y = height -1, width-1
mid_x = left_x
elif matrix[mid_x, mid_y] == target:
return True
if left_x == right_x and left_y == right_y:
if matrix[left_x, left_y] == target:return True
else:return False
return False
240. 搜索二维矩阵 II
import numpy as np
class Solution:
def searchMatrix(self, matrix, target):
if len(matrix) <1:return False
matrix = np.array(matrix)
height, width = matrix.shape
def binarySearch(nums):
left = 0
right = len(nums) -1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] > target:
right = mid -1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] == target:
return True
return False
if height >= 1:
for i in range(height):
if binarySearch(matrix[i, :]):
return True
return False
287. 寻找重复数
#以时间换空间,二分查找法的反应用
class Solution:
def findDuplicate(self, nums):
left = 0
right = len(nums) - 1
repeat = 0
while left <= right:
mid = left + (right - left) // 2
count = 0
for num in nums:
if num <= mid: count += 1
if count > mid:
right = mid - 1
repeat = mid
elif count <= mid:
left = mid + 1
return repeat
print(Solution().findDuplicate([3,2,4,2,2]))
33. 搜索旋转排序数组
class Solution:
def search(self, nums, target: int) -> int:
def binarySearch(arr):
left = 0
right = len(arr) - 1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] > target:
right = mid - 1
elif arr[mid] < target:
left = mid + 1
elif arr[mid] == target:
return mid
return -1
if len(nums) < 1: return -1
if nums[-1] >= nums[0]:
return binarySearch(nums)
left = 0
right = len(nums) - 1
star = nums[0]
min_index = -1
while left <= right:
mid = left + (right - left) // 2
if nums[mid - 1] > nums[mid]:
min_index = mid
break
elif nums[mid] > nums[mid + 1]:
min_index = mid + 1
break
if nums[mid] >= star:
left = mid + 1
elif nums[mid] < star:
right = mid - 1
print(min_index)
flag = binarySearch(nums[min_index:])
if flag != -1:
return min_index + flag
return binarySearch(nums[:min_index])
528. 按权重随机选择
import random
class Solution:
def __init__(self, w: List[int]):
self.w = w
# self.total = sum(w)
self.probability = list()
for i in range(len(w)):
self.probability.append(sum(w[0:i+1]))
#寻找左区间
def pickIndex(self) -> int:
acc = random.randint(0,self.probability[-1] - 1)
left = 0
right = len(self.w) -1
# 找到最小的
while left <= right:
mid = left + (right -left) // 2
if self.w[mid] >= acc:
right = mid - 1
elif self.w[mid] < acc:
left = mid + 1
if left < 0:return 0
else:return left - 1
return left - 1
436. 寻找右区间 Java
import java.util.ArrayList;
import java.util.Arrays;
// 无脑for循环
class Solution {
public int[] findRightInterval(int[][] intervals) {
int height = intervals.length;
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < height; i++) {
int des = intervals[i][1];
int index = -1;
double temp = 1.0/0;
for (int j = 0; j < height; j++) {
if (intervals[j][0] >= des) {
if(intervals[j][0]<=temp){
index = j;
temp = intervals[j][0];
}
}
}
result.add(index);
}
int length = result.size();
int[] a = new int[length];
for(int i =0;i<length;i++){
a[i] = result.get(i);
}
return a;
}
}