字節(jié)跳動(dòng)iOS面試算法題——當(dāng)前數(shù)組中沒有的最小正整數(shù)

背景

社畜初級(jí)程序員面試頭條iOS開發(fā)鲸鹦,被完虐。其中一個(gè)算法題如下:

給定一個(gè)整數(shù)數(shù)組覆积,輸出當(dāng)前數(shù)組中沒有的最小正整數(shù)

示例1

輸入:[0, -1, 1, -4, 5, 6, 10]

輸出:2

示例2

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

輸出:6

分析

暴力破解

首先想到的就是暴力遍歷法庵朝,即從1開始在數(shù)組中比較搜索椎瘟,直到在數(shù)組中沒有找到。其代碼實(shí)現(xiàn)如下:

// swift實(shí)現(xiàn)
func findMissMinUnsignedIntValue(_ nums: [Int]) -> Int {
  let size = nums.count
    var i = 1
    while i <= size {
        var j = 0
        for index in 0..<size {
            if i == nums[index] {
                break
            }
            j += 1
        }
        if j == size {
            return i
        }
        i += 1
    }
    
    return i
}

暴力算法由于需要嵌套遍歷N次汰蜘,所以其時(shí)間復(fù)雜度是O(N^2),空間復(fù)雜度是O(1)

先排序泼舱,在搜索

由于給定的數(shù)組是未排序的,而我們需要找的是未出現(xiàn)最小的整數(shù)危喉,所以可以先進(jìn)行排序,然后在遍歷這個(gè)數(shù)組找到未出現(xiàn)的最小整數(shù)氧急。

其實(shí)現(xiàn)代碼如下:

// swift實(shí)現(xiàn)
func findMissMinUnsignedIntValue(_ nums: [Int]) -> Int {
    let size = nums.count
    var sortNums = nums;
    sortNums.sort() // 先進(jìn)行排序,排序的最快時(shí)間復(fù)雜度是O(N*logN)
    
    var retValue = 1
    for index in 0..<size {
        if sortNums[index] <= 0 {
            continue
        } else {
            if sortNums[index] != retValue {
                return retValue
            }
            retValue += 1
        }
    }
    
    return retValue
}

先排序后查找的算法時(shí)間復(fù)雜度是有排序和遍歷決定的钉寝,即為O(NlogN) +O(N)腥沽,所以其時(shí)間復(fù)雜度為O(NlogN)师溅,空間復(fù)雜度為O(1)**

使用緩存

這是一種空間換時(shí)間的方法矿筝,我們可以創(chuàng)建一個(gè)大小為N(N是原始數(shù)組的大小)數(shù)組進(jìn)行來標(biāo)記是否出現(xiàn)過該整數(shù)鼻疮。其原理如下:

min_Int_01.png

實(shí)現(xiàn)代碼如下:

func findMissMinUnsignedIntValue(_ nums: [Int]) -> Int {
    let size = nums.count
    if size == 0 {
        return 1
    }
    
    var flags: [Int] = Array(repeating: 0, count: size)
    for index in 0..<size {
        if nums[index] >= 0 && nums[index] < size {
            flags[nums[index]] = 1
        }
    }
    
    for index in 0..<flags.count {
        if flags[index] == 0 {
            return index
        }
    }
    
    return size
}

有代碼可知琉闪,我們只遍歷了一次原始數(shù)組斯入,但是同時(shí)創(chuàng)建了一個(gè)大小為N的數(shù)組進(jìn)行標(biāo)記闹伪,所以其時(shí)間復(fù)雜度為O(N),控件復(fù)雜度為O(N)

緩存思想,不使用額外的空間

前面我們使用了一個(gè)額外的數(shù)組進(jìn)行標(biāo)記,如果不使用額外的數(shù)組,應(yīng)該如何進(jìn)行標(biāo)記呢?

那么我們只能在本身的數(shù)組上進(jìn)行操作了,這里我們可以利用本身整數(shù)的特性,正數(shù)和負(fù)數(shù)來進(jìn)行標(biāo)記恼布。基本步驟如下;

  • 將原始數(shù)組小于等于0的數(shù)奸忽,都置為N+1富俄。
  • 遍歷數(shù)組悠瞬,將數(shù)組值對應(yīng)位置的值標(biāo)記成負(fù)數(shù),注意在取值時(shí)晾捏,要取絕對值。
  • 遍歷數(shù)組,第一個(gè)不為負(fù)數(shù)的值的下標(biāo)即是未出現(xiàn)的最小整數(shù)。

原理如下:

min_Int_02.png

代碼如下:

func findMissMinUnsignedIntValue_cache2(_ nums: [Int]) -> Int {
    let size = nums.count
    if size == 0 {
        return 1
    }
    
    var mutableNums = nums
    // 1.將負(fù)數(shù)置為正數(shù)N+1
    for index in 0..<size {
        if mutableNums[index] <= 0 {
            mutableNums[index] = size + 1
        }
    }
    
    // 2. 將對應(yīng)元素的值索引位置的值置為負(fù)數(shù)
    for index in 0..<size {
        let tmpNum = abs(mutableNums[index])
        if tmpNum <= size {
            mutableNums[tmpNum - 1] = -abs(mutableNums[tmpNum - 1])
        }
    }
    
    // 3. 找到第一個(gè)>=0的位置索引
    for index in 0..<size {
        if mutableNums[index] > 0 {
            return index + 1
        }
    }
    
    return size + 1
}

該算法是使用自身數(shù)組作為緩存處理帮寻,所以其時(shí)間復(fù)雜度為O(N),空間復(fù)雜度為O(1)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末长捧,一起剝皮案震驚了整個(gè)濱河市肌割,隨后出現(xiàn)的幾起案子帐要,更是在濱河造成了極大的恐慌摩渺,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挥萌,死亡現(xiàn)場離奇詭異榨馁,居然都是意外死亡珍剑,警方通過查閱死者的電腦和手機(jī)饰序,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蚊逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人箫章,你說我怎么就攤上這事烙荷。” “怎么了檬寂?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵终抽,是天一觀的道長。 經(jīng)常有香客問我桶至,道長昼伴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任镣屹,我火速辦了婚禮圃郊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘女蜈。我一直安慰自己持舆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布伪窖。 她就那樣靜靜地躺著逸寓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪覆山。 梳的紋絲不亂的頭發(fā)上席覆,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機(jī)與錄音汹买,去河邊找鬼佩伤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晦毙,可吹牛的內(nèi)容都是我干的生巡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼见妒,長吁一口氣:“原來是場噩夢啊……” “哼孤荣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起须揣,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤盐股,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后耻卡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疯汁,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年卵酪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幌蚊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谤碳。...
    茶點(diǎn)故事閱讀 38,664評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖溢豆,靈堂內(nèi)的尸體忽然破棺而出蜒简,到底是詐尸還是另有隱情,我是刑警寧澤漩仙,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布搓茬,位于F島的核電站,受9級(jí)特大地震影響队他,放射性物質(zhì)發(fā)生泄漏垮兑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一漱挎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雀哨,春花似錦磕谅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捌浩,卻和暖如春放刨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尸饺。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工进统, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浪听。 一個(gè)月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓螟碎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迹栓。 傳聞我的和親對象是個(gè)殘疾皇子掉分,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評論 2 349