Leecode 154+74(二分查找)

Leecode 154

题目: 寻找旋转排序数组(有重复数字)中的最小值
分类: 二分查找
难度: Hard

题目描述
假设按照升序排序的数组在预先未知的某个点上进行了旋转(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2])
请找出其中最小的元素,注意数组中可能存在重复的元素

示例 1:
输入: [1,3,5]输出: 1

示例 2:
输入: [2,2,2,0,1]输出: 0

主要思路:哎?之前153不包含循环状态的数组找最小值好像就没搞清楚,这会儿傻了吧!
前期的判断分类没有问题
在加入mid值后,有问题,如何分类呢?

  1. 如果nums[mid]>nums[0],最小值应该在旋转的后半段 [mid,right]
  2. 如果nums[mid]<nums[0],最小值应该再旋转的 [0,mid]

下面这个图应该更直观一点
在这里插入图片描述
上图对第一种情况:如果逼近min,需要left = mid+1
在这里插入图片描述
上图针对第二种情况,如果逼近min,那么right = mid -1

还是有点问题,晚上回来再改吧!

class Solution:
    def findMin(self, nums) :
        """nums: list
           return:int
        """
        if len(nums)==1: return nums[0]
        if len(nums)==2 : return min(nums)
        #判断数组是否发生旋转
        if nums[0]<nums[len(nums)-1]:
            return nums[0]
        else:
            left = 0
            right = len(nums)-1
            
        while(left<right):
            mid= left+int((right-left)/2)
            if (nums[mid]<nums[mid-1] and nums[mid]<nums[mid+1]):
                return nums[mid]
            #判断left是否为最小值 
            elif left>=1 and left+1<len(nums) and nums[left] < nums[left-1] and nums[left]<nums[left+1]:  
                return nums[left]
            #判断right 是否为最小值
            elif right >= 1 and right+1<len(nums) and  nums[right] < nums[right-1] and  nums[right] < nums[right+1]:
                return nums[right]
            elif nums[mid]>nums[0]:
                left = mid+1
            else :
                right = mid-1
          
        if nums[0]<nums[len(nums)-1]:
            return nums[0]
        else:
            return nums[len(nums)-1]
       

            
                

Leecode 74

题目: 搜索二维矩阵
分类: 二分查找
难度: 中等

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

示例1
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
输出: true

示例2
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
输出: false

分析:

  1. 可以把矩阵看成多个数组的形式,相当于一个长数组进行判断目标值,并且长数组的顺序为升序排列
  2. 先确定目标值所在行数,再确定是否含有目标值(未用到二分查找,直接比较target和每一行最大元素的大小)

分析2代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length==0)
            return false;
        int rowIndex=0;//表示行元素下标
        int colIndex =matrix[0].length -1;  //表示列元素下标
        while(rowIndex < matrix.length && colIndex >=0)
        {
            if(target == matrix[rowIndex][colIndex])
                return true;
            else if(target > matrix[rowIndex][colIndex])
                rowIndex++;
            else 
                colIndex--;
        }
        return false;
    }
}

**分析1的代码:**关键点在于如何将数组下标和矩阵下标进行转换

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length==0)
            return false;
        int n = matrix[0].length;  //列数
        int left = 0;
        int right=matrix.length*matrix[0].length-1;
        //matrix.length =m表示行
        //matrix[0].length= n 表示列元素个数
        while(left<=right){    //注意:这里是小于等于,一开始写的<提交后会出现错误
            int mid = left + (right-left)/2;
            if (target == matrix[mid/n][mid%n])
                //确定一个下标在二维数组中的位置:行数是下标值除以列的长度4
                //对于列:小标除以4取余
                return true;
            else if(target > matrix[mid/n][mid%n])
                left = mid+1;
            else 
                right = mid -1;
        }
        return false;
    }
}
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值