本篇文章仅汇总该系列的变题!!!关于搜索旋转排序数组的原理可见 浅析:搜索旋转排序数组
题目详情可见 搜索旋转排序数组
x
// 写法一
public int search(int[] nums, int target) {
int n = nums.length, l = 0, r = n - 1;
while (l < r) {
int m = l + r + 1 >> 1;
if (nums[m] == target) return m;
if (nums[m] <= nums[r])
if (nums[m] <= target && target <= nums[r]) l = m;
else r = m - 1;
} else {
if (nums[l] <= target && target <= nums[m]) r = m;
else l = m + 1;
}
}
return nums[l] == target ? l : -1;
}
// 写法二
public int search(int[] nums, int target) {
int n = nums.length, l = 0, r = n - 1;
while (l < r) {
int m = l + r >> 1;
if (nums[m] == target) return m;
if (nums[l] <= nums[m]) {
if (nums[l] <= target && target <= nums[m]) r = m;
else l = m + 1;
} else {
if (nums[m] <= target && target <= nums[r]) l = m;
else r = m - 1;
}
}
return nums[l] == target ? l : -1;
}
题目详情可见 搜索旋转排序数组 II
x
public boolean search(int[] nums, int target) {
int n = nums.length;
int l = 0, r = n - 1;
while (l < r) {
int m = l + r + 1 >> 1;
if (nums[m] == target) return true;
if (nums[m] == nums[r]) r--; // 和无重复元素的类型唯一的不同点
else if (nums[l] <= nums[m]) {
if (nums[l] <= target && target <= nums[m]) r = m;
else l = m + 1;
} else {
if (nums[m] <= target && target <= nums[r]) l = m;
else r = m - 1;
}
}
return nums[l] == target;
}
题目详情可见 寻找旋转排序数组中的最小值
xxxxxxxxxx
public int findMin(int[] nums) {
int n = nums.length;
int l = 0, r = n - 1;
while (l < r) {
int m = l + r >> 1;
if (nums[m] <= nums[r]) r = m;
else l = m + 1;
}
return nums[l];
}
题目详情可见 寻找旋转排序数组中的最小值 II
x
public int findMin(int[] nums) {
int n = nums.length;
int l = 0, r = n - 1;
while (l < r) {
int m = l + r >> 1;
if (nums[m] == nums[r]) r--; // 和无重复元素的类型唯一的不同点
else if (nums[m] < nums[r]) r = m;
else l = m + 1;
}
return nums[l];
}
该变题是在 搜索旋转排序数组 的基础上进行修改滴!!
🌰 举个例子:nums = [6, 7, 9, 0, 2, 4, 5], target = 8
,该样例应该返回9
用变题一中的写法一可以做到部分样例可以正确返回,但有些样例返回错误,如:nums = [6, 7, 9, 0, 2, 4, 5], target = 3
,错误返回5
,应该返回4
这里提供一种曲线救国的方法:先找到最小值,如:变题四、变题五;然后分两段找
旋转一次和旋转两次是一样的,都会把一个数组分成两段递增序列
🌰 举个例子:nums = [1, 2, 3, 4, 5, 6]
先旋转一次后:nums = [3, 4, 5, 6, 1, 2]
再旋转一次后:nums = [5, 6, 1, 2, 3, 4]
xxxxxxxxxx
// 方法一:逐个移动
public void moveOne(int[] nums) {
int t = nums[0], n = nums.length;
for (int i = 1; i < n; i++) {
nums[i - 1] = nums[i];
}
nums[n - 1] = t;
}
// 方法二:借助临时数组
// 从下标 idx 开始旋转数组
public void move(int[] nums, int idx) {
int n = nums.length;
int[] temp = new int[idx];
for (int i = 0; i < idx; i++) temp[i] = nums[i];
for (int i = idx; i < n; i++) {
nums[i - idx] = nums[i];
}
for (int i = 0; i < idx; i++) {
nums[n - idx + i] = temp[i];
}
}