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

在这里插入图片描述
先找到有序的那一部分,然后有序那一部分中最左元素和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));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43179428/article/details/107341480
今日推荐