徐雄 發表於 2025-6-26 09:00:00

剑指offer-6、旋转数组的最小数字

<h2 id="题描述">题⽬描述</h2>
<p>把⼀个数组最开始的若⼲个元素搬到数组的末尾,我们称之为数组的旋转。</p>
<p>输⼊⼀个⾮递减排序的数组的⼀个旋转,输出旋转数组的最⼩元素。</p>
<p>例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的⼀个旋转,该数组的最⼩值为 1 。</p>
<p>NOTE:给出的所有元素都⼤于 0 ,若数组⼤⼩为 0 ,请返回 0 。</p>
<h2 id="思路及解答">思路及解答</h2>
<p>在这⾥最重要的特征是 ⾮递减排序,也就是本来是递增的,如果旋转后会出现什么情况呢?</p>
<p>肯定会出现先递增,再递减的情况,只要我们找出这个点,其实就是最⼩的值。</p>
<p>⼤致有以下两种⽅式解答:</p>
<ul>
<li>直接遍历,当出现后⾯的数⽐前⾯的数⼩的时候,就是找到了最⼩的数。</li>
<li>使⽤⼆分查找,在已经排序过的数组中常⽤的算法。</li>
</ul>
<h3 id="直接遍历">直接遍历</h3>
<pre><code class="language-java">import java.util.ArrayList;

public class Solution {
        public int minNumberInRotateArray(int [] array) {
                if(array == null || array.length == 0){
                        return 0;
                }

                if(array.length == 1){
                        return array;
                }

                int max = array;
               
                for(int i=1; i&lt;array.length; i++){
                        if(array&gt;max){
                                max = array;
                        }
                        if(array&lt;max){
                                return array;
                        }
                }
                return 0;
        }
}
</code></pre>
<h3 id="分法">⼆分法</h3>
<p>旋转之后的数组其实就是分成两段,⽐如 {3,4,5,1,2} ,可以看到, 3 , 4 , 5 是递增的,但是 5之后1 就是⽐之前的数⼩的,这样就可以找到最⼩值 1 。</p>
<p><img src="https://seven97-blog.oss-cn-hangzhou.aliyuncs.com/imgs/202503161734320.png" alt="" loading="lazy"></p>
<p>取出中间元素,和最右边元素⽐较,如果中间元素⼤于最右边元素,则证明,最⼩值存在于中间元素到最右边元素之间的⼀段。如果中间元素⼩于最右边元素,则证明,最⼩值在最左边元素到中间元素之间的⼀段中。</p>
<p>有⼀种特殊情况,就是相同元素,这样我们没有办法判断最⼩的元素位于哪⼀段,所以只能将右边的边界向左移动,即high-- 。</p>
<pre><code class="language-java">public class Solution {
    public static int minNumberInRotateArray(int[] array) {
      if (array == null || array.length == 0) {
              return 0;
      }
      
      if (array.length == 1) {
              return array;
      }
      
      int low = 0, high = array.length - 1;
      
      while (high - low &gt; 1) {
            int mid = (low + high) / 2;
            if (array &gt; array) {
                    low = mid;
            } else if (array &lt; array) {
                    high = mid;
            } else {
                    high--;
            }
      }
      return Math.min(array, array);
    }
}
</code></pre>
<ul>
<li>时间复杂度: ⼆分解法,为O(logN)</li>
<li>空间复杂度:没有开辟额外的空间,为 O(1)</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自在线网站:seven的菜鸟成长之路,作者:seven,转载请注明原文链接:www.seven97.top</p><br><br>
来源:https://www.cnblogs.com/sevencoding/p/18942361
頁: [1]
查看完整版本: 剑指offer-6、旋转数组的最小数字