Leetcode 153/154: 寻找旋转排序数组中的最小值—java代码

153.寻找旋转排序数组中的最小值Ⅰ

题目详情:
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如:原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 2 次,则可以得到 [2,4,5,6,7,0,1]
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

给定一个元素值 互不相同 升序排列的数组 nums ,并按上述情形进行了多次旋转。请找出并返回数组中的 最小元素 。

解析:经过旋转的数组,前半段满足 >=nums[0],后半段不满足 >=nums[0]。因此,通过二分找到旋转点,然后通过旋转点找到全局最小值。

class Solution {
	public int findMin(int[] nums] {
		int n = nums.length; 
		int low = 0, high = n - 1;
		//寻找旋转点
		while (low < high) {//循环条件只要满足low<high就说明没有找到最小值
			int mid = low + high + 1 >> 1;
			if (nums[mid] >= nums[0]) {//判断最小值是在而分段的前一段还是后一段
				low = mid;
			} else {
				high = mid - 1;
			}
		}
		//如果high<n+1,说明经过了旋转(不是原数组),最小值经过旋转循环过后一定在high+1位置;
		//否则nums未旋转,或者旋转过后保持原数组,则最小值在0处
		return high + 1 < n ? nums[high+1] : nums[0];
	}
}

154.寻找旋转排序数组中的最小值Ⅱ

题目详情:
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
若旋转 7 次,则可以得到 [0,1,4,4,5,6,7]

注意:所谓的旋转其实就是[将某个下标前面的所有数整体移到后面,使得数组从整体升序变成分段升序]

给定一个可能存在 重复 元素的升序排列数组 nums ,并按上述情形进行了多次旋转。请找出并返回数组中的 最小元素 。

不同点: 与上一题的不同之处在于本题可以元素重复,这意味着无法直接根据与nums[0]的大小关系将数组划分为二段,即无法通过二分来找旋转点。
因为二分的本质是二段性,而非单调性。只要一段满足某个性质,另一段不满足某个性质,即可用二分。

class Solution {
	public int findMin(int[] nums){
		int n = nums.length;
		int low = 0, high = n - 1;
		while (low < high && nums[0] == nums[high]) high--;//恢复二段性
		//寻找旋转点
		while (low < high) {
			int mid = low + high + 1 >> 1;
			if (nums[mid] >= nums[0]) {
				low = mid;
			} else {
				high = mid - 1;
			}
		}
		return (high + 1)  < n ? nums[high + 1] : nums[0];
	}
}

注释:写的不好之处请您纠正,新手小白,期待您来指教!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值