LeetCode112 | 路徑總和|8月更文挑戰

天天分享一個LeetCode題目node

天天 5 分鐘,一塊兒進步python

LeetCode112 路徑總和,地址: leetcode-cn.com/problems/pa…git

這道題目是 LeetCode 中「樹」路徑總和的第一個題目,就是給定 targetSum ,去判斷,自頂而下到葉子結點,整個路徑有沒有路徑和爲 targetSum 的路徑,有就返回 True,不然,返回 False。github

樹結點定義

class TreeNode(object):
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
複製代碼

遞歸方式

依然遞歸方式比較簡單,就是一個先續遍歷,先判斷當前結點是否有孩子結點markdown

若是有,則繼續向下判斷app

若是沒有,則該結點是葉子結點,判斷是否知足給定目標值 targetSum 的條件。oop

具體思路是,在不斷的先序遞歸遍歷中ui

每次遞歸,都要用 targetSum 減去當前結點值,當到了葉子結點的時候,判斷被不斷減掉的 targetSum 當前的值是否和單當前結點值相同。若相同,返回 True。spa

def hasPathSum(self, root, targetSum):
    if not root:
        return False
    if not root.left and not root.right and targetSum == root.val:
        return True
    return self.hasPathSum(root.left, targetSum-root.val) or self.hasPathSum(root.right, targetSum-root.val)
複製代碼

這就是一個簡單的先序遍歷,對於遞歸思惟方式解決有關「樹」的題目的時候,仍是比較不容易想清楚.code

多思考,多練習。

非遞歸方式

使用層序遍歷的思考過程。

在不斷遍歷訪問結點的過程當中,須要記錄兩個值,一個是結點,另一個是從根結點到當前結點路徑和,這裏咱們用 Python 的元祖來表示(結點, 從根結點到當前結點路徑和)

層序遍歷的過程,這裏先不贅述了,須要看詳細說明的,能夠轉戰這裏mp.weixin.qq.com/s/nTB41DvE7…

看代碼:

def hasPathSum_bfs(self, root, targetSum):
    if not root:
        return False
    queue = collections.deque()
    # 使用元祖存放結點信息(結點,當前結點自頂向下路徑和)
    queue.append((root, root.val))
    while queue:
        node, node_val = queue.pop()
        if not node.left and not node.right and node_val == targetSum:
            return True
        if node.left:
            queue.appendleft((node.left, node.left.val + node_val))
        if node.right:
            queue.appendleft((node.right, node.right.val + node_val))
    return False
複製代碼

尤爲是不少地方都會使用像這種 BFS 的方式進行遍歷訪問,並且主要適用於一些從頂向下的題目。這個是一道很典型的從頂向下題目。

對於這一類從頂向下的題目,使用 BFS 的思路是很是清晰的。

所有代碼

# -*- coding:utf-8 -*-
# !/usr/bin/env python

import collections

# 樹結點類
class TreeNode(object):
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution(object):
    def hasPathSum(self, root, targetSum):
        if not root:
            return False
        if not root.left and not root.right and targetSum == root.val:
            return True
        return self.hasPathSum(root.left, targetSum-root.val) or self.hasPathSum(root.right, targetSum-root.val)

    def hasPathSum_bfs(self, root, targetSum):
        if not root:
            return False
        queue = collections.deque()
        # 使用元祖存放結點信息(結點,當前結點自頂向下路徑和)
        queue.append((root, root.val))
        while queue:
            node, node_val = queue.pop()
            if not node.left and not node.right and node_val == targetSum:
                return True
            if node.left:
                queue.appendleft((node.left, node.left.val + node_val))
            if node.right:
                queue.appendleft((node.right, node.right.val + node_val))
        return False


if __name__ == "__main__":
    # 新建節點
    root = TreeNode(5)
    node_B = TreeNode(3)
    node_C = TreeNode(6)
    node_D = TreeNode(1)
    node_E = TreeNode(2)
    node_F = TreeNode(4)
    node_G = TreeNode(9)
    node_H = TreeNode(7)
    node_I = TreeNode(0)
    node_J = TreeNode(9)
    # 構建二叉樹
    # 5
    # / \
    # 3 6
    # / \ / \
    # 1 2 4 9
    # / \
    # 7 0
    # \
    # 9
    root.left, root.right = node_B, node_C
    node_B.left, node_B.right = node_D, node_E
    node_C.left, node_C.right = node_F, node_G
    node_D.left, node_D.right = node_H, node_I
    node_I.right = node_J

    s = Solution()
    print(s.hasPathSum(root, 18))
    print(s.hasPathSum_bfs(root, 18))
複製代碼

Github

github.com/xiaozhutec/…

玩的開心呀 ღ( ´・ᴗ・` )

相關文章
相關標籤/搜索