先找到有序的那一部分,然后有序那一部分中最左元素和min作比较。修改范围,再次查找。
class Solution {
public int findMin(int[] nums) {
int left=0;
int min=nums[0];
int right=nums.length-1;
while (left<=right){
int mid=left+((right-left)>>1);
if(nums[mid]<min) min=nums[mid];
if(mid-1>=left&&nums[left]<=nums[mid-1]){
if(nums[left]<min){
min=nums[left];
}
left=mid+1;
}else{
if(mid+1<nums.length&&nums[mid+1]<min){
min=nums[mid+1];
}
right=mid-1;
}
}
return min;
}
}
看到题解的解法很简洁。
再次写的时候发现体验不太好。
如果只比较两端是比较不出啥的。
如 8 1 2 3 4
8 9 10 11 4
所以必有mid
class Solution {
public int findMin(int[] nums) {
int left=0;
int right=nums.length-1;
while (left<=right) {
if(nums[left]<=nums[right]) return nums[left];
int mid =left+((right-left) >> 1);
if(nums[mid]<=nums[right]){
right=mid;
}else{
left=mid+1;
}
/*下同、
if(nums[mid]<=nums[right]){
right=mid;
}else{
left=mid+1;
}
*/
}
return 0;
}
}
154, 要求元素可能重复。
题解很简洁。特别在意的是mid和right的比较。
如果mid和left比较,代码可能更加复杂。
class Solution {
public int findMin(int[] nums) {
int left=0;
int right=nums.length-1;
while (left<=right) {
int mid=left+((right-left)>>1);
if(nums[mid]>nums[right]){
left=mid+1;
}else if(nums[mid]<nums[right]){
right=mid;
}else{
right--;
}
}
return nums[left];
}
}
看了题解写出的递归。
面向测试编程了。
//比较左边
/*
因为数组之前是递增的,旋转之后可能会起起伏伏。
判断mid和left的时候,只是假定了会起起伏伏的,要加上判断是否有没有旋转
*/
class Solution {
public int findMin(int[] nums) {
return find(nums,0,nums.length-1);
}
private int find(int[] nums,int left,int right){
//存在 mid+1和mid-1
if(left<0||left>=nums.length) return nums[right];
if(right<0||right>=nums.length) return nums[left];
//判断有没有起伏
if(nums[left]<nums[right]) return nums[left];
if(right<=left) return Math.min(nums[left],nums[right]);
int mid=left+((right-left)>>1);
if(nums[mid]<nums[left]){
return find(nums,left,mid);
}else if(nums[mid]>nums[left]){
return find(nums,mid+1,right);
}else{
return Math.min(find(nums,left,mid-1),find(nums,mid+1,right));
}
}
}
//判断右边
class Solution {
public int findMin(int[] nums) {
return find(nums,0,nums.length-1);
}
private int find(int[] nums,int left,int right){
if(left<0||left>=nums.length) return nums[right];
if(right<0||right>=nums.length) return nums[left];
// if(nums[left]<nums[right]) return nums[left];
if(right<=left) return Math.min(nums[left],nums[right]);
int mid=left+((right-left)>>1);
if(nums[mid]<nums[right]){
return find(nums,left,mid);
}else if(nums[mid]>nums[right]){
return find(nums,mid+1,right);
}else{
return Math.min(find(nums,left,mid-1),find(nums,mid+1,right));
}
}
}