算法(3):數(shù)組

??一鼓作氣,再而衰氮发,三而竭渴肉,第三篇走起!


數(shù)組(Array)

??數(shù)組是大家再熟悉不過(guò)的東西了爽冕,但是這里還是簡(jiǎn)單說(shuō)一下仇祭,數(shù)組是連續(xù)存放一系列元素的數(shù)據(jù)結(jié)構(gòu),我們可以方便的通過(guò)索引訪問(wèn)數(shù)組當(dāng)中的任何一個(gè)元素颈畸。通常乌奇,數(shù)組在定義時(shí)是固定大小的,但是也有一種動(dòng)態(tài)數(shù)組眯娱,它在初始化時(shí)不需要定義數(shù)組大小礁苗,也就意味著可以無(wú)限裝數(shù)據(jù),我們稱之為動(dòng)態(tài)數(shù)組徙缴,如C++當(dāng)中的Vector(曾經(jīng)是我最喜歡的一個(gè)數(shù)據(jù)結(jié)構(gòu)试伙,當(dāng)然,在我遇到python當(dāng)中的List之前)和Java當(dāng)中的ArrayList 于样。

安利一波問(wèn)題4疏叨,大家一定要看一看。


問(wèn)題1:找到一個(gè)一維數(shù)組的“中樞”元素的索引穿剖。如果有很多中樞元素考廉,則只需返回最左側(cè)的即可。中樞在此處意味著該索引左側(cè)元素和等于該索引右側(cè)元素和携御。
輸入: [1, 2, 8, 4, 5, 6]
輸出: 3(1+2+8 = 5+6)

代碼,那是異常的簡(jiǎn)單啊既绕。小編不禁想起了有一次面試啄刹,面試官讓我寫一個(gè)找數(shù)組中最大最小值的算法,啊凄贩,那時(shí)的時(shí)光是多么美好誓军!如下代碼的時(shí)間復(fù)雜度O(n),空間復(fù)雜度O(1)疲扎。

def pivotIndex(nums) -> int:
    ts, cs = sum(nums), 0
    for idx, num in enumerate(nums):
        ls, rs = cs, ts - cs - num
        if ls == rs:
            return idx
        cs += num
    return -1

if __name__ == '__main__':
    ans = pivotIndex([1, 2, 8, 4, 5, 6])
    print(ans)


問(wèn)題2:加1操作昵时。將輸入數(shù)組當(dāng)成一個(gè)整數(shù)捷雕,然后執(zhí)行加1操作
例子:
輸入: [1,2,3] 輸出: [1,2,4]
輸入: [9,9,9] 輸出: [1,0,0,0]

我的方法是直接在數(shù)組里面執(zhí)行操作,當(dāng)然你也可以換種方法壹甥,如把數(shù)組里元素按位讀出來(lái)變成int救巷,然后加一,然后在按位存放到數(shù)組中句柠。

def plusOne(digits: list) -> list:
    digits = [0] + digits
    for i in range(len(digits) - 1, -1, -1):
        if digits[i] == 9:
            digits[i] = 0
        else:
            digits[i] += 1
            break

    return (digits, digits[1:])[0 if digits[0] != 0 else 1]

if __name__ == '__main__':
    ans = plusOne([1, 2, 8, 4, 5, 6])
    print(ans)

問(wèn)題3:對(duì)角線遍歷二維數(shù)組(Diagonal Traverse)浦译。
一維數(shù)組一般都很簡(jiǎn)單,但是到了二維數(shù)組溯职,難度就會(huì)上升一個(gè)臺(tái)階精盅,畢竟,問(wèn)題的花樣變多了嘛~
輸入:[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
輸出: [1,2,4,7,5,3,6,8,9]
如果看不懂的話谜酒,可以配上下面這張圖看叹俏,保證一眼就明白~

對(duì)角線遍歷矩陣圖

代碼具體思路分為兩步:
step1:根據(jù)對(duì)角線將矩陣分組(可以發(fā)現(xiàn),同一對(duì)角線的矩陣row和col坐標(biāo)相加為定值)僻族,如上圖粘驰,可以分為5組,得到[1] , [2,4]鹰贵,[3,5,7]晴氨,[6,8],[9]碉输。
step2:按照(row + col)的大小順序?qū)?shù)據(jù)依次添加到結(jié)果列表當(dāng)中籽前。根據(jù)代碼定義,在(row + col )為偶數(shù)時(shí)敷钾,需要翻轉(zhuǎn)一下該組元素枝哄。即[3,5,7](此時(shí)row + col = 2)需要變?yōu)閇7,5,3]再添加到結(jié)果中。

import  collections
def findDiagonalOrder(matrix):
    """
    :type matrix: List[List[int]]
    :rtype: List[int]
    """
    result = []
    dd = collections.defaultdict(list)
    if not matrix: return result
    # Step 1: Numbers are grouped by the diagonals.
    # Numbers in same diagonal have same value of row+col
    for i in range(0, len(matrix)):
        for j in range(0, len(matrix[0])):
            dd[i + j].append(matrix[i][j])  # starting indices from 1, hence i+j+1.
    # Step 2: Place diagonals in the result list.
    # But remember to reverse numbers in odd diagonals.
    for k in sorted(dd.keys()):
        if k % 2 == 0: dd[k].reverse()
        result += dd[k]
    return result

if __name__ == '__main__':
    arr = [[ 1, 2, 3 ],[ 4, 5, 6 ],[ 7, 8, 9 ]]
    ans = findDiagonalOrder(arr)
    print(ans)

問(wèn)題4:旋轉(zhuǎn)矩陣(Spiral Matrix)阻荒,即返回一個(gè)矩陣順時(shí)針旋轉(zhuǎn)的結(jié)果挠锥。
輸入:
[ [ 1, 2, 3 ],
?[ 4, 5, 6 ],
?[ 7, 8, 9 ] ]
輸出:[1,2,3,6,9,8,7,4,5]

下面這個(gè)答案是我在網(wǎng)上找的,看到這個(gè)代碼之后的好久時(shí)間里侨赡,我的嘴巴只能發(fā)出“wo cao”這兩個(gè)音蓖租。。羊壹”突拢看到這段代碼,我仿佛戀愛(ài)了油猫。

def spiralOrder(matrix: list) -> list:
    return matrix and [*matrix.pop(0)] + spiralOrder([*zip(*matrix)][::-1])

if __name__ == '__main__':
    arr = [[ 1, 2, 3 ],[ 4, 5, 6 ],[ 7, 8, 9 ]]
    ans = spiralOrder(arr)
    print(ans)

問(wèn)題5:數(shù)組求和稠茂。給定一個(gè)升序排列的數(shù)組,找出兩個(gè)數(shù)情妖,其和等于輸入‘target’睬关,結(jié)果返回這兩個(gè)數(shù)的索引诱担。
輸入: numbers = [2,7,11,15], target = 9
輸出: [1,2]
我們?nèi)绻褂帽┝Ψǖ脑挘Y(jié)果有C^2_n種电爹,時(shí)間復(fù)雜度為O(n^2)蔫仙。那么大家還記不記得 有一招從天而降的掌法... 上一章講解的雙指針技術(shù)呢?這里便用到了藐不!兩個(gè)指針?lè)謩e從左和右開始向中間走匀哄,兩個(gè)數(shù)的和大了,右指針左移雏蛮,和偏小涎嚼,左指針右移......

# 四個(gè)問(wèn)題不吉利,小編拍胸脯保證挑秉,馬上(百年之內(nèi))把第五個(gè)問(wèn)題補(bǔ)起來(lái)法梯!
def twoSum(numbers: list, target: int) -> list:
    i, j = 0, len(numbers) - 1
    while i < j:
        if numbers[i] + numbers[j] == target:
            return [i, j]
        elif numbers[i] + numbers[j] > target:
            j -= 1
        else:
            i += 1
    return []

if __name__ == '__main__':
    numbers = [2, 7, 11, 15]
    target = 9
    ans = twoSum(numbers,target)
    print(ans)


問(wèn)題6:移除特定值(寫五道已經(jīng)達(dá)到我的標(biāo)準(zhǔn)了,奈何又看到一個(gè)較為經(jīng)典的案例犀概,那就......再來(lái)個(gè)雙指針教學(xué)吧~)立哑,將數(shù)組當(dāng)中等于’target'的值移除掉,空間復(fù)雜度限定為O(1)姻灶,最后結(jié)果返回新數(shù)組長(zhǎng)度铛绰。
例子:
輸入:[1,2,7,4,4,5],target = 4
輸出:4 (新數(shù)組為[1,2,7,5],所以長(zhǎng)度為4)
快指針遍歷數(shù)組产喉,慢指針則作為新數(shù)組的尾部捂掰。只有當(dāng)快指針?biāo)傅闹岛汀畉arget’不同時(shí),才會(huì)執(zhí)行賦值以及p+=1操作曾沈,相同時(shí)直接跳過(guò)該數(shù)这嚣。

def removeElement(numbers: list, target: int) -> int:
    p = 0
    for i in range(len(numbers)):
        if numbers[i] != target:
            numbers[p] = numbers[i]
            p +=1
    return p

if __name__ == '__main__':
    numbers = [1,7,3,4,4,5]
    target = 4
    ans = removeElement(numbers,target)
    print(ans)
    print(numbers[:ans])


問(wèn)題7:滿足要求的最小子數(shù)組(Minimum Size Subarray Sum)。不好意思我忍不住又添了一道......該題給定n只包含正整數(shù)的數(shù)組塞俱,以及一個(gè)整數(shù)s姐帚,要求是找到一個(gè)最小長(zhǎng)度的連續(xù)子數(shù)組,該子數(shù)組的元素和≥s障涯。 如果不存在罐旗,則返回0。
輸入: s = 7, nums = [2,3,1,2,4,3]
輸出: 2(子數(shù)組 [4,3] 是滿足題目約束的最小數(shù)組)
運(yùn)行下面程序會(huì)輸出每步變量信息唯蝶,大家可以自己讀讀試試尤莺,看能否理解~如果不理解可以留言探討,現(xiàn)在已經(jīng)晚上11點(diǎn)了生棍,小編扛不住,這道題就不寫分析了......

def minSubArrayLen( s: int, nums: list) -> int:
    total = left = 0
    result = len(nums) + 1
    for right, num in enumerate(nums):
        total += num
        while total >= s:
            result = min(result, right - left + 1)
            total -= nums[left]
            left += 1
            print('total:',total,'result:',result,'left:',left,'right:',right)
    return result if result <= len(nums) else 0

if __name__ == '__main__':
    numbers = [2,3,1,2,4,3]
    target = 7
    ans = minSubArrayLen(target,numbers)
    print(ans)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末媳谁,一起剝皮案震驚了整個(gè)濱河市涂滴,隨后出現(xiàn)的幾起案子友酱,更是在濱河造成了極大的恐慌,老刑警劉巖柔纵,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缔杉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡搁料,警方通過(guò)查閱死者的電腦和手機(jī)或详,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)郭计,“玉大人霸琴,你說(shuō)我怎么就攤上這事≌焉欤” “怎么了梧乘?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)庐杨。 經(jīng)常有香客問(wèn)我选调,道長(zhǎng),這世上最難降的妖魔是什么灵份? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任仁堪,我火速辦了婚禮,結(jié)果婚禮上填渠,老公的妹妹穿的比我還像新娘弦聂。我一直安慰自己,他們只是感情好揭蜒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布横浑。 她就那樣靜靜地躺著,像睡著了一般屉更。 火紅的嫁衣襯著肌膚如雪徙融。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天瑰谜,我揣著相機(jī)與錄音欺冀,去河邊找鬼。 笑死萨脑,一個(gè)胖子當(dāng)著我的面吹牛隐轩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渤早,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼职车,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起悴灵,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扛芽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后积瞒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體川尖,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年茫孔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叮喳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缰贝,死狀恐怖馍悟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情揩瞪,我是刑警寧澤赋朦,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站李破,受9級(jí)特大地震影響宠哄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嗤攻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一毛嫉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妇菱,春花似錦承粤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至房交,卻和暖如春彻舰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背候味。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工刃唤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人白群。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓尚胞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親帜慢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笼裳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354