LeetCode 題解2 (Python)

本文轉載自作業部落chanvee.

Same Tree


這個題的意思非常簡單,給定兩顆二叉樹,判斷這兩顆二叉樹是否相同。樹相同包括兩點:一是結構相同,而是值相同。因此我們只需要對兩棵樹同時遍歷)(簡單的遞歸)一遍,遇到不同(結構不同或者值不同)時則返回False;若遍歷一遍之后沒有發現不同則說明這兩棵樹相同。代碼如下:

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param p, a tree node
    # @param q, a tree node
    # @return a boolean
    def isSameTree(self, p, q):  
        if p == None and q == None:
            return(True)
        elif p == None or q == None:
            return(False)
        else:
            if p.val != q.val:
                return(False)
            else:  
                if self.isSameTree(p.left, q.left): 
                    return(self.isSameTree(p.right, q.right))
                else:
                    return(False) 

Symmetric Tree


這個題是判斷一棵樹是不是對稱樹。我們可以根據上一個題來解決這個問題,先給代碼:

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param root, a tree node
    # @return a boolean
    def isSymmetric(self, root):
        if root == None:
            return(True)
        else:
            return(self.isSameTree(root.left, root.right))
    def isSameTree(self, p, q):
        if p == None and q == None:
            return(True)
        elif p == None or q == None:
            return(False)
        else:
            if p.val != q.val:
                return(False)
            else:
                if self.isSameTree(p.left, q.right): 
                    return(self.isSameTree(p.right, q.left))
                else:
                    return(False) 

有代碼可知,我們首先把這個樹分成左右兩顆子樹,然后遍歷這兩顆子樹,比較時不再是左邊和左邊的比,因為對稱,所以比較左子樹的左節點和右子樹的右節點以及左子樹的右節點和右子樹的左節點是否相等即可。

Add Two Numbers


這個題目是實現鏈表的加法,剛開始理解錯了,看到題目給的例子以為給的兩個列表長度是相等的,其實不是哈,不一定等長。題目本身很簡單,值得一提的是python中鏈表的操作,才開始我硬是沒搞清楚,先貼代碼:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # @return a ListNode
    def addTwoNumbers(self, l1, l2):
        add = 0
        l3 = ListNode(0)
        cur = l3
        while l1 or l2:
            node = ListNode(add)
            if l1:
                node.val += l1.val
                l1 = l1.next
            if l2:
                node.val += l2.val
                l2 = l2.next
            if node.val >= 10:
                add = 1
            else:
                add = 0
            node.val %= 10
            cur.next, cur = node, node 
        if add:
            cur.next = ListNode(1)
        return(l3.next)

代碼中cur = l3,表示cur和l3都指向了同一個鏈表,在另一句cur.next, cur = node, node中,當第一次執行這句話時,首先cur.next指向了node,也代表了l3.next也指向了node,然后cur再指向node,也就是指向了l3的next;當再一次執行時,首先cur.next指向node就相當于l3.next.next指向node,以此類推,從而cur就相當于實現了C中的指針的作用了。

Remove Duplicates from Sorted List


這個題目的意思是去除掉鏈表中所有重復的元素,即每個元素只保留一次,方法就是遍歷這個鏈表,每次將當前節點的值跟下一個的節點的值相比,如果相同則將當前節點指向下下個節點即可,需要注意的是如果下下個節點沒有的話,則當前節點指向None。代碼如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def deleteDuplicates(self, head):
        if head == None:
            return(None)
        else:
            cur = ListNode(head.val)
            cur.next, head = head, cur
            while cur:
                if cur.next and cur.val == cur.next.val:
                    if cur.next.next:
                        cur.next = cur.next.next
                    else:
                        cur.next = None
                else:
                    cur = cur.next
            return(head)

Remove Duplicates from Sorted List II


這個題是上一個題目的升級版,只要出現重復的數字,這些數字都要從鏈表中刪掉,方法是在鏈表前先加一個節點以及一個刪除標識,然后遍歷這個鏈表,比較后兩個節點是否相同,如果相同,先刪掉第一個節點,并讓刪除標識變為真,表明下一次操作需要把第二個節點刪掉(即使下一次比較的時候兩個節點值不同,但是上次只刪掉了一個重復節點,所以還是要把它刪掉),如果下兩個節點不同且刪除標識不為真則跳過。代碼如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def deleteDuplicates(self, head):
        if head == None or head.next == None:
            return(head)
        cur = ListNode(head.val)
        cur.next, head = head, cur
        flag = False
        while cur:
            if cur.next and cur.next.next and cur.next.val == cur.next.next.val:
                cur.next = cur.next.next
                flag = True
            elif flag and cur.next:
                cur.next = cur.next.next
                flag = False
            else:
                cur = cur.next
        return(head.next)

Remove Duplicates from Sorted Array


這個題與上面兩個題類似,只是有鏈表變為了指針,需要注意的是雖然題目只要求返回數組的長度,但是它還有一個隱性的要求就是要使得數組A[0:len]是你想要的得到的不包含重復元素的數組,如他給的例子A=[1,1,2],remove 完之后要求A=[1,2,2],也就是說A[0:2] = [1,2]。我就在這里卡了好久。。。代碼如下:

class Solution:
    # @param a list of integers
    # @return an integer
    def removeDuplicates(self, A):
        if A == []:
            return(0)
        count = 1
        for i in range(1,len(A)):
            if A[i] != A[i-1]:
                A[count] = A[i]
                count += 1
        return(count)

Remove Duplicates from Sorted Array II


這個題是上個題目的升級版,這是移除數組中重復元素大于2個的元素并返回新數組的長度,思想類似,這里就不在贅述,直接貼代碼:

class Solution:
    # @param A a list of integers
    # @return an integer
    def removeDuplicates(self, A):
        if len(A) <= 2: 
            return(len(A))
        count = 2
        for i in range(2,len(A)):
            if A[i] != A[count-1] or A[i] != A[count-2]:
                A[count] = A[i]
                count += 1
        return(count)

Pascal's Triangle


精簡版
題目的意思是生成n行的Pascal's三角并存入到列表中。思路是第i(i>=3)的第j個元素等于第i-1行的第j-1個元素和第j個元素之和,初識化第一二行之后for一下就可以了,另外由于Pascal's三角是對稱的,所以我們每次只需算前一半即可。代碼如下:

class Solution:
    # @return a list of lists of integers
    def generate(self, numRows):
        if numRows == 1:
            return([[1]])
        elif numRows == 2:
            return([[1],[1,1]])
        elif numRows == 0:
            return([])
        else:
            result = [[1],[1,1]]
            for i in range(3, numRows+1):
                tmp = [1]*i
                last = result[i-2]
                for j in range(1,(i-1)//2 + 1):
                    tmp[j] = tmp[i-1-j] = last[j-1] +last[j]
                result.append(tmp)
            return(result)

Pascal's Triangle II


這個題跟上一個題目類似,只是這次不是全部返回,而是只返回固定的某一行。由于Pascal's三角中的第i行第j個元素

_LeTeX(簡書不支持): _ $$L(i,j)=C^{j-1}_i=\frac{i!}{(j-1)!(n-j+1)!}$$

Pascal's 三角

所有我們就可以很簡單得到任意一行的值了,只需再添加一個計算階乘的函數,代碼如下:

class Solution:
    # @return a list of integers
    def getRow(self, rowIndex):
        result = [1]*(rowIndex + 1)
        for i in range(1,(rowIndex)//2 + 1):
            result[i] = result[rowIndex-i] = self.factorial(rowIndex)//(self.factorial(i)*self.factorial(rowIndex-i))
        return(result)
    def factorial(self, n):
        if n == 1:
            return(1)
        else:
            return(n*self.factorial(n-1))

Minimum Depth of Binary Tree


這個題目是計算一顆二叉樹的最小深度,分別計算左右子樹的深度,然后取較小,深度的計算方法是如果節點是葉子節點深度加1,如果節點有子節點深度加1,初識化左右子樹深度為無窮大。代碼如下:

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param root, a tree node
    # @return an integer
    def minDepth(self, root):
        if root == None:
            return(0)
        if root.left == None and root.right == None:
            return(1)
        left = right = float("inf") # 表示無窮大
        if root.left != None:
            left = 1 + self.minDepth(root.left)
        if root.right != None:
            right = 1 + self.minDepth(root.right)
        return(min(left, right))

Maximum Depth of Binary Tree


與上題類似,只不過是找樹的最大深度,改一下判別條件就可以了。代碼如下:

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param root, a tree node
    # @return an integer
    def maxDepth(self, root):
        if root == None:
            return(0)
        if root.left == None and root.right == None:
            return(1)
        left = right = -1
        if root.left != None:
            left = 1 + self.maxDepth(root.left)
        if root.right != None:
            right = 1 + self.maxDepth(root.right)
        return(max(left, right))

Path Sum


這個題的意思是一顆二叉樹上是否存在一條從根節點到葉子節點的路徑,其上所有節點之和等于一個指定的數。方法就是當我們從根節點往下遞歸時,看當前節點是否存在sum減去前面節點之和的路徑存在。代碼如下:

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param root, a tree node
    # @param sum, an integer
    # @return a boolean
    def hasPathSum(self, root, sum):
        result = False
        if root == None:
            return(result)
        else:
            sum -= root.val
            if sum == 0 and root.left == None and root.right == None:
                result = True
                return(result)
            else:
                if root.left:
                    result = result or self.hasPathSum(root.left, sum) # 只要存在一條就返回True
                if root.right:
                    result = result or self.hasPathSum(root.right, sum)
                return(result)

Length of Last Word


求一行字符串中最后一個單詞的長度,這個題用python做就非常簡單了,代碼如下:

class Solution:
    # @param s, a string
    # @return an integer
    def lengthOfLastWord(self, s):
        if s == '':
            return(0)
        result = s.split()
        if result == []:
            return(0)
        return(len(result[-1]))

Add Binary


這個題目非常簡單,就是二進制的加法。對于我們這種python的初學者來說難點是字符串與列表的轉化,題目本身需要注意的一個地方就是,最后可能由于進位需要補一位,我們可以先把字符串先倒一轉再加,這樣就可以在末尾補位。代碼如下:

class Solution:
    # @param a, a string
    # @param b, a string
    # @return a string
    def addBinary(self, a, b):
        a = a[::-1] # 字符串倒序
        b = b[::-1] # 字符串倒序
        i = j = 0
        c = []
        add = 0 # 表示進位
        while i < len(a) or j < len(b):
            if i < len(a) and j < len(b):
                tmp = (int(a[i]) + int(b[j]) + add) % 2
                c.append(str(tmp))
                if (int(a[i]) + int(b[j]) + add) >= 2:
                    add = 1
                else:
                    add = 0
                i += 1
                j += 1
            if i < len(a) and j>= len(b):
                tmp = (int(a[i]) + add)%2
                c.append(str(tmp))
                if (int(a[i]) + add) >= 2:
                    add = 1
                else:
                    add = 0
                i += 1
            if i >= len(a) and j < len(b):
                tmp = (int(b[j]) + add)%2
                c.append(str(tmp))
                if (int(b[j]) + add) >= 2:
                    add = 1
                else:
                    add = 0
                j += 1
        if add:
            c.append('1')
        c = c[::-1]
        result = "".join(c)
        return(result)

Valid Parentheses


這道題是判斷括號是否匹配,就是利用棧來進行解決,遇到正括號加入棧,遇到反括號彈出棧看是否匹配,只不過剛開始時可以直接排除一些結果:

  1. 如果字符串的長度為奇數, 必然False.
  2. 如果最后一個字符是( [ {必然False.
  3. 第一個字符為) ] }必然False等.

代碼如下:

class Solution:
    # @return a boolean
    def isValid(self, s):
        if len(s)%2 != 0 or s[-1] == '(' or s[-1] =='[' or s[-1] =='{':
            return(False)
        result = True
        a = []
        for i in range(len(s)):
            if s[i] =='(' or s[i] =='[' or s[i] =='{':
                a.append(s[i])
            else:
                if len(a) == 0:
                    result = False
                    break
                if s[i] == ')':
                    if a.pop() != '(':
                        result = False
                        break
                if s[i] == ']':
                    if a.pop() != '[':
                        result = False
                        break
                if s[i] == '}':
                    if a.pop() != '{':
                        result = False
                        break
        return(result)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容