两道题
33. Search in Rotated Sorted Array
https://leetcode.com/problems/search-in-rotated-sorted-array/
81. Search in Rotated Sorted Array II
https://leetcode.com/problems/search-in-rotated-sorted-array-ii/
这两道题都是属于循环有序数组的查找问题,无论是查找具体元素的下标还是检查一个目标值是否在数组中,主要的判断逻辑都是一致的。
思路
这种将有序数组翻转成循环有序数组的解决办法是将原数组分段。用首元素start、中间元素mid、尾元素end,可以将数组分为两个子数组s1,s2。
则这两个子数组中,必然有至少一个子数组是有序的。
那么如何确定那一段是有序的呢,通过分析可以看到只有3种情况:
- 当start就是A中最小的元素时,以下不等式成立:start <= mid <= end
- 当最小值位于(start, mid]时,则有:mid <= end <= start
- 当最小值出现在(mid,end]时,则有:end <= start <= mid
所以通过start, mid, end的大小关系,就可以判断出s1和s2哪个是有序的。
通过比较要查找的目标target与start,mid,end的大小关系,就可以知道target位于哪个子数组。
若target位于有序的子数组,则用二分查找就可以了。否则,对无序的子数组重复刚才的过程就可以了。
代码
package com.lingyejun.dating.chap11.toutiao;
public class RotatedArrayQuery {
/**
* 33. Search in Rotated Sorted Array
* 查找目标值下标
*
* @param nums
* @param target
* @return
*/
public int searchTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
// (start ... middle ... end)
int mid = (start + end) / 2;
if (nums[mid] == target) {
return mid;
}
// 前半段数组是有序的
if (nums[start] < nums[mid]) {
// target在前半段数组中
if (target < nums[mid] && target >= nums[start]) {
// 将原数组折半,取出前半段数组
end = mid - 1;
} else {
// target在后半段数组中
start = mid + 1;
}
}
// 后半段数组是有序的
else if (nums[mid] < nums[end]) {
// target在后半段数组中
if (target > nums[mid] && target <= nums[end]) {
// 将原数组折半,取出后半段数组
start = mid + 1;
} else {
// target在前半段数组中
end = mid - 1;
}
} else {
// 此种场景{1, 0, 1, 1, 1} start = mid = end
start++;
}
}
return -1;
}
/**
* 81. Search in Rotated Sorted Array II
*
* 查找是否存在目标值
*
* @param nums
* @param target
* @return
*/
public static boolean searchExistsKey(int nums[], int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[start] < nums[mid]) {
if (nums[start] <= target && target < nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
} else if (nums[start] > nums[mid]) {
if (nums[mid] < target && target <= nums[end]) {
start = mid + 1;
} else {
end = mid - 1;
}
} else {
start++;
}
}
return false;
}
public static void main(String[] args) {
int[] array = new int[]{1, 0, 1, 1, 1};
RotatedArrayQuery caq = new RotatedArrayQuery();
System.out.println(caq.searchTargetIndex(array, 0));
System.out.println(caq.searchExistsKey(array, 1));
}
}
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。
首发链接:Search in Rotated Sorted Array - 循环有序数组查找问题 - 翎野君 - 博客园