LeetCode 每日一题笔记 日期:2026.05.16 题目:154. 寻找旋转排序数组中的最小值 II
LeetCode 每日一题笔记0. 前言日期2026.05.16题目154. 寻找旋转排序数组中的最小值 II难度困难标签数组、二分查找1. 题目理解问题描述给定一个可能存在重复元素的升序数组经过1~n次旋转后找出并返回数组中的最小元素。要求操作步骤尽可能少。示例输入nums [2,2,2,0,1]输出0解释数组中存在重复的2最小值为0。输入nums [1,3,5]输出1解释数组未旋转最小值为1。2. 解题思路核心观察与无重复元素的版本153题相比本题存在重复元素当arr[mid] arr[right]时无法判断最小值所在区间解决方法当arr[mid] arr[right]时直接将right--缩小搜索范围直到不相等为止整体逻辑仍基于二分查找只是在相等时增加了线性步的收缩操作。算法步骤初始化左右指针left 0right nums.length - 1循环直到left right计算mid left (right - left) / 2若arr[mid] arr[right]最小值在 mid 右侧left mid 1若arr[mid] arr[right]最小值在 mid 左侧right mid若arr[mid] arr[right]无法判断right--缩小范围返回nums[left]即为最小值。3. 代码实现classSolution{intbinary(int[]arr,intleft,intright){while(left!right){intmidleft(right-left)/2;if(arr[mid]arr[right]){leftmid1;}elseif(arr[mid]arr[right]){rightmid;}else{right--;}}returnarr[left];}publicintfindMin(int[]nums){returnbinary(nums,0,nums.length-1);}}4. 代码优化说明减少分支判断将逻辑合并到主函数中去掉单独的binary方法classSolution{publicintfindMin(int[]nums){intleft0,rightnums.length-1;while(leftright){intmidleft(right-left)/2;if(nums[mid]nums[right]){leftmid1;}elseif(nums[mid]nums[right]){rightmid;}else{right--;}}returnnums[left];}}5. 复杂度分析时间复杂度平均O(logn)O(\log n)O(logn)最坏O(n)O(n)O(n)无重复元素时为标准二分查找O(logn)O(\log n)O(logn)极端情况下全为重复元素会退化为线性遍历O(n)O(n)O(n)。空间复杂度O(1)O(1)O(1)仅使用常数级额外变量无额外空间开销。6. 总结核心思路带重复元素的二分查找利用right--处理arr[mid] arr[right]的情况关键区别与无重复元素版本相比增加了相等时的线性收缩步骤优化后代码逻辑更紧凑去掉了不必要的方法调用可读性和效率更高。