【牛客 - 剑指offer】JZ11 旋转数组的最小数字 Java实现


剑指offer题解汇总 Java实现

https://blog.csdn.net/guliguliguliguli/article/details/126089434

本题链接

知识分类篇 - 02 算法 - 搜索算法 - JZ11 旋转数组的最小数字 Java实现

题目

在这里插入图片描述
题目主要信息

  • 有一个长度为n的非降序数组,把一个数组最开始的若干元素“平移”到数组的末尾,变成一个旋转数组

  • 找到这个旋转数组的最小值

方案 分治法

分治即“分而治之”

  • “分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决

  • “治”指的是将子问题单独进行处理

分治后的问题需要将解进行合并才能得到原问题的解,因此整个过程经常用递归来实现

思路

旋转数组将原本有序的数组分成了两部分有序的数组,因为在原始有序数组中,最小的元素一定是在首位,那个“断崖式”突然下降的点,就是最小的数字,不过,一个数组中的每个数都一样的话,那就不是了…

可以将旋转前的前半段命名为A,旋转后的前半段命名为B,旋转数组即将AB变成了BA

因为A部分和B部分都是各自有序的,所以可以使用分治,每次比较中间值,确认目标值(最小元素)所在的区间。

具体做法

  1. 双指针指向旋转后数组的首尾,作为区间端点
  2. 若区间中点值大于区间右边界值,则最小值一定在中点右边
  3. 若区间中点值等于区间右边界值,则不好判断最小值在哪半个区间,应逐个缩减右边界

[1,0,1,1,1,1,1]
[1,1,1,1,1,0,1]

  1. 若区间中点值小于区间右边界值,则最小值一定在中点左边(包括中点)
  2. 调整整个区间后,即可缩小最小值所在的区间范围
import java.util.ArrayList;

public class Solution {
    public int minNumberInRotateArray(int[] array) {
        int left = 0;
        int right = array.length - 1;
        int mid;
        while (left <= right) {
            mid = (left + right) / 2;
            if (array[mid] > array[right]) {
                left = mid + 1;
            } else if (array[mid] < array[right]) {
                right = mid;
            } else {
                right--;
            }
        }
        return array[left];
    }
}

能不能以左边界值为参考呢?

应该是不能不能,如[1,0,1,1,1],left的值和mid的值相同,left++
在进入第二次循环的时候,会变成[0,1,1,1],这时,mid的值大于left的值,执行left=mid+1,会把0这个真正的最小值排除在外了

原问题和子问题也不是同一性质的题了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值