python 二分查找_二分查找-python-leetcode

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 #峰谷元素不满足上面两个条件

a76a5c2742c857b210526c4e8616a84b.png

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;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值