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值后,有问题,如何分类呢?
- 如果nums[mid]>nums[0],最小值应该在旋转的后半段 [mid,right]
- 如果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
分析:
- 可以把矩阵看成多个数组的形式,相当于一个长数组进行判断目标值,并且长数组的顺序为升序排列
- 先确定目标值所在行数,再确定是否含有目标值(未用到二分查找,直接比较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;
}
}