leetcode第33题,搜索旋转排序数组
第一种方式:暴力破解,但是这样子不好,比较垃圾
class Solution {
public int search(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
if (target == nums[i])
return i;
}
return -1;
}
}
第二种方式 二分查找 时间复杂度o(logn)
思路分析:
- 这个算法是基于一个事实,无只要我们从中间位数砍,就一定会劈出来一个有序数组,看这个目标值是不是在这个有序数组里面,如果在的话,就在这里面找,舍弃另外的一半,但是必须要从有序的数组里面开始找,开始截取,也就是一个逐渐开始找有序数组的过程
class Solution {
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int mid;
while (start <= end) {
mid = start + (end - start) / 2;
if (nums[mid] == target) {
return mid;
}
//前半部分有序,注意此处用小于等于
if (nums[start] <= nums[mid]) {
//target在前半部分
if (target >= nums[start] && target < nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
} else {
if (target <= nums[end] && target > nums[mid]) {
start = mid + 1;
} else {
end = mid - 1;
}
}
}
return -1;
}
}
第三种方式:区分段
谈一下自己的感受吧:
- 这种思路非常不错,也非常前沿,但是自己调试的话,总是觉得怪怪的
- 对于我们要找到的target,target不在的这一段,所有的数字可以看作是无穷大或是无穷小,这样就可以用正常的二分法进行查找了.
class Solution {
public int search(int[] nums, int target) {
//将无序的数组往有序的弄
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
int num = nums[mid];
if ((nums[mid] < nums[0]) && (target < nums[0])) {
num = nums[mid];
} else {
num = target < nums[0] ? Integer.MIN_VALUE : Integer.MAX_VALUE;
}
if (num < target) {
start = mid + 1;
} else if (num > target) {
end = mid - 1;
} else {
return mid;
}
}
return -1;
}
}