0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言:LeetCode 153尋找旋轉(zhuǎn)排序數(shù)組中的最小值

如意 ? 來源:CSDN ? 作者:CaspianSea ? 2020-06-22 08:59 ? 次閱讀

假設(shè)按照升序排序的數(shù)組在預(yù)先未知的某個(gè)點(diǎn)上進(jìn)行了旋轉(zhuǎn)。

( 例如,數(shù)組 [0,1,2,4,5,6,7] 可能變?yōu)?[4,5,6,7,0,1,2] )。

請(qǐng)找出其中最小的元素。

你可以假設(shè)數(shù)組中不存在重復(fù)元素。

示例 1:

輸入: [3,4,5,1,2]

輸出: 1

示例 2:

輸入: [4,5,6,7,0,1,2]

輸出: 0

這道尋找最小值的題目可以用二分查找法來解決,時(shí)間復(fù)雜度為O(logN),空間復(fù)雜度為O(1)。

看一下代碼:

C語言:LeetCode 153尋找旋轉(zhuǎn)排序數(shù)組中的最小值

首先說一下主要思路:

單調(diào)遞增的序列:

*

*
*

*

*

做了旋轉(zhuǎn):

*

*

*

*

*

用二分法查找,需要始終將目標(biāo)值(這里是最小值)套住,并不斷收縮左邊界或右邊界。

左、中、右三個(gè)位置的值相比較,有以下幾種情況:

左值 《 中值, 中值 《 右值 :沒有旋轉(zhuǎn),最小值在最左邊,可以收縮右邊界

左值 》 中值, 中值 《 右值 :有旋轉(zhuǎn),最小值在左半邊,可以收縮右邊界

左值 《 中值, 中值 》 右值 :有旋轉(zhuǎn),最小值在右半邊,可以收縮左邊界

左值 》 中值, 中值 》 右值 :?jiǎn)握{(diào)遞減,不可能出現(xiàn)

分析前面三種可能的情況,會(huì)發(fā)現(xiàn)情況1、2是一類,情況3是另一類。

如果中值 《 右值,則最小值在左半邊,可以收縮右邊界。

如果中值 》 右值,則最小值在右半邊,可以收縮左邊界。

通過比較中值與右值,可以確定最小值的位置范圍,從而決定邊界收縮的方向。

而情況1與情況3都是左值 《 中值,但是最小值位置范圍卻不同,這說明,如果只比較左值與中值,不能確定最小值的位置范圍。

所以我們需要通過比較中值與右值來確定最小值的位置范圍,進(jìn)而確定邊界收縮的方向。

接著分析解法里的一些問題:

首先是while循環(huán)里的細(xì)節(jié)問題。

這里的循環(huán)不變式是left 《 right, 并且要保證左閉右開區(qū)間里面始終套住最小值。

中間位置的計(jì)算:mid = left + (right - left) / 2

這里整數(shù)除法是向下取整的地板除,mid更靠近left,

再結(jié)合while循環(huán)的條件left 《 right,

可以知道left 《= mid,mid 《 right,

即在while循環(huán)內(nèi),mid始終小于right。

因此在while循環(huán)內(nèi),nums[mid]要么大于要么小于nums[right],不會(huì)等于。

這樣else {right = mid;}這句判斷可以改為更精確的

else if (nums[mid] 《 nums[right]) {right = mid;}。

再分析一下while循環(huán)退出的條件。

如果輸入數(shù)組只有一個(gè)數(shù),左右邊界位置重合,left == right,不會(huì)進(jìn)入while循環(huán),直接輸出。

如果輸入數(shù)組多于一個(gè)數(shù),循環(huán)到最后,會(huì)只剩兩個(gè)數(shù),nums[left] == nums[mid],以及nums[right],這里的位置left == mid == right - 1。

如果nums[left] == nums[mid] 》 nums[right],則左邊大、右邊小,

需要執(zhí)行l(wèi)eft = mid + 1,使得left == right,左右邊界位置重合,循環(huán)結(jié)束,nums[left]與nums[right]都保存了最小值。

如果nums[left] == nums[mid] 《 nums[right],則左邊小、右邊大,

會(huì)執(zhí)行right = mid,使得left == right,左右邊界位置重合,循環(huán)結(jié)束,nums[left]、nums[mid]、nums[right]都保存了最小值。

細(xì)化了的代碼:

C語言:LeetCode 153尋找旋轉(zhuǎn)排序數(shù)組中的最小值

再討論一個(gè)問題:

為什么左右不對(duì)稱?為什么比較mid與right而不比較mid與left?能不能通過比較mid與left來解決問題?

左右不對(duì)稱的原因是:

這是循環(huán)前升序排列的數(shù),左邊的數(shù)小,右邊的數(shù)大,而且我們要找的是最小值,肯定是偏向左找,所以左右不對(duì)稱了。

為什么比較mid與right而不比較mid與left?

具體原因前面已經(jīng)分析過了,簡(jiǎn)單講就是因?yàn)槲覀冋易钚≈?,要偏向左找,目?biāo)值右邊的情況會(huì)比較簡(jiǎn)單,容易區(qū)分,所以比較mid與right而不比較mid與left。

那么能不能通過比較mid與left來解決問題?

能,轉(zhuǎn)換思路,不直接找最小值,而是先找最大值,最大值偏右,可以通過比較mid與left來找到最大值,最大值向右移動(dòng)一位就是最小值了(需要考慮最大值在最右邊的情況,右移一位后對(duì)數(shù)組長(zhǎng)度取余)。

以下是先找最大值的代碼,可以與前面找最小值的比較:

C語言:LeetCode 153尋找旋轉(zhuǎn)排序數(shù)組中的最小值

使用left 《 right作while循環(huán)條件可以很方便推廣到數(shù)組中有重復(fù)元素的情況,即154題:

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/

只需要在nums[mid] == nums[right]時(shí)挪動(dòng)右邊界就行:

初始條件是左閉右閉區(qū)間,right = nums.size() - 1,

那么能否將while循環(huán)的條件也選為左閉右閉區(qū)間left 《= right?

可以的,代碼如下:

C語言:LeetCode 153尋找旋轉(zhuǎn)排序數(shù)組中的最小值

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134092
  • leetcode
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

    2307
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    DAQmx的最大最小值的設(shè)定

    如何將與最大最小值相連的輸入控件控制旋鈕的最大最小值,即DAQmx中最大最小值的數(shù)值改變,旋鈕的最大最小值也跟著改變??急求啊
    發(fā)表于 08-08 10:45

    幫忙看看:數(shù)字排序數(shù)組

    如何按照?qǐng)D中數(shù)字排序數(shù)組簇~~謝謝
    發(fā)表于 06-12 10:45

    數(shù)組的最大最小值模塊輸出端的含義

    各位大神,那個(gè)最大索引,最小索引是什么意思?如果數(shù)組是一位數(shù)組,索引出來的是最大最小值的位置?
    發(fā)表于 04-22 09:46

    labview數(shù)組全是負(fù)數(shù)最大最小值顯示不對(duì)

    labview數(shù)組全是負(fù)數(shù)最大最小值就會(huì)變反怎么回事,(最大變成最小值,最小值變成最大
    發(fā)表于 06-27 14:43

    一維數(shù)組找出最小值及它的位置索引,其實(shí)如果只是這樣還好,但它要所有索引位置(如果有多個(gè)最小值

    查找一個(gè)一維數(shù)組最小值,以及最小值數(shù)組的位置索引,如果有多個(gè)最小值,找到所有
    發(fā)表于 10-19 17:12

    C語言教程之查找數(shù)組的最

    C語言教程之查找數(shù)組的最,很好的C語言資料,快來
    發(fā)表于 04-25 15:13 ?0次下載

    C語言教程之求數(shù)組元素最小值

    C語言教程之求數(shù)組元素最小值,很好的C語言資料,
    發(fā)表于 04-25 16:09 ?0次下載

    C語言教程之對(duì)數(shù)組進(jìn)行升序和降序排序

    C語言教程之對(duì)數(shù)組進(jìn)行升序和降序排序,很好的C語言資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-25 16:09 ?0次下載

    C語言leetcode 35搜索插入位置

    給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值,在數(shù)組中找到目標(biāo)值,并返回其索引。如果目標(biāo)值不存在于數(shù)組,返回它將會(huì)被按順序插入的位置。
    的頭像 發(fā)表于 06-22 08:40 ?1576次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>leetcode</b> 35搜索插入位置

    C語言: Leetcode 33搜索旋轉(zhuǎn)排序數(shù)組

    假設(shè)按照升序排序數(shù)組在預(yù)先未知的某個(gè)點(diǎn)上進(jìn)行了旋轉(zhuǎn)。
    的頭像 發(fā)表于 06-22 08:51 ?1588次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>: <b class='flag-5'>Leetcode</b> 33搜索<b class='flag-5'>旋轉(zhuǎn)</b><b class='flag-5'>排序數(shù)組</b>

    AD629A SPICE宏模型最小值

    AD629A SPICE宏模型最小值
    發(fā)表于 04-13 20:53 ?12次下載
    AD629A SPICE宏模型<b class='flag-5'>最小值</b>

    AD629A SPICE宏模型最小值

    AD629A SPICE宏模型最小值
    發(fā)表于 06-17 11:32 ?1次下載
    AD629A SPICE宏模型<b class='flag-5'>最小值</b>

    C語言總結(jié)_數(shù)組全方位練習(xí)

    C語言數(shù)組的練習(xí)題:涉及到數(shù)組插入、數(shù)組刪除、數(shù)組下標(biāo)數(shù)據(jù)的左移右移、
    的頭像 發(fā)表于 08-14 09:34 ?808次閱讀

    C語言_數(shù)組的查找、替換、排序、拼接

    這篇文章主要是總結(jié)C語言的位運(yùn)算幾個(gè)實(shí)戰(zhàn)例子,接著介紹數(shù)組的基本定義用法、數(shù)組排序、插入、拼接、刪除、字符串查找替換等。
    的頭像 發(fā)表于 08-14 09:48 ?2431次閱讀

    C 語言數(shù)組的基本結(jié)構(gòu)

    數(shù)組是最基本的數(shù)據(jù)結(jié)構(gòu),關(guān)于數(shù)組的面試題也屢見不鮮,本文羅列了一些常見的面試題,僅供參考。目前有以下18道題目。 數(shù)組求和 求數(shù)組的最大
    的頭像 發(fā)表于 06-22 10:56 ?505次閱讀