天天分享一個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))
複製代碼
玩的開心呀 ღ( ´・ᴗ・` )