Q503 Next Greater Element II

Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.

Example 1:
Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1's next greater number is 2; 
The number 2 can't find next greater number; 
The second 1's next greater number needs to search circularly, which is also 2.

Note: The length of given array won't exceed 10000.

解題思路:

題意為:給一個(gè)循環(huán)列表(最后一個(gè)元素與第一個(gè)元素相同)拦宣,求出列表中每個(gè)元素的下一個(gè)較大的元素是什么(最大值沒(méi)有下一個(gè)較大的元素,對(duì)應(yīng)位置為-1)祥国。

以 nums = [100,9,1,11,1,120,111,123,1,-1,-100,103,98,100] 為例阁谆,我們可以觀察到幾個(gè)性質(zhì):

  • 在最大值(123)左側(cè)碳抄,如果前面的數(shù)比后面的數(shù)小,則把后面的數(shù)當(dāng)做較大值(如 9 < 11)场绿;
  • 在最大值(123)右側(cè)剖效,如果一直到列表結(jié)束都找不到較大的數(shù)(如103),則需要重新再遍歷一次列表焰盗,找到下一個(gè)較大的數(shù)(120)璧尸。
  1. 思路一:
  • 設(shè)置兩個(gè)指針 i 和 j,i 始終指向當(dāng)前元素熬拒。然后爷光,將 nums 擴(kuò)寬 2 倍,j 每次指向下一個(gè)較大的元素澎粟。當(dāng) i 的指針達(dá)到原 nums 的長(zhǎng)度蛀序,則退出循環(huán)。注意活烙,當(dāng) i 指向 103徐裸,j 向后找到 120,然后啸盏,j 還要回退到 i 的下一個(gè)位置重贺,不然,98就找不到下一個(gè)較大的數(shù) 100。這種情況下檬姥,最壞時(shí)間復(fù)雜度為 O(n^2)曾我,Python3 版本會(huì)超時(shí)(C++ 和 Java不會(huì))。
  1. 思路二:
  • 使用一個(gè)棧健民,遍歷列表抒巢,棧中存放還未確定下一個(gè)較大元素的下標(biāo),如果遇到一個(gè)較大的數(shù)秉犹,則進(jìn)入一個(gè)新的循環(huán)蛉谜,把未確定的元素出棧,直到棧中留下的元素比當(dāng)前的元素大崇堵。(比如型诚,[100,9,1] 都先放入棧中,因?yàn)樗鼈兌歼€未找到較大的元素鸳劳,下一次狰贯,遇到 11,則 1 比 11 小赏廓,1 出棧涵紊;此時(shí)繼續(xù)循環(huán)判斷棧中的 9, 9 也比 11 小,9 出棧幔摸;100 比 11 大摸柄,則棧中元素不能在確定下一個(gè)較大的元素了,則 11 入棧既忆,繼續(xù)遍歷列表)驱负。
  • 當(dāng)一次遍歷結(jié)束后,只有 [123,103,100] 還在棧中患雇。這時(shí)跃脊,只需要重新再次遍歷一遍列表,100 比 120 小庆亡,出棧匾乓;103 比 120 小捞稿,出棧又谋;直到再次遇到最大數(shù)123,則循環(huán)結(jié)束娱局。
  • 因?yàn)椴簧婕爸羔樆赝苏煤ィ瑒t時(shí)間復(fù)雜度 O(n),但空間復(fù)雜度 O(n)
Python 實(shí)現(xiàn):
class Solution:
    # 超時(shí)版本:最壞時(shí)間復(fù)雜度為 O(n^2)
    def nextGreaterElements(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        lens = len(nums)
        if lens == 0:
            return []
        maxnum = max(nums)  # nums 中的最大值
        nums = nums + nums  # 將 nums 擴(kuò)展成 2 倍長(zhǎng)
        ret = []  # 返回值
        i = j = 0 # i 指向當(dāng)前數(shù)衰齐,j 指向下一個(gè)較大數(shù)
        while i < lens:
            if nums[i] == maxnum: # 最大值位置直接為 -1
                ret.append(-1)
                i += 1; j += 1
            elif nums[i] < nums[j]:
                ret.append(nums[j])
                i += 1; j = i + 1  # j 指針回退
            else:
                j += 1
        return ret

    # AC版本:最壞時(shí)間復(fù)雜度為 O(n)任斋,但空間復(fù)雜度也為 O(n)
    def nextGreaterElements2(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        lens = len(nums)
        if lens == 0:
            return []
        maxnum = max(nums)  # nums 中的最大值
        ret = [-1] * lens   # 返回值
        stack = []  # 存儲(chǔ)還未確定的下一個(gè)較大數(shù)的元素
        for i in range(lens):
            while stack and nums[stack[-1]] < nums[i]:
                ret[stack.pop()] = nums[i]
            stack.append(i)
        # print(stack)

        for i in range(lens):
            while stack and nums[stack[-1]] < nums[i]:
                ret[stack.pop()] = nums[i]
            if maxnum == nums[i]:
                break
        return ret

a = [3,1,4,2,5,3]
a = [3,5,4,2,5,1,3]
a = [3,1,5,4,6,5,2,6,5,4,3]
a = [6,5,3,1,4,5,6,7,6,5,4,3,2,6]
a = [100,9,1,11,1,120,111,123,1,-1,-100,103,98,100]
print(Solution().nextGreaterElements2(a)) 
# [120, 11, 11, 120, 120, 123, 123, -1, 103, 103, 103, 120, 100, 120]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耻涛,隨后出現(xiàn)的幾起案子废酷,更是在濱河造成了極大的恐慌瘟檩,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澈蟆,死亡現(xiàn)場(chǎng)離奇詭異墨辛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)趴俘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門睹簇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人寥闪,你說(shuō)我怎么就攤上這事太惠。” “怎么了疲憋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵凿渊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我缚柳,道長(zhǎng)嗽元,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任喂击,我火速辦了婚禮剂癌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翰绊。我一直安慰自己佩谷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布监嗜。 她就那樣靜靜地躺著谐檀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裁奇。 梳的紋絲不亂的頭發(fā)上桐猬,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音刽肠,去河邊找鬼溃肪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛音五,可吹牛的內(nèi)容都是我干的惫撰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躺涝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厨钻!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤夯膀,失蹤者是張志新(化名)和其女友劉穎诗充,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體诱建,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡其障,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涂佃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片励翼。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辜荠,靈堂內(nèi)的尸體忽然破棺而出汽抚,到底是詐尸還是另有隱情,我是刑警寧澤伯病,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布造烁,位于F島的核電站,受9級(jí)特大地震影響午笛,放射性物質(zhì)發(fā)生泄漏惭蟋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一药磺、第九天 我趴在偏房一處隱蔽的房頂上張望告组。 院中可真熱鬧,春花似錦癌佩、人聲如沸木缝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)我碟。三九已至,卻和暖如春姚建,著一層夾襖步出監(jiān)牢的瞬間矫俺,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工掸冤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厘托,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓贩虾,卻偏偏與公主長(zhǎng)得像催烘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缎罢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容