【C】153 寻找旋转排序数组中的最小值

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

若旋转 4 次,则可以得到 4,5,6,7,0,1,2

若旋转 7 次,则可以得到 0,1,2,4,5,6,7

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

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

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

c 复制代码
#include <stdio.h>

int findMin(int* nums, int numsSize) {
    int left = 0, right = numsSize - 1;
    
    while (left < right) {
        int mid = left + (right - left) / 2;
        
        if (nums[mid] > nums[right]) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    
    return nums[left];
}

int main() {
    int nums[] = {4, 5, 6, 7, 0, 1, 2};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    
    int min = findMin(nums, numsSize);
    printf("最小元素为: %d\n", min);
    
    return 0;
}

总体思路,通过判断当前中间元素 numsmid 和最右侧元素 numsright 的大小关系,以确定最小元素的位置所在。

如果 numsmid > numsright

这表示当前中间元素 numsmid 大于最右侧元素 numsright,说明最小元素位于 mid 的右侧(包括 mid 自身)。因此,将搜索范围调整到 mid + 1, right,即将 left 指针移到 mid + 1 处。

否则:

如果 numsmid <= numsright,则说明最小元素位于 left 到 mid 之间(包括 mid)。因此,将搜索范围调整到 left, mid,即将 right 指针移到 mid 处。

通过这样的判断和调整,不断缩小搜索范围,直到 left 和 right 指针相遇,找到最小元素的位置。

利用二分查找的思想,每次通过比较中间元素与右边界元素的大小关系,将搜索范围缩小一半,因此时间复杂度为 O(log n)。

这种算法充分利用了数组原本是升序排列的性质,并通过比较中间元素与右侧边界元素的大小关系,快速缩小搜索范围,从而找到最小值的位置。

相关推荐
地平线开发者2 分钟前
工具链使用从入门到顺手
算法
明航咨询—张老师10 分钟前
AI工具狂飙时代:三款实用AI产品深度横向测评
大数据·人工智能·算法·it
真实的菜43 分钟前
Redis 从入门到精通(二):深入数据结构 —— 从 RedisObject 到 SkipList 的源码级拆解
数据结构·redis·skiplist
mifengxing1 小时前
LeetCode热题100——字母异位词分组
java·算法·leetcode·职场和发展·哈希表·hot100
社交怪人1 小时前
【判断奇偶】信息学奥赛一本通C语言解法(题号1041)
c语言
Billlly2 小时前
莫比乌斯反演学习笔记
算法
stolentime2 小时前
CF2066D1 Club of Young Aircraft Builders (easy version)题解
c++·算法·动态规划·组合数学
Dillon Dong2 小时前
【风电控制】高低穿现场失败的原因分析——算法简单但工程复杂
算法·变流器·风电控制·dfig
Jun6262 小时前
QT(1)-C/C++库生成和调用
c语言·开发语言·c++·qt
小欣加油3 小时前
leetcode41 缺失的第一个正数
数据结构·c++·算法·leetcode