二分查找
二分查找的过程就是不断的尝试,确定范围,再缩小范围,再尝试的过程。范围缩到最后,总会有两个数,如果我们要查找的数在这两个数之内,那么就被我们找到了,如果没有,说明不存在要找的数。
再说旋转数组,旋转数组就是原来有序的数组,把前面一部分数据,接到了尾部,或者尾部的数据接到了前头,例如:array: [0,1,2,3,4,5,6,7,8,9] —> array: [4,5,6,7,8,9,0,1,2,3]
对于上面的数组,我们如果要查询8,这个数字是否在数组中,如果在的话,返回8所在的索引。
利用二分法:
start = 0;
结束索引是end = array.length -1;
确定mid(中间数)的值:mid = (start + end)/2;
mid就是 5,array[5] = 9
array[mid] >=array[start]
说明mid左侧的数据是有序的,否则,如果 array[end] >=array[mid]
就是右侧数据是有序的。start~mid-1
,执行:end = mid-1
。(start,end)
范围内重复以上过程,mid = 2,8不等于6且不在索引2的左侧,在右侧,我们下次的查找范围变为了:3~5,start =mid+1Leetcode—33 搜索旋转排序数组:
题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
https://leetcode-cn.com/problems/search-in-rotated-sorted-array
代码:
class Solution {
public int search(int[] nums, int target) {
//is empty
if(nums.length == 0){
return -1;
}
int start = 0;
int end = nums.length-1;
while(end>=start){
int mid = (start + end)/2;
if(nums[mid] == target){
return mid;
}
//左边有序
if(nums[mid] >= nums[start]){
//判断target在不在左边
if(nums[mid] >target && target >= nums[start]){
end = mid - 1;
}else{
start = mid + 1;
}
}
else{
if( nums[mid] < target && target <= nums[end]) {
start = mid + 1;
}else{
end = mid - 1;
}
}
}
return -1;
}
}
在原来是升序,经过旋转后的数组里查找最小值
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0
链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
原来的数组是升序,那么截取一部分旋转之后,取mid值,在mid的左右两侧至少有一侧是保持了原来的递增规则的。判断:nums[right]是不是大于nums[mid],如果是,说明从mid到right是递增的,那么舍弃右边的范围,如果右边的值小于中间的值,那么最小值一定在右边。等范围缩小到就剩下两个元素时,再进行一步操作,就可以使left = right,使得while循环结束,
直接用最普通的方法:遍历数组,找最小元素
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length == 0 ){
return 0;
}
int ret=array[0];
for(int i = 0 ; i < array.length; i++){
if(array[i]
二分法:
class Solution {
public int findMin(int[] nums) {
// 使用二分法
int l = 0;
int r = nums.length - 1;
int mid = 0;
while(l < r){
mid = l + (r-l)/2;
if(nums[mid]nums[r]){
l = mid + 1;
}
}
return nums[l];
}
}