63、在排序数组中查找元素的第一个位置和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums.length == 0) {
return new int[]{-1,-1};
}
int[] ans = new int[2];
int l = 0,r = nums.length - 1;
while (l < r) {
int mid = l + (r - l + 1) / 2;
if (nums[mid] <= target) {
l = mid;
}else {
r = mid - 1;
}
}
if (nums[l] == target) ans[1] = l;
l = 0;
r = nums.length - 1;
while (l < r) {
int mid = l + (r - l) / 2;
if (nums[mid] >= target) {
r = mid;
}else {
l = mid + 1;
}
}
if (nums[l] == target) ans[0] = l;
if (nums[ans[0]] != target) {
ans[0] = -1;
ans[1] = -1;
}
return ans;
}
}
64、寻找旋转排序数组中的最小值
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
- 若旋转
4次,则可以得到[4,5,6,7,0,1,2] - 若旋转
7次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
public class Solution {
public int findMin(int[] nums) {
int n = nums.length; // 数组长度
if (n == 0) { // 如果数组为空,题意中一般不允许,可抛异常处理
throw new IllegalArgumentException("数组不能为空");
}
int left = 0, right = n - 1; // 初始化左、右指针
while (left < right) { // 当 left < right 时继续循环
int mid = (left + right) >>> 1; // 计算中点索引,使用无符号右移防止溢出
if (nums[mid] > nums[right]) {
// 中点元素比最右边元素大,说明旋转点在右侧,最小值在 mid 右边
left = mid + 1; // 排除 mid 及其左侧部分
} else {
// 否则说明中点右侧有序,最小值在 mid 左侧或就是 mid
right = mid; // 包括 mid 在内,缩小右边界
}
}
// 循环结束时 left == right,指向最小值
return nums[left];
}
}
|
作者:万能包哥 出处:http://www.cnblogs.com/mybloger/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |
浙公网安备 33010602011771号