數組中重復的數字——jzoffer

棧是一個與遞歸緊密相關的數據結構(深度優(yōu)先遍歷),同樣隊列也與廣度優(yōu)先遍歷算法緊密相關浪读。
數組中的內存是連續(xù)的盟蚣,于是可以根據下標在O(1)時間讀/寫任何元素,可以用數組實現簡單的哈希表(字典)故爵,既可以將下標設置為key,也可以將元素值設置為key(如果元素不重復的話)隅津;
為了解決數組空間效率不高的問題诬垂,人們設計實現了動態(tài)數組,為了避免浪費伦仍,我們先為數組開辟小的空間结窘,然后往數組中添加數據,當數組的數目超過一個閾值(跟當前數組長度有關)充蓝,我們再重新分配更大的空間(C++的STL中的vector每次擴容隧枫,新的容量是前一次的兩倍)。但是每一次擴充數組容量時都有大量的額外操作谓苟,對時間性能有負面影響官脓,因此使用動態(tài)數組時,盡量減少改變數組容量大小的操作涝焙。

問題:長度為n的數組卑笨,數組在0~n-1的范圍內,存在重復數字仑撞,不知道重復次數赤兴,不知道幾個重復數字妖滔,請找出任意一個。

方法一:從排序后的數組中查找桶良,排序的話使用快速排序或者歸并排序座舍,時間復雜度為O(nlogn)

# 我的錯誤答案
def sort_(seq, begin, end):
    if len(seq) < 2:
        return seq
    pivot = get_pivot(seq, begin, end)
    left_side = sort_(seq, begin, pivot)
    right_side = sort_(seq, pivot+1, end)
    return left_side + seq[pivot] + right_side
def get_pivot(seq, begin, end):
    pivot = 0
    pivot_value = seq[0]
    left = 1
    right = len(seq) - 1
    while left < right:
        while seq[left] < pivot_value and left < right:
            left += 1
        while seq[right] > pivot_value and right > left:
            right -= 1
        seq[left], seqp[right] = seq[right], seq[left]
    seq[left], seq[pivot] = seq[pivot], seqp[left]
        
# pythonic方式
def sort_(seq):
    if len(seq) < 2:
        return seq
    pivot = 0
    pivot_value = seq[0]
    left_side = [seq[i] for i in seq[1:] if seq[i] < pivot_value]
    right_side = [seq[i] for i in seq[1:] if seq[i] >= pivot_value]
    return sort_(left_side) +[pivot_value] + sort_(right_side)

# 節(jié)省空間的方法,實現inplace排序
def sort_(seq, beg, end):
    if beg < end:
        pivot = get_pivot(seq, begin, end)
        sort_(seq, begin, pivot)
        sort_(seq, pivot+1, end)
def get_pivot(seq, begin, end):
    pivot = begin
    pivot_value = seq[begin]
    left = begin + 1
    right = end
    while True:
        while seq[left] < pivot_value and left <= right:
            left += 1
        while seq[right] > pivot_value and left <= right:
            right += 1
        if left > right:
            break
        else:
            seq[left], seq[right] = seq[right], seq[left]
    seq[right], seq[pivot] = seq[pivot], seq[right]
    return right

方法二:遍歷數組陨帆,將元素放到哈希表中曲秉,如果哈希表中包含元素,就返回該元素疲牵,時間復雜度為O(n)岸浑,需要一個大小為O(n)的哈希表作為代價

def get_multi(seq):
    d = {}
    for k, v in enumerate(seq):
        if v not in d:
            d[v] = k
        else:
            print (k, v)
            break

方法三:時間復雜度為O(n),空間復雜度為O(1)

def get_multe(seq):
    for i in xrange(len(seq)):
        if seq[i] < 0 or seq[i] > len(seq) - 1:
            raise Exception("nonono")
    for index, value in enumerate(seq):
        while seq[index] != index:
            if seq[value] == value:
                return value
            else:
                seq[index], seq[value] = seq[value], seq[index]

不修改數組找出重復數字

在一個長度為n+1的數組里瑰步,所有數字都在1~n的范圍內矢洲,所以數組至少有一個數字是重復的。請找出任意一個缩焦,但是不能修改輸入的數組读虏。

我的想法:

利用額外的空間,比如上面的通過hash表來查找重復數字袁滥,這樣的話代價是空間復雜度O(1)

答案的想法:

針對1~n范圍內的數盖桥,如果在數組中存在大于n個,代表有重復题翻;

通過二分法做這個判斷揩徊,但是無法找到全部的重復數字,比如1~2范圍內兩個數字嵌赠,數組中有[1, 1]就無法拿出重復數字1

class Solution(object):
    def count_(self, seq, length, beg, end):
        if beg > end:
            raise Exceptino("wrong")
        count = 0
        for i in range(length):
            if seq[i] >= beg and seq[i] <= end:
                count += 1
        return count
    
    # 我的思路
    def get_multi(self, seq, beg, end):
        mid = (end - beg) / 2
        # mid = (end - beg) >> 1
        count_all = self.count_(seq, beg, end)
        if end == beg and count_all > 1:
            return True
        while beg <= end:
            count_left = self.count_(seq, beg, mid)
            left = mid - beg + 1
            count_right = self.count_(seq, mid+1, end)
            right = end - mid
            if count_ > left or :
    # 答案
    def get_multi(self, seq, length):
        if len(seq) == 0 or length <= 0:
            raise Exception("wrong")
        beg = 1
        end = length - 1
        while beg <= end:
            mid = (end - beg) >> 1 + beg
            count_all = self.count_(seq, length, beg, mid)
            if end == beg:
                if count_all > 1:
                    return beg
                else:
                    break
            if count_all > mid - beg + 1:
                end = mid
            else:
                beg = mid + 1
         return False
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末塑荒,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子姜挺,更是在濱河造成了極大的恐慌齿税,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炊豪,死亡現場離奇詭異凌箕,居然都是意外死亡,警方通過查閱死者的電腦和手機词渤,發(fā)現死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門牵舱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缺虐,你說我怎么就攤上這事芜壁。” “怎么了真仲?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵止吁,是天一觀的道長。 經常有香客問我,道長腰涧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任紊浩,我火速辦了婚禮窖铡,結果婚禮上,老公的妹妹穿的比我還像新娘坊谁。我一直安慰自己费彼,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布口芍。 她就那樣靜靜地躺著箍铲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鬓椭。 梳的紋絲不亂的頭發(fā)上颠猴,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機與錄音小染,去河邊找鬼翘瓮。 笑死,一個胖子當著我的面吹牛裤翩,可吹牛的內容都是我干的资盅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼踊赠,長吁一口氣:“原來是場噩夢啊……” “哼呵扛!你這毒婦竟也來了?” 一聲冷哼從身側響起筐带,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤择份,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烫堤,有當地人在樹林里發(fā)現了一具尸體荣赶,經...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年鸽斟,在試婚紗的時候發(fā)現自己被綠了拔创。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡富蓄,死狀恐怖剩燥,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤灭红,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布侣滩,位于F島的核電站,受9級特大地震影響变擒,放射性物質發(fā)生泄漏君珠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一娇斑、第九天 我趴在偏房一處隱蔽的房頂上張望策添。 院中可真熱鬧,春花似錦毫缆、人聲如沸唯竹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浸颓。三九已至,卻和暖如春旺拉,著一層夾襖步出監(jiān)牢的瞬間产上,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工账阻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒂秘,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓淘太,卻偏偏與公主長得像姻僧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蒲牧,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內容

  • 一些概念 數據結構就是研究數據的邏輯結構和物理結構以及它們之間相互關系撇贺,并對這種結構定義相應的運算,而且確保經過這...
    Winterfell_Z閱讀 5,700評論 0 13
  • 靜靜 白露未晞(何一諾) 仰望 花兒紛飛的時光 觀察 月兒變化的時刻 氣球里的夢滿的裝不下, 只能由朱塔來往里面撒...
    柳動蟬鳴閱讀 296評論 0 3
  • 從前車馬很慢,書信很遠挎扰,一生只夠愛一個人翠订,如今,相擁遵倦、相忘都會在一剎那間尽超,轉瞬便可消失在彼此的生命里,兩不相欠梧躺,亦...
    Morfee莫菲閱讀 749評論 0 1
  • 先說下昨天我所遇到的情況,在做某個平臺接口對接的時候,因為要把這個平臺的接口所得到的某個對象賦值給自己項目的對象(...
    小農夢閱讀 526評論 0 0