Leetcode題解 - 部分中等難度算法題解(56、957、825、781、1324、816)


957. N 天后的牢房

在這里插入圖片描述
思路:
模擬變換,當N天結合后返回 => 當N非常大的時候,超時 => 一般N很大的時候,這種題目必然存在循環,所以記錄找過的狀態,一旦出現已經訪問過的狀態可立即跳出循環。

class Solution:
    def prisonAfterNDays(self, cells, N: int):
        vis = []
        while 1:
            if not N:
                return cells
            if cells in vis:
                ind = vis.index(cells)
                break
            tcell = cells.copy()
            for i in range(len(cells)):
                if i == 0 or i == len(cells)-1:
                    tcell[i] = 0
                    continue
                if cells[i-1] == cells[i+1]:
                    tcell[i] = 1
                else:
                    tcell[i] = 0
            vis.append(cells)
            cells = tcell
            N -= 1
        vis = vis[ind:]
        return vis[N % len(vis)]

825. 適齡的朋友

在這里插入圖片描述
思路:
最直觀的就是兩層循環暴力,意料之中的超時了。那么就改以人為單位交友,變為以組(年齡相同的為一組)為單位交友。

還需要注意的一點就是15歲以下的沒朋友,不符合第一個條件!

from collections import Counter
class Solution:
    def numFriendRequests(self, ages) -> int:
        ages, res = sorted(Counter(ages).items(), key=lambda x: x[0]), 0
        for i in range(len(ages)):
            if ages[i][0] < 15:
                continue
            res += (ages[i][1] - 1) * ages[i][1]
            for j in range(i):
                if ages[j][0] <= (ages[i][0] * 0.5 + 7):
                    continue
                else:
                    res += ages[i][1] * ages[j][1]
        return res

781. 森林中的兔子

在這里插入圖片描述
在這里插入圖片描述
思路:
顏色相同的兔子如果說自己有i個伙伴,那么所有伙伴都出現,該顏色對應的數字最多出現 i+1次 => 通過頻率來判斷,那些是同樣顏色的。

"""
判斷某數字出現的頻次,數字0特殊處理一下
數字i出現的頻次小於等於i+1時,說明大家都是一個色。
大於i+1的時候,就說明還有別的顏色,看是i+1的幾倍就 i+1 * ?
"""
import math
from collections import Counter
class Solution:
    def numRabbits(self, answers) -> int:
        ans, res = Counter(answers), 0
        for num, times in ans.items():
            if not num:
                res += times
            else:
                if times <= num + 1:
                    res += num + 1
                else:
                    t = math.ceil(times / (num + 1))
                    res += t * (num + 1)
        return res

1324. 豎直打印單詞

在這里插入圖片描述
思路:
補上空格,矩陣轉置輸出,末尾的空格需要去掉。

class Solution:
    def printVertically(self, s: str):
        s = s.split(" ")
        l = len(sorted(s, key=lambda x:-len(x))[0])
        for i in range(len(s)):
            s[i] = s[i] + (l - len(s[i])) * " "
        res = []
        for i in zip(*s):
            i = ("".join(list(i))).rstrip()
            res.append(i)
        return res

816. 模糊坐標

在這里插入圖片描述
思路:
分割數組找到整數、小數部分。比較麻煩在於加上小數點后時候合理:

  1. 不是‘0’也不是'0.'但以0開頭的不合理
  2. 以‘0’結尾的不合理
"""
先分割字符串,得到整數部分和小數部分,再分別為兩部分加上小數點,同時判斷加上小數點后是否為合理數字
"""
class Solution:
    def ambiguousCoordinates(self, S: str):
        def produce(string):
            res = []
            # 本身就是一個完整的數字
            if len(str(int(string))) == len(string):
                res = [string]
            # 如果全是零直接返回
            if set(string) == {'0'}:
                return res
            # 在不同的位置添加小數點
            for i in range(1,len(string)):
                t = string[:i]+"."+string[i:]
                # 不是'0'也不是'0.'開頭的,以'0'開頭的都要刪掉
                if len(string[:i]) >= 2 and string[:i].startswith("0"):
                    continue
                # '0'結尾的也刪掉
                if string[i:].endswith('0'):
                    continue
                res.append(t)
            return res
        S, res, r = S[1:-1], [], []
        # 分割字符串獲取整數、小數部分
        for i in range(1, len(S)):
            res.append((S[:i], S[i:]))
        for x, y in res:
            px = produce(x)
            py = produce(y)
            for i in px:
                for j in py:
                    r.append("("+i+", "+j+")")
        return r

56. 合並區間

在這里插入圖片描述
思路:
按照合並的要求來就vans了。先排序,保證遍歷的時候后面的要么是頭比前面大,要么是尾巴更長。記錄當前拼接的頭尾,如果遇到了頭比當前拼接的尾巴還大,這兩個區間不可能合並的,重新開始一次拼接,否則更新尾巴。

class Solution:
    def merge(self, intervals):
        res = []
        # 先排序
        intervals = sorted(intervals)
        # 記錄拼接的首尾大小
        s, e = intervals[0][0], intervals[0][1]
        for x, y in intervals[1:]:
            # 你的頭大於我的尾部,不可能拼接的。重新開始一次拼接
            if x > e:
                res.append([s, e])
                s, e = x, y
                continue
            # 可以拼接到一起,更新尾巴
            if y > e:
                e = y
        if [s, e] not in res:
            res.append([s, e])
        return res


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM