LeetCode刷題記錄(持續(xù)更新中14/2073)

LeetCode是一個(gè)刷算法題的網(wǎng)站,這里用的是python3,做一下刷題記錄

1. 兩數(shù)之和

題目

給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)整數(shù)目標(biāo)值 target钥弯,請(qǐng)你在該數(shù)組中找出 和為目標(biāo)值 的那 兩個(gè) 整數(shù),并返回它們的數(shù)組下標(biāo)睛蛛。

你可以假設(shè)每種輸入只會(huì)對(duì)應(yīng)一個(gè)答案忆肾。但是,數(shù)組中同一個(gè)元素在答案里不能重復(fù)出現(xiàn)场仲。

你可以按任意順序返回答案渠缕。

示例 1:

輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因?yàn)?nums[0] + nums[1] == 9 馍忽,返回 [0, 1] 。
示例 2:

輸入:nums = [3,2,4], target = 6
輸出:[1,2]
示例 3:

輸入:nums = [3,3], target = 6
輸出:[0,1]

提示:

2 <= nums.length <= 103
-109 <= nums[i] <= 109
-109 <= target <= 109
只會(huì)存在一個(gè)有效答案

解法

直接窮舉即可:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(0, len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

優(yōu)化算法

可以通過hashmap的方式將時(shí)間復(fù)雜度將至O(n):

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashmap = {}
        for index, num in enumerate(nums):
            another_num = target - num
            if another_num in hashmap:
                return [hashmap[another_num], index]
            hashmap[num] = index
        return None

2. 兩數(shù)相加

題目

給你兩個(gè) 非空 的鏈表,表示兩個(gè)非負(fù)的整數(shù)吵血。它們每位數(shù)字都是按照 逆序 的方式存儲(chǔ)的蹋辅,并且每個(gè)節(jié)點(diǎn)只能存儲(chǔ) 一位 數(shù)字。

請(qǐng)你將兩個(gè)數(shù)相加褒傅,并以相同形式返回一個(gè)表示和的鏈表。

你可以假設(shè)除了數(shù)字 0 之外支竹,這兩個(gè)數(shù)都不會(huì)以 0 開頭。

示例 1:

輸入:l1 = [2,4,3], l2 = [5,6,4]
輸出:[7,0,8]
解釋:342 + 465 = 807.
示例 2:

輸入:l1 = [0], l2 = [0]
輸出:[0]
示例 3:

輸入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
輸出:[8,9,9,9,0,0,0,1]

提示:

每個(gè)鏈表中的節(jié)點(diǎn)數(shù)在范圍 [1, 100] 內(nèi)
0 <= Node.val <= 9
題目數(shù)據(jù)保證列表表示的數(shù)字不含前導(dǎo)零

解法

這里做題習(xí)慣性忽略注釋叹坦,于是吃了個(gè)大虧募书,最終解決如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:

        newList = ListNode()
        newNode = newList
        carry = 0
        while(l1 or l2 or carry):
            sumNum = (l1.val if l1 else 0)+(l2.val if l2 else 0)+carry
            if sumNum > 9:
                carry = 1
                newNode.next = ListNode(sumNum-10)
            else:
                newNode.next = ListNode(sumNum)
                carry = 0
            newNode = newNode.next
            if l1:
                l1 = l1.next
            if l2:
                l2 = l2.next
        return newList.next

27. 移除元素

題目

給你一個(gè)數(shù)組 nums 和一個(gè)值 val鬼吵,你需要 原地 移除所有數(shù)值等于 val 的元素,并返回移除后數(shù)組的新長度涣脚。

不要使用額外的數(shù)組空間遣蚀,你必須僅使用 O(1) 額外空間并 原地 修改輸入數(shù)組芭梯。

元素的順序可以改變。你不需要考慮數(shù)組中超出新長度后面的元素累奈。

說明:

為什么返回?cái)?shù)值是整數(shù),但輸出的答案是數(shù)組呢?

請(qǐng)注意旱幼,輸入數(shù)組是以「引用」方式傳遞的,這意味著在函數(shù)里修改輸入數(shù)組對(duì)于調(diào)用者是可見的匀油。

你可以想象內(nèi)部操作如下:

// nums 是以“引用”方式傳遞的敌蚜。也就是說齐媒,不對(duì)實(shí)參作任何拷貝
int len = removeElement(nums, val);

// 在函數(shù)里修改輸入數(shù)組對(duì)于調(diào)用者是可見的。
// 根據(jù)你的函數(shù)返回的長度, 它會(huì)打印出數(shù)組中 該長度范圍內(nèi) 的所有元素唬血。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 1:

輸入:nums = [3,2,2,3], val = 3
輸出:2, nums = [2,2]
解釋:函數(shù)應(yīng)該返回新的長度 2, 并且 nums 中的前兩個(gè)元素均為 2拷恨。你不需要考慮數(shù)組中超出新長度后面的元素。例如兜挨,函數(shù)返回的新長度為 2 拌汇,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也會(huì)被視作正確答案与倡。
示例 2:

輸入:nums = [0,1,2,2,3,0,4,2], val = 2
輸出:5, nums = [0,1,4,0,3]
解釋:函數(shù)應(yīng)該返回新的長度 5, 并且 nums 中的前五個(gè)元素為 0, 1, 3, 0, 4。注意這五個(gè)元素可為任意順序净响。你不需要考慮數(shù)組中超出新長度后面的元素馋贤。

提示:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

解法

這個(gè)題目的意思也就是直接在原列表中進(jìn)行更改配乓,因此直接使用remove即可:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        while val in nums:
            nums.remove(val)
        return len(nums)

在評(píng)論區(qū)看到了一種快慢指針的方法(據(jù)說時(shí)間更優(yōu),但python執(zhí)行結(jié)果倒是差不多):

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        index = 0
        for i in range(0, len(nums)):
            if val != nums[i]:
                nums[index] = nums[i]
                index += 1
        return index

28. 實(shí)現(xiàn) strStr()

題目

實(shí)現(xiàn) strStr() 函數(shù)实昨。

給你兩個(gè)字符串 haystack 和 needle ,請(qǐng)你在 haystack 字符串中找出 needle 字符串出現(xiàn)的第一個(gè)位置(下標(biāo)從 0 開始)。如果不存在蛔趴,則返回 -1 鱼蝉。

說明:

當(dāng) needle 是空字符串時(shí),我們應(yīng)當(dāng)返回什么值呢洁奈?這是一個(gè)在面試中很好的問題。

對(duì)于本題而言,當(dāng) needle 是空字符串時(shí)我們應(yīng)當(dāng)返回 0 轮蜕。這與 C 語言的 strstr() 以及 Java 的 indexOf() 定義相符肠虽。

示例 1:

輸入:haystack = "hello", needle = "ll"
輸出:2
示例 2:

輸入:haystack = "aaaaa", needle = "bba"
輸出:-1
示例 3:

輸入:haystack = "", needle = ""
輸出:0

提示:

0 <= haystack.length, needle.length <= 5 * 104
haystack 和 needle 僅由小寫英文字符組成

解法

解法如下(執(zhí)行用時(shí):36 ms, 在所有 Python3 提交中擊敗了89.52%的用戶內(nèi)存消耗:15.1 MB, 在所有 Python3 提交中擊敗了47.80%的用戶):

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if needle == '':
            return 0
        elif needle not in haystack:
            return -1
        else:
            return len(haystack.split(needle)[0])

91. 解碼方法

題目

一條包含字母 A-Z 的消息通過以下映射進(jìn)行了 編碼 :

'A' -> 1
'B' -> 2
...
'Z' -> 26
要 解碼 已編碼的消息痊剖,所有數(shù)字必須基于上述映射的方法韩玩,反向映射回字母(可能有多種方法)。例如陆馁,"11106" 可以映射為:

"AAJF" 找颓,將消息分組為 (1 1 10 6)
"KJF" ,將消息分組為 (11 10 6)
注意叮贩,消息不能分組為 (1 11 06) 击狮,因?yàn)?"06" 不能映射為 "F" ,這是由于 "6" 和 "06" 在映射中并不等價(jià)益老。

給你一個(gè)只含數(shù)字的 非空 字符串 s 酷誓,請(qǐng)計(jì)算并返回 解碼 方法的 總數(shù) 娘扩。

題目數(shù)據(jù)保證答案肯定是一個(gè) 32 位 的整數(shù)。

示例 1:

輸入:s = "12"
輸出:2
解釋:它可以解碼為 "AB"(1 2)或者 "L"(12)辣之。
示例 2:

輸入:s = "226"
輸出:3
解釋:它可以解碼為 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 灾部。
示例 3:

輸入:s = "0"
輸出:0
解釋:沒有字符映射到以 0 開頭的數(shù)字。
含有 0 的有效映射是 'J' -> "10" 和 'T'-> "20" 逃呼。
由于沒有字符推姻,因此沒有有效的方法對(duì)此進(jìn)行解碼,因?yàn)樗袛?shù)字都需要映射。
示例 4:

輸入:s = "06"
輸出:0
解釋:"06" 不能映射到 "F" 臭墨,因?yàn)樽址星皩?dǎo) 0("6" 和 "06" 在映射中并不等價(jià))掺冠。

提示:

1 <= s.length <= 100
s 只包含數(shù)字憾股,并且可能包含前導(dǎo)零伐庭。

解法

自己沒做出來饺著,看了下別人的答案绝葡,照著寫了個(gè):

class Solution:
    def numDecodings(self, s: str) -> int:
        if s[0] == '0' or '00' in s:
            return 0
        else:
            n = len(s)
            dp = [0] * (n + 1)
            dp[0] = 1
            for i in range(n):
                if s[i] == '0':
                    dp[i] = 0
                if s[i-1] == '1' or (s[i-1] == '2' and int(s[i]) < 7):
                    dp[i+1] = dp[i-1]
                dp[i+1] += dp[i]
            return dp[n]

179. 最大數(shù)

題目

給定一組非負(fù)整數(shù) nums幽七,重新排列每個(gè)數(shù)的順序(每個(gè)數(shù)不可拆分)使之組成一個(gè)最大的整數(shù)词顾。

注意:輸出結(jié)果可能非常大吓笙,所以你需要返回一個(gè)字符串而不是整數(shù)幌墓。

示例 1:

輸入:nums = [10,2]
輸出:"210"
示例 2:

輸入:nums = [3,30,34,5,9]
輸出:"9534330"
示例 3:

輸入:nums = [1]
輸出:"1"
示例 4:

輸入:nums = [10]
輸出:"10"

提示:

1 <= nums.length <= 100
0 <= nums[i] <= 109

解法

直接將兩個(gè)數(shù)字拼接比大小即可欧募,最后去掉一下前導(dǎo)0:

class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        for i in range(0, len(nums)):
            nums[i] = str(nums[i])
        
        temp = nums[0]
        temp1 = ''
        temp2 = ''

        for i in range(0, len(nums)):
            for j in range(1, len(nums)):
                temp1 = nums[j-1] + nums[j]
                temp2 = nums[j] + nums[j-1]
                if temp1 > temp2:
                    temp = nums[j-1]
                    nums[j-1] = nums[j]
                    nums[j] = temp
        str1 = ''
        nums.reverse()
        for i in range(0, len(nums)):
            str1 += str(nums[i])
        index = 0
        for i in range(len(str1)):
            if str1[i] == '0' and index < len(str1)-1:
                index += 1
            else:
                break
        return str1[index:]

208. 實(shí)現(xiàn) Trie (前綴樹)

題目

Trie(發(fā)音類似 "try")或者說 前綴樹 是一種樹形數(shù)據(jù)結(jié)構(gòu)摇庙,用于高效地存儲(chǔ)和檢索字符串?dāng)?shù)據(jù)集中的鍵讽营。這一數(shù)據(jù)結(jié)構(gòu)有相當(dāng)多的應(yīng)用情景膜蠢,例如自動(dòng)補(bǔ)完和拼寫檢查。

請(qǐng)你實(shí)現(xiàn) Trie 類:

Trie() 初始化前綴樹對(duì)象。
void insert(String word) 向前綴樹中插入字符串 word 祭饭。
boolean search(String word) 如果字符串 word 在前綴樹中,返回 true(即,在檢索之前已經(jīng)插入)猪钮;否則品山,返回 false 。
boolean startsWith(String prefix) 如果之前已經(jīng)插入的字符串 word 的前綴之一為 prefix 烤低,返回 true 肘交;否則,返回 false 扑馁。

示例:

輸入
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
輸出
[null, null, true, false, true, null, true]

解釋
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 True
trie.search("app"); // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app"); // 返回 True

提示:

1 <= word.length, prefix.length <= 2000
word 和 prefix 僅由小寫英文字母組成
insert涯呻、search 和 startsWith 調(diào)用次數(shù) 總計(jì) 不超過 3 * 104 次

解法

根據(jù)相應(yīng)的函數(shù)寫出對(duì)應(yīng)功能即可(內(nèi)存消耗極小,但運(yùn)行時(shí)間奇高腻要,執(zhí)行用時(shí): 2356 ms复罐,內(nèi)存消耗: 20.8 MB):

class Trie:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.datalist = []


    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        self.datalist.append(word)


    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        for i in range(0, len(self.datalist)):
            if word == self.datalist[i]:
                return True
        return False


    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        for i in range(0, len(self.datalist)):
            if prefix in self.datalist[i] and prefix == self.datalist[i][0:len(prefix)]:
                return True
        return False


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

看了下題解,看到一個(gè)代碼更簡(jiǎn)更加省內(nèi)存(執(zhí)行用時(shí):424 ms, 內(nèi)存消耗:20.6 MB)的寫法:

class Trie:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.datalist = ','


    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        self.datalist = self.datalist + word + ','


    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        return ',' + word + ',' in self.datalist


    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        return ',' + prefix in self.datalist


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

但是嚴(yán)格來說都不符合前綴樹的定義雄家,于是查了下更省時(shí)間的前綴樹的寫法(執(zhí)行用時(shí):120 ms效诅,內(nèi)存消耗:27.7 MB):

class Trie:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root = {}

        
    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        node = self.root
        for s in word:
            if s in node.keys():
                node = node[s]
            else:
                node[s] = {}
                node = node[s]
        node['is_word'] = True
                
    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        node = self.root
        for s in word:
            if s in node.keys():
                node = node[s]
            else:
                return False
        
        return True if 'is_word' in node.keys() else False
        

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        node = self.root
        for s in prefix:
            if s in node.keys():
                node = node[s]
            else:
                return False
        
        return True


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

403. 青蛙過河

題目

一只青蛙想要過河。 假定河流被等分為若干個(gè)單元格咳短,并且在每一個(gè)單元格內(nèi)都有可能放有一塊石子(也有可能沒有)填帽。 青蛙可以跳上石子蛛淋,但是不可以跳入水中咙好。

給你石子的位置列表 stones(用單元格序號(hào) 升序 表示), 請(qǐng)判定青蛙能否成功過河(即能否在最后一步跳至最后一塊石子上)褐荷。

開始時(shí)勾效, 青蛙默認(rèn)已站在第一塊石子上,并可以假定它第一步只能跳躍一個(gè)單位(即只能從單元格 1 跳至單元格 2 )叛甫。

如果青蛙上一步跳躍了 k 個(gè)單位层宫,那么它接下來的跳躍距離只能選擇為 k - 1、k 或 k + 1 個(gè)單位其监。 另請(qǐng)注意萌腿,青蛙只能向前方(終點(diǎn)的方向)跳躍。

示例 1:

輸入:stones = [0,1,3,5,6,8,12,17]
輸出:true
解釋:青蛙可以成功過河抖苦,按照如下方案跳躍:跳 1 個(gè)單位到第 2 塊石子, 然后跳 2 個(gè)單位到第 3 塊石子, 接著 跳 2 個(gè)單位到第 4 塊石子, 然后跳 3 個(gè)單位到第 6 塊石子, 跳 4 個(gè)單位到第 7 塊石子, 最后毁菱,跳 5 個(gè)單位到第 8 個(gè)石子(即最后一塊石子)。
示例 2:

輸入:stones = [0,1,2,3,4,8,9,11]
輸出:false
解釋:這是因?yàn)榈?5 和第 6 個(gè)石子之間的間距太大锌历,沒有可選的方案供青蛙跳躍過去贮庞。

提示:

2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0

解法

這個(gè)題沒做出來,看了下別人的題解:

class Solution:
    def canCross(self, stones: List[int]) -> bool:
        # 假設(shè)每次都跳 k + 1 步
        # 0   1   2   3   4   5   6   :  i
        # 1   2   3   4   5   6   7   :   step
        # 那么第 i 個(gè)單位最遠(yuǎn)能夠條 i + 1 步

        #  動(dòng)態(tài)規(guī)劃
        #  dp[i][k] 表示能否由前面的某一個(gè)石頭 j 通過跳 k 步到達(dá)當(dāng)前這個(gè)石頭 i 究西,這個(gè) j 的范圍是 [1, i - 1]
        #  當(dāng)然窗慎,這個(gè) k 步是 i 石頭 和 j 石頭之間的距離
        #  那么對(duì)于 j 石頭來說,跳到 j 石頭的上一個(gè)石頭的步數(shù)就必須是這個(gè) k - 1 || k || k + 1
        #  由此可得狀態(tài)轉(zhuǎn)移方程:dp[i][k] = dp[j][k - 1] || dp[j][k] || dp[j][k + 1]

        stonesLen = len(stones)
        if stones[1] != 1:
            return False
        
        dp = []
        for i in range(stonesLen):
            dp.append([])
            for j in range(stonesLen+1):
                dp[i].append(False)
        # print(dp)
        dp[0][0] = True
        for i in range(stonesLen):
            for j in range(i):
                k = stones[i] - stones[j]
                if k <= j + 1:
                    if dp[j][k-1] or dp[j][k] or dp[j][k+1]:
                        dp[i][k] = True
                    if i == (stonesLen-1) and dp[i][k]:
                        return True
        return False

633. 平方數(shù)之和

題目

給定一個(gè)非負(fù)整數(shù) c ,你要判斷是否存在兩個(gè)整數(shù) a 和 b遮斥,使得 a2 + b2 = c 峦失。

示例 1:

輸入:c = 5
輸出:true
解釋:1 * 1 + 2 * 2 = 5
示例 2:

輸入:c = 3
輸出:false
示例 3:

輸入:c = 4
輸出:true
示例 4:

輸入:c = 2
輸出:true
示例 5:

輸入:c = 1
輸出:true

解法

直接遍歷,然后求差開根號(hào)看是不是一個(gè)整數(shù)即可术吗,對(duì)于0需要特別處理下宠进,為了效率,直接遍歷到根號(hào)c即可:

import math
class Solution:
    def judgeSquareSum(self, c: int) -> bool:
        if c == 0:
            return True
        for i in range(math.ceil(math.sqrt(c))):
            difference = math.sqrt(c - i*i)
            if int(difference) == difference:
                return True
        return False

優(yōu)化

看了下題解藐翎,用雙指針更快材蹬,其思想大概是先從i=0和j=根號(hào)c開始,不滿足的話前者依次加1吝镣,后者依次減1堤器,然后i和j不停趨近,如果i>j的話就說明找不到了:

import math

class Solution(object):
    def judgeSquareSum(self, c):
        """
        :type c: int
        :rtype: bool
        """
        j = int(math.sqrt(c))
        i = 0
        while i <= j:
            total = i * i + j * j
            if total > c:
                j = j - 1
            elif total < c:
                i = i + 1
            else:
                return True
        return False

783. 二叉搜索樹節(jié)點(diǎn)最小距離

題目

給你一個(gè)二叉搜索樹的根節(jié)點(diǎn) root 末贾,返回 樹中任意兩不同節(jié)點(diǎn)值之間的最小差值 闸溃。

注意:本題與 530:https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/ 相同

示例 1:


輸入:root = [4,2,6,1,3]
輸出:1

示例 2:


輸入:root = [1,0,48,null,null,12,49]
輸出:1

提示:

樹中節(jié)點(diǎn)數(shù)目在范圍 [2, 100] 內(nèi)
0 <= Node.val <= 105

解法

這里遇到了一個(gè)問題,就是python的Null報(bào)錯(cuò)拱撵,說未定義:

NameError: name 'Null' is not defined
    if cursor == Null:
Line 18 in minDiffInBST (Solution.py)
    ret = Solution().minDiffInBST(param_1)
Line 45 in _driver (Solution.py)
    _driver()
Line 56 in <module> (Solution.py)

通過搜索引擎辉川,發(fā)現(xiàn)這里應(yīng)該用None

然后遇到了第二個(gè)錯(cuò)誤:

UnboundLocalError: local variable 'pre' referenced before assignment
    if pre != None and node != None and abs(pre.val - node.val) < smallestDis:
Line 16 in traversalTree (Solution.py)
    traversalTree(node.left)
Line 15 in traversalTree (Solution.py)
    traversalTree(node.left)
Line 15 in traversalTree (Solution.py)
    traversalTree(root)
Line 21 in minDiffInBST (Solution.py)
    ret = Solution().minDiffInBST(param_1)
Line 44 in _driver (Solution.py)
    _driver()
Line 55 in <module> (Solution.py)

發(fā)現(xiàn)是python的變量作用域的問題,在python3里面可以用nonlocal關(guān)鍵字來解決

最終代碼如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def minDiffInBST(self, root: TreeNode) -> int:
        pre = None
        smallestDis = 10e5
        def traversalTree(node):
            nonlocal smallestDis
            nonlocal pre
            if node.left != None:
                traversalTree(node.left)
            if pre != None and node != None and abs(pre.val - node.val) < smallestDis:
                smallestDis = abs(pre.val - node.val)
            pre = node
            if node.right != None:
                traversalTree(node.right)
        traversalTree(root)
        return smallestDis

938. 二叉搜索樹的范圍和

題目

給定二叉搜索樹的根結(jié)點(diǎn) root拴测,返回值位于范圍 [low, high] 之間的所有結(jié)點(diǎn)的值的和乓旗。

示例 1:


image.png

輸入:root = [10,5,15,3,7,null,18], low = 7, high = 15
輸出:32
示例 2:


image.png

輸入:root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10
輸出:23

提示:

樹中節(jié)點(diǎn)數(shù)目在范圍 [1, 2 * 104] 內(nèi)
1 <= Node.val <= 105
1 <= low <= high <= 105
所有 Node.val 互不相同

解法

直接遞歸遍歷二叉樹即可:

class Solution:
    def rangeSumBST(self, root: TreeNode, low: int, high: int) -> int:
        # cursor = root
        allSum = 0
        def traversalTree(cursor):
            nonlocal allSum
            if cursor.left:
                traversalTree(cursor.left)
            if cursor.val <= high and cursor.val >= low:
                allSum += cursor.val
            if cursor.right:
                traversalTree(cursor.right)
        traversalTree(root)
        return allSum

1011. 在 D 天內(nèi)送達(dá)包裹的能力

題目

傳送帶上的包裹必須在 D 天內(nèi)從一個(gè)港口運(yùn)送到另一個(gè)港口。

傳送帶上的第 i 個(gè)包裹的重量為 weights[i]集索。每一天屿愚,我們都會(huì)按給出重量的順序往傳送帶上裝載包裹。我們裝載的重量不會(huì)超過船的最大運(yùn)載重量务荆。

返回能在 D 天內(nèi)將傳送帶上的所有包裹送達(dá)的船的最低運(yùn)載能力妆距。

示例 1:

輸入:weights = [1,2,3,4,5,6,7,8,9,10], D = 5
輸出:15
解釋:
船舶最低載重 15 就能夠在 5 天內(nèi)送達(dá)所有包裹,如下所示:
第 1 天:1, 2, 3, 4, 5
第 2 天:6, 7
第 3 天:8
第 4 天:9
第 5 天:10

請(qǐng)注意函匕,貨物必須按照給定的順序裝運(yùn)娱据,因此使用載重能力為 14 的船舶并將包裝分成 (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) 是不允許的。
示例 2:

輸入:weights = [3,2,2,4,1,4], D = 3
輸出:6
解釋:
船舶最低載重 6 就能夠在 3 天內(nèi)送達(dá)所有包裹盅惜,如下所示:
第 1 天:3, 2
第 2 天:2, 4
第 3 天:1, 4
示例 3:

輸入:weights = [1,2,3,1,1], D = 4
輸出:3
解釋:
第 1 天:1
第 2 天:2
第 3 天:3
第 4 天:1, 1

提示:

1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500

解法

這里用二分法中剩,直接認(rèn)為最小裝載量是列表中的最大值,而最大裝載量是列表的總和酷窥,然后二分分別驗(yàn)證是否能夠裝載:

class Solution:
    def shipWithinDays(self, weights: List[int], D: int) -> int:
        loadAbi = max(weights)
        maxWeight = sum(weights)
        if loadAbi == maxWeight:
            return loadAbi
        def checkLoad(theLoad):
            temp = 0
            count = 0
            for i in range(len(weights)):
                temp += weights[i]
                if temp > theLoad:
                    temp = weights[i]
                    count += 1
            if temp != 0:
                count += 1
            if count <= D:
                return True
            else:
                return False
        while loadAbi < maxWeight:
            mid = (loadAbi + maxWeight) // 2
            if checkLoad(mid):
                maxWeight = mid
            else:
                loadAbi = mid + 1
        return loadAbi

1720. 解碼異或后的數(shù)組

題目

未知 整數(shù)數(shù)組 arr 由 n 個(gè)非負(fù)整數(shù)組成咽安。

經(jīng)編碼后變?yōu)殚L度為 n - 1 的另一個(gè)整數(shù)數(shù)組 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 蓬推。例如妆棒,arr = [1,0,2,1] 經(jīng)編碼后得到 encoded = [1,2,3] 。

給你編碼后的數(shù)組 encoded 和原數(shù)組 arr 的第一個(gè)元素 first(arr[0])。

請(qǐng)解碼返回原數(shù)組 arr 糕珊《郑可以證明答案存在并且是唯一的。

示例 1:

輸入:encoded = [1,2,3], first = 1
輸出:[1,0,2,1]
解釋:若 arr = [1,0,2,1] 红选,那么 first = 1 且 encoded = [1 XOR 0, 0 XOR 2, 2 XOR 1] = [1,2,3]
示例 2:

輸入:encoded = [6,2,7,3], first = 4
輸出:[4,2,0,7,4]

提示:

2 <= n <= 104
encoded.length == n - 1
0 <= encoded[i] <= 105
0 <= first <= 105

解法

由于異或具有自反性澜公,即a^b = c可得出a^c = b,因此直接循環(huán)異或即可:

class Solution:
    def decode(self, encoded: List[int], first: int) -> List[int]:
        originList = [first]
        for n in encoded:
            originList += [n ^ originList[-1]]
        return originList
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇肋,一起剝皮案震驚了整個(gè)濱河市坟乾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蝶防,老刑警劉巖甚侣,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異间学,居然都是意外死亡殷费,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門低葫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來详羡,“玉大人,你說我怎么就攤上這事嘿悬∈的” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵鹊漠,是天一觀的道長主到。 經(jīng)常有香客問我茶行,道長躯概,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任畔师,我火速辦了婚禮娶靡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘看锉。我一直安慰自己姿锭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布伯铣。 她就那樣靜靜地躺著呻此,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腔寡。 梳的紋絲不亂的頭發(fā)上焚鲜,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼忿磅。 笑死糯彬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葱她。 我是一名探鬼主播撩扒,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吨些!你這毒婦竟也來了搓谆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤豪墅,失蹤者是張志新(化名)和其女友劉穎挽拔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體但校,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡螃诅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了状囱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片术裸。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖亭枷,靈堂內(nèi)的尸體忽然破棺而出袭艺,到底是詐尸還是另有隱情,我是刑警寧澤叨粘,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布猾编,位于F島的核電站,受9級(jí)特大地震影響升敲,放射性物質(zhì)發(fā)生泄漏答倡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一驴党、第九天 我趴在偏房一處隱蔽的房頂上張望瘪撇。 院中可真熱鬧,春花似錦港庄、人聲如沸倔既。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渤涌。三九已至,卻和暖如春把还,著一層夾襖步出監(jiān)牢的瞬間实蓬,已是汗流浹背稿存。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞳秽,地道東北人瓣履。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像练俐,于是被迫代替她去往敵國和親袖迎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 兩數(shù)之和給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)目標(biāo)值 target腺晾,請(qǐng)你在該數(shù)組中找出和為目標(biāo)值的那 兩個(gè) 整數(shù)燕锥,并返...
    kaxi4it閱讀 361評(píng)論 1 0
  • 從尾到頭打印鏈表輸入一個(gè)鏈表的頭節(jié)點(diǎn),從尾到頭反過來返回每個(gè)節(jié)點(diǎn)的值(用數(shù)組返回)悯蝉。示例 1:輸入:head = ...
    拼搏男孩閱讀 532評(píng)論 0 0
  • 常規(guī)動(dòng)態(tài)規(guī)劃問題 相關(guān)題目: 70.爬樓梯 70.爬樓梯 描述 假設(shè)你正在爬樓梯归形。需要 n 階你才能到達(dá)樓頂。 每...
    要記錄的Ivan閱讀 576評(píng)論 0 0
  • 技術(shù)交流QQ群:1027579432鼻由,歡迎你的加入暇榴! 歡迎關(guān)注我的微信公眾號(hào):CurryCoder的程序人生 遞歸...
    CurryCoder閱讀 597評(píng)論 0 1
  • 刷題并記錄。 1 給定一個(gè)整數(shù)數(shù)組 nums和一個(gè)目標(biāo)值 target蕉世,請(qǐng)你在該數(shù)組中找出和為目標(biāo)值的那兩個(gè)整數(shù)蔼紧,...
    Windy_xf閱讀 88評(píng)論 0 0