LeetCode第107場(chǎng)周賽題解

925. 長(zhǎng)按鍵入

  • 題目難度Easy

你的朋友正在使用鍵盤(pán)輸入他的名字 name。偶爾杨拐,在鍵入字符 c 時(shí)棕所,按鍵可能會(huì)被長(zhǎng)按糊肠,而字符可能被輸入 1 次或多次辨宠。

你將會(huì)檢查鍵盤(pán)輸入的字符 typed。如果它對(duì)應(yīng)的可能是你的朋友的名字(其中一些字符可能被長(zhǎng)按)货裹,那么就返回 True嗤形。

示例 1:

輸入:name = "alex", typed = "aaleex"
輸出:true
解釋:'alex' 中的 'a' 和 'e' 被長(zhǎng)按。

示例 2:

輸入:name = "saeed", typed = "ssaaedd"
輸出:false
解釋:'e' 一定需要被鍵入兩次弧圆,但在 typed 的輸出中不是這樣派殷。

示例 3:

輸入:name = "leelee", typed = "lleeelee"
輸出:true

示例 4:

輸入:name = "laiden", typed = "laiden"
輸出:true
解釋:長(zhǎng)按名字中的字符并不是必要的还最。

提示:

  1. name.length <= 1000
  2. typed.length <= 1000
  3. nametyped 的字符都是小寫(xiě)字母。

思路:

  1. 兩個(gè)指針?lè)謩e指向nametyped毡惜,如果字符相等拓轻,就都右移一;
  2. 如果不等经伙,檢查typed中字符是否重復(fù)扶叉,如果不重復(fù)直接返回False,如果重復(fù)就一直指針一直右移到不重復(fù)為止帕膜;
  3. 重復(fù)前兩個(gè)步驟直到其中一個(gè)指針遍歷完成枣氧,如果name未遍歷完成而typed遍歷完成了,那么返回False垮刹,如果typed未遍歷完成而name遍歷完成了达吞,那么要判斷是否typed后面多余的字符都是name的最后一個(gè)字符,是則返回True荒典,否則返回False酪劫。

時(shí)間復(fù)雜度O(N)?

空間復(fù)雜度O(1)

代碼:

class Solution:
    def isLongPressedName(self, name: str, typed: str) -> bool:
        p1 = 0
        p2 = 0
        while p1 < len(name) and p2 < len(typed):
            if name[p1] == typed[p2]:
                p1 += 1
                p2 += 1
            elif p2 > 0 and typed[p2] == typed[p2 - 1]:
                p2 += 1
            else:
                return False
        if p1 < len(name):
            return False
        while p2 < len(typed):
            if typed[p2] != typed[p2 - 1]:
                return False
            p2 += 1
        return True

926. 將字符串翻轉(zhuǎn)到單調(diào)遞增

  • 題目難度Medium

如果一個(gè)由 '0''1' 組成的字符串,是以一些 '0'(可能沒(méi)有 '0')后面跟著一些 '1'(也可能沒(méi)有 '1')的形式組成的寺董,那么該字符串是單調(diào)遞增的覆糟。

我們給出一個(gè)由字符 '0''1' 組成的字符串 S,我們可以將任何 '0' 翻轉(zhuǎn)為 '1' 或者將 '1' 翻轉(zhuǎn)為 '0'遮咖。

返回使 S 單調(diào)遞增的最小翻轉(zhuǎn)次數(shù)滩字。

示例 1:

輸入:"00110"
輸出:1
解釋:我們翻轉(zhuǎn)最后一位得到 00111.

示例 2:

輸入:"010110"
輸出:2
解釋:我們翻轉(zhuǎn)得到 011111,或者是 000111御吞。

示例 3:

輸入:"00011000"
輸出:2
解釋:我們翻轉(zhuǎn)得到 00000000麦箍。

提示:

  1. 1 <= S.length <= 20000
  2. S 中只包含字符 '0''1'

思路:

本題有多種思路

  1. cnt0[i]表示第i位(包含)之前有多少個(gè)0,那么我們只需要尋找一個(gè)分割點(diǎn)i陶珠,讓i之前的1i之后的0數(shù)目之和最小挟裂。
  2. 從頭遍歷,從第一個(gè)1開(kāi)始0的數(shù)目和1的數(shù)目賽跑背率,每次0的數(shù)目超過(guò)1的數(shù)目翻轉(zhuǎn)前面的所有1,再找到下一個(gè)1從新計(jì)數(shù)嫩与,以此類推寝姿。最后0的數(shù)目不超過(guò)1的數(shù)目翻轉(zhuǎn)后面剩下的0。程序中只需要計(jì)數(shù)划滋,不需要真實(shí)的翻轉(zhuǎn)饵筑。
  3. 某一位為1時(shí),前面一位是0或者1都可以处坪;某一位為0時(shí)根资,前面一位只能為0架专。
  4. one表示到第i位為止1的個(gè)數(shù),用d表示1的個(gè)數(shù)減去0的個(gè)數(shù)玄帕,遍歷時(shí)維護(hù)d的最小值部脚,即可得到結(jié)果為d + len(S) - one

時(shí)間復(fù)雜度O(N)

空間復(fù)雜度O(N)

代碼:

class Solution:
    def minFlipsMonoIncr(self, S: str) -> int:
        l = len(S)
        cnt0 = [0] * (l + 1)
        for i in range(l):
            cnt0[i + 1] = cnt0[i]
            if S[i] == "0":
                cnt0[i + 1] += 1
        ans = l - cnt0[l]
        for i in range(l):
            ans = min(ans, i - cnt0[i] + cnt0[l] - cnt0[i])
        return ans

解法2:

class Solution:
    def minFlipsMonoIncr(self, S: str) -> int:
        p, ans, zero, one = 0, 0, 0, 0
        while p < len(S):
            if S[p] == '1':
                one += 1
            elif one > 0:
                zero += 1
            if zero > one:
                ans += one
                zero, one = 0, 0
            p += 1
        return ans + zero

解法3:

class Solution:
    def minFlipsMonoIncr(self, S: str) -> int:
        zero, one = 0, 0
        for i in S:
            if i == '1':
                one = min(zero, one)
                zero += 1
            else:
                one = min(zero, one) + 1
        return min(zero, one)

解法4:

class Solution:
    def minFlipsMonoIncr(self, S: str) -> int:
        one, d = 0, 0
        for i in range(0, len(S)):
            if S[i] == '1':
                one += 1
            elif d > one - (i + 1 - one):
                d = one - (i + 1 - one)
        return d + len(S) - one

927. 三等分

  • 題目難度Hard

給定一個(gè)由 01 組成的數(shù)組 A裤纹,將數(shù)組分成 3 個(gè)非空的部分委刘,使得所有這些部分表示相同的二進(jìn)制值。

如果可以做到鹰椒,請(qǐng)返回任何 [i, j]锡移,其中 i+1 < j,這樣一來(lái):

  • A[0], A[1], ..., A[i] 組成第一部分漆际;
  • A[i+1], A[i+2], ..., A[j-1] 作為第二部分淆珊;
  • A[j], A[j+1], ..., A[A.length - 1] 是第三部分。
  • 這三個(gè)部分所表示的二進(jìn)制值相等奸汇。

如果無(wú)法做到施符,就返回 [-1, -1]

注意茫蛹,在考慮每個(gè)部分所表示的二進(jìn)制時(shí)操刀,應(yīng)當(dāng)將其看作一個(gè)整體。例如婴洼,[1,1,0] 表示十進(jìn)制中的 6骨坑,而不會(huì)是 3。此外柬采,前導(dǎo)零也是被允許的欢唾,所以 [0,1,1][1,1] 表示相同的值。

示例 1:

輸入:[1,0,1,0,1]
輸出:[0,3]

示例 2:

輸出:[1,1,0,1,1]
輸出:[-1,-1]

提示:

  1. 3 <= A.length <= 30000
  2. A[i] == 0A[i] == 1

思路:

直接模擬判斷:首先統(tǒng)計(jì)1的個(gè)數(shù)粉捻,如果1的個(gè)數(shù)不是3的倍數(shù)礁遣,那么直接返回?zé)o解;如果數(shù)組中沒(méi)有1肩刃,那么直接返回[0, 2]祟霍。否則按照1的個(gè)數(shù)來(lái)劃分?jǐn)?shù)組,判斷表示的二進(jìn)制是否相等盈包,注意最后一個(gè)數(shù)有多少個(gè)結(jié)尾0沸呐。

時(shí)間復(fù)雜度O(N)

空間復(fù)雜度O(N)?

代碼:

class Solution:
    def threeEqualParts(self, A: List[int]) -> List[int]:
        
        def check(A1, A2, A3):
            if not len(A1) == len(A2) == len(A3):
                return False
            for i in range(len(A1)):
                if not A1[i] == A2[i] == A2[i]:
                    return False
            return True
        
        cnt1 = 0
        for i in A:
            if i == 1:
                cnt1 += 1
        if cnt1 == 0:
            return [0, 2]
        if cnt1 % 3 != 0:
            return [-1, -1]
        interval = [[0, 0], [0, 0], [0, 0]]
        cnt = 0
        j = 0
        for i in range(len(A)):
            if A[i] == 1:
                if cnt == 0:
                    interval[j][0] = i
                cnt += 1
                if cnt == cnt1 // 3:
                    interval[j][1] = i + 1
                    j += 1
                    cnt = 0
        if check(A[interval[0][0]:interval[0][1]], A[interval[1][0]:interval[1][1]], A[interval[2][0]:interval[2][1]]):
            zero_last = len(A) - interval[2][1]
            if interval[1][0] - interval[0][1] >= zero_last and interval[2][0] - interval[1][1] >= zero_last:
                return [interval[0][1] - 1 + zero_last, interval[1][1] + zero_last]
            else:
                return [-1, -1]
        else:
            return [-1, -1]

更簡(jiǎn)單的寫(xiě)法:

class Solution:
    def threeEqualParts(self, A: List[int]) -> List[int]:
        N = len(A)
        pos = [i for i in range(N) if A[i] == 1]
        if not pos:return [0,N-1]
        rd1, rd2, rd3 = pos[0], pos[len(pos)//3], pos[len(pos)//3*2]
        sub = N - rd3
        if len(pos)%3 == 0 and A[rd1:rd1+sub] == A[rd2:rd2+sub] == A[rd3:]:
            return [rd1+sub-1,rd2+sub]
        return [-1,-1]

928. 盡量減少惡意軟件的傳播 II

  • 題目難度Hard

(這個(gè)問(wèn)題與 盡量減少惡意軟件的傳播 是一樣的,不同之處用粗體表示呢燥。)

在節(jié)點(diǎn)網(wǎng)絡(luò)中崭添,只有當(dāng) graph[i][j] = 1 時(shí),每個(gè)節(jié)點(diǎn) i 能夠直接連接到另一個(gè)節(jié)點(diǎn) j叛氨。

一些節(jié)點(diǎn) initial 最初被惡意軟件感染呼渣。只要兩個(gè)節(jié)點(diǎn)直接連接棘伴,且其中至少一個(gè)節(jié)點(diǎn)受到惡意軟件的感染,那么兩個(gè)節(jié)點(diǎn)都將被惡意軟件感染屁置。這種惡意軟件的傳播將繼續(xù)焊夸,直到?jīng)]有更多的節(jié)點(diǎn)可以被這種方式感染。

假設(shè) M(initial) 是在惡意軟件停止傳播之后缰犁,整個(gè)網(wǎng)絡(luò)中感染惡意軟件的最終節(jié)點(diǎn)數(shù)淳地。

我們可以從初始列表中刪除一個(gè)節(jié)點(diǎn),并完全移除該節(jié)點(diǎn)以及從該節(jié)點(diǎn)到任何其他節(jié)點(diǎn)的任何連接帅容。如果移除這一節(jié)點(diǎn)將最小化 M(initial)颇象, 則返回該節(jié)點(diǎn)。如果有多個(gè)節(jié)點(diǎn)滿足條件并徘,就返回索引最小的節(jié)點(diǎn)遣钳。

示例 1:

輸出:graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
輸入:0

示例 2:

輸入:graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1]
輸出:1

示例 3:

輸入:graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1]
輸出:1

提示:

  1. 1 < graph.length = graph[0].length <= 300
  2. 0 <= graph[i][j] == graph[j][i] <= 1
  3. graph[i][i] = 1
  4. 1 <= initial.length < graph.length
  5. 0 <= initial[i] < graph.length

思路:

根據(jù)題意直接進(jìn)行initial.length遍BFS統(tǒng)計(jì)病毒感染數(shù),最少的即為答案麦乞。BFS時(shí)蕴茴,需要剔除第i個(gè)結(jié)點(diǎn),直接先把它標(biāo)記為被訪問(wèn)過(guò)即可姐直。

時(shí)間復(fù)雜度O(NM)?

空間復(fù)雜度O(N)?

代碼:

class Solution:
    def minMalwareSpread(self, graph: List[List[int]], initial: List[int]) -> int:
        
        def bfs(g, init, i):
            ret = 0
            n = len(g)
            visited = [False] * n
            visited[init[i]] = True
            q = []
            for j in range(len(init)):
                if j != i:
                    q.append(init[j])
                    visited[init[j]] = True
            while q:
                t = []
                while q:
                    node = q.pop()
                    for j in range(n):
                        if not visited[j] and g[node][j]:
                            t.append(j)
                            visited[j] = True
                            ret += 1
                q = t
            return ret
        
        initial.sort()
        ans = initial[0]
        m = bfs(graph, initial, 0)
        for i in range(1, len(initial)):
            t = bfs(graph, initial, i)
            if t < m:
                m = t
                ans = initial[i]

        return ans
最后編輯于
?著作權(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)店門(mé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)容

  • 922. 按奇偶排序數(shù)組 II 題目難度Easy 給定一個(gè)非負(fù)整數(shù)數(shù)組 A钉疫, A 中一半整數(shù)是奇數(shù),一半整數(shù)是偶數(shù)...
    獨(dú)孤岳閱讀 457評(píng)論 0 0
  • 914. 卡牌分組 題目難度Easy 給定一副牌巢价,每張牌上都寫(xiě)著一個(gè)整數(shù)牲阁。 此時(shí),你需要選定一個(gè)數(shù)字 X壤躲,使我們可...
    獨(dú)孤岳閱讀 666評(píng)論 0 0
  • 900. RLE 迭代器 題目難度Medium 編寫(xiě)一個(gè)遍歷游程編碼序列的迭代器城菊。 迭代器由 RLEIterato...
    獨(dú)孤岳閱讀 2,168評(píng)論 0 1
  • 陽(yáng)光普照萬(wàn)物 不是為了祈求回報(bào) 只是為了平復(fù)自己燥動(dòng)的心跳 螢蟲(chóng)之光 雖也明亮 但它只是為了把食物尋找 給予了 就...
    空夢(mèng)幻花閱讀 454評(píng)論 2 1
  • 初夏黃昏,夕陽(yáng)西下碉克。遠(yuǎn)方的天空在太陽(yáng)的余輝照耀下一片金黃凌唬,地上是一望無(wú)垠的麥田,一陣微風(fēng)吹來(lái)金黃色麥浪隨風(fēng)起伏漏麦。 ...
    蕭蕭秋雨閱讀 928評(píng)論 37 31