【每日算法】查找算法1(中等)

简介: 查找算法(中等)

16fb98eea012ef0cb446588ddc50662.png

题目

剑指 Offer 11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

示例:

输入:numbers = [3,4,5,1,2]
输出:1
复制代码

分析

做这道题还是花了有点多时间的,踩坑无数,现在来一起复盘一下

首先这是一个半有序数组,可以优先考虑使用二分查找

之前有个误区,认为二分查找必须是有序数组才能使用,实际上只要满足一定的条件,就可以使用二分查找

二分查找本质是将查找区间由中间分为两份,只要能总结出,目标值在其中哪一部分,就可以使用二分查找

回到这道题中

需要我们分析出目标值在我们分割的区间中有什么特点

5770153093445a30cb6f415cbe2aa35.png

旋转点右侧元素大于旋转点左侧元素

如果使用二分法将数组切分,以 mid 为中点,把数组切成两部分

即 3 个端点:left = 0; right = numbers.length - 1; mid = (left + right) >> 1

[leff, mid)

[mid, right]

那么根据中间点 mid 的大小,会有三种情况

  • nums[mid] < nums[right]

最小值就在 [left, mid] 之间

  • nums[mid] > nums[right]

最小值就在 [mid, right]之间

  • 两者相等?

这个地方就有坑了,由于可能存在多个相同的值,无法直接确定就是最小值

这里就需要逐步逼近了,让右端点减1再继续迭代,这样最后的右端点就是我们所求的最小值

实现

function minArray(numbers: number[]): number {
    let l_idx: number = 0
    let r_idx: number = numbers.length - 1
    while(l_idx < r_idx) {
        const mid: number = (l_idx + r_idx) >> 1
        if (numbers[mid] < numbers[r_idx]) {
            // 【l_ridx - mid】
            r_idx = mid
        } 
        else if (numbers[mid] > numbers[r_idx]) {
            // 【mid - r_idx】
            l_idx = mid + 1
        }
        else {
            r_idx --
        }
    }
    return numbers[r_idx]
};
相关文章
|
27天前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
17 0
|
6月前
|
机器学习/深度学习 算法
刷题记录:牛客-WY49数对 | 以数学分析来破解暴力搜索的时间复杂度问题 2023/1/11
这是一个关于编程题解的文章摘要,讨论了一道名为&quot;WY49 数对&quot;的问题。文章指出,暴力搜索的解决方案在大规模问题中效率低下,然后转向通过数学分析来寻找更优解。作者解释了如何根据除数和余数的关系,以及余数的周期性变化来计算满足条件的数对数量。通过将数对中的其中一个数(被模数x)按除数y划分区间,并分析每个区间的余数分布,得出一个公式来计算总数。最后,提供了两种不同的代码实现来展示这个思路,这些代码具有O(n)的时间复杂度和O(1)的空间复杂度。文章强调了理解数学方法在解决此类问题中的重要性,特别是对于优化算法性能的作用。
89 3
|
6月前
|
算法 前端开发 JavaScript
< 每日算法:一文带你认识 “ 双指针算法 ” >
`双指针`并非指的是一种具体的公式或者范式。而是一种运算思路,用于节省逻辑运算时间的`逻辑思路`!双指针算法通常用于`优化时间复杂度`!
< 每日算法:一文带你认识 “ 双指针算法 ” >
|
算法 索引
LeetCode算法小抄-- N 叉树 和 洗牌算法
LeetCode算法小抄-- N 叉树 和 洗牌算法
|
算法 C++ Python
每日算法系列【LeetCode 16】最接近的三数之和
每日算法系列【LeetCode 16】最接近的三数之和
|
算法 索引
从三道经典的leetcode题掌握二分法
前言 二分法是典型的搜索算法,其主要运用于有序序列中寻找目标值。其思路非常简单,就是不断比较搜索区间的中间值与目标值,当中间值等于目标值则结束搜索,如果中间值大于目标值,则继续搜索左半区间,反之搜索右半区间。 总结下,二分法就是在搜索过程中不断地将搜索区间减半,直到搜索到目标值或者搜索区间为空集。