Trees and Graphs

  1. Validate Binary Search Tree
# Validate Binary Search Tree
# Given a binary tree, 
# determine if it is a valid binary search tree (BST).

class Solution:
    def isValidBST(self, root):   #输入一棵树
        output = []               #树放入列表
        self.inOrder(root, output)#中序放入
        for i in range(1, len(output)):
            if output[i-1] >= output[i]:#中序递增即为BST
                return False   #任一非增 中断False
        return True

    def inOrder(self, root, output):
        if root is None:
            return
        self.inOrder(root.left, output) #递归调用
        output.append(root.val) # 中序 左中右 递增
        self.inOrder(root.right, output)#递归调用
        
  1. Binary Tree Inorder Traversal
# Binary Tree Inorder Traversal
# Given a binary tree;
# return the inorder traversal of its nodes' values.
class Solution:   
    def inorderTraversal(self, root):
        res, stack = [], []  # 结果、中间数组;
        while True:
            while root: #可循环其左节点的头结点
                stack.append(root) # 存节点
                root = root.left   # 一直左
            if not stack:          
                return res
            node = stack.pop()    # 存下最左结点
            res.append(node.val)  # 存节点值
            root = node.right     # 左无 其右节点循环左、或存上层左&循环其右 
  1. Binary Tree Level Order Traversal
# Binary Tree Level Order Traversal
# Given a binary tree, 
# return the level order traversal of its nodes' values.
# (ie, from left to right, level by level).

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]: #输入数 输出二维数组
        if not root:  
            return []
        ans, level = [], [root]  # 结果数据集;当前层节点
        while level:  # 遍历每个当前层节点  
            ans.append([node.val for node in level]) #归并当前层集level至res
            temp = []  # 下层节点集
            for node in level: #确定下一层节点集temp
                temp.extend([node.left, node.right]) #extend元素添加
            level = [leaf for leaf in temp if leaf] # 进入下一层去遍历
        return ans
  1. Binary Tree Zigzag Level Order Traversal
# 103. Binary Tree Zigzag Level Order Traversal
# Given a binary tree, 
# return the zigzag level order traversal of its nodes' values. 
#(ie, from left to right, then right to left for the next level and alternate between).
class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:return []
        res, level, direction = [], [root], 1
        while level:
            res.append([n.val for n in level][::direction])
            direction *= -1
            level = [kid for node in level for kid in (node.left, node.right) if kid]
        return res
  1. Populating Next Right Pointers in Each Node
## Populating Next Right Pointers in Each Node
# You are given a perfect binary tree 
# where all leaves same level, and every parent has two children. 
# Populate each next pointer to point to its next right node. 
# If there is no next right node, the next pointer should be set to NULL.

import collections 
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        Q = collections.deque([root])
        while Q:
            size = len(Q)
            for i in range(size):
                node = Q.popleft()
                if i < size - 1:
                    node.next = Q[0]  #添加next
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        return root
    
# Notes:
# deque 是双边队列(double-ended queue),具有队列和栈的性质,在 list 的基础上增加了移动、旋转和增删等
# d = collections.deque([])
# d.append('a') # 在最右边添加一个元素,此时 d=deque('a')
# d.appendleft('b') # 在最左边添加一个元素,此时 d=deque(['b', 'a'])
# d.extend(['c','d']) # 在最右边添加所有元素,此时 d=deque(['b', 'a', 'c', 'd'])
# d.extendleft(['e','f']) # 在最左边添加所有元素,此时 d=deque(['f', 'e', 'b', 'a', 'c', 'd'])
# d.pop() # 将最右边的元素取出,返回 'd',此时 d=deque(['f', 'e', 'b', 'a', 'c'])
# d.popleft() # 将最左边的元素取出,返回 'f',此时 d=deque(['e', 'b', 'a', 'c'])
# d.rotate(-2) # 向左旋转两个位置(正数则向右旋转),此时 d=deque(['a', 'c', 'e', 'b'])
# d.count('a') # 队列中'a'的个数,返回 1
# d.remove('c') # 从队列中将'c'删除,此时 d=deque(['a', 'e', 'b'])
# d.reverse() # 将队列倒序,此时 d=deque(['b', 'e', 'a'])
  1. Populating Next Right Pointers in Each Node
## Populating Next Right Pointers in Each Node
# You are given a perfect binary tree 
# where all leaves same level, and every parent has two children. 
# Populate each next pointer to point to its next right node. 
# If there is no next right node, the next pointer should be set to NULL.

import collections 
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        Q = collections.deque([root])
        while Q:
            size = len(Q)
            for i in range(size):
                node = Q.popleft()
                if i < size - 1:
                    node.next = Q[0]  #添加next
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        return root
    
# Notes:
# deque 是双边队列(double-ended queue),具有队列和栈的性质,在 list 的基础上增加了移动、旋转和增删等
# d = collections.deque([])
# d.append('a') # 在最右边添加一个元素,此时 d=deque('a')
# d.appendleft('b') # 在最左边添加一个元素,此时 d=deque(['b', 'a'])
# d.extend(['c','d']) # 在最右边添加所有元素,此时 d=deque(['b', 'a', 'c', 'd'])
# d.extendleft(['e','f']) # 在最左边添加所有元素,此时 d=deque(['f', 'e', 'b', 'a', 'c', 'd'])
# d.pop() # 将最右边的元素取出,返回 'd',此时 d=deque(['f', 'e', 'b', 'a', 'c'])
# d.popleft() # 将最左边的元素取出,返回 'f',此时 d=deque(['e', 'b', 'a', 'c'])
# d.rotate(-2) # 向左旋转两个位置(正数则向右旋转),此时 d=deque(['a', 'c', 'e', 'b'])
# d.count('a') # 队列中'a'的个数,返回 1
# d.remove('c') # 从队列中将'c'删除,此时 d=deque(['a', 'e', 'b'])
# d.reverse() # 将队列倒序,此时 d=deque(['b', 'e', 'a'])

6.Poputlating Next Right Pointers in Each Node II

# 117. Populating Next Right Pointers in Each Node II
# Given a binary tree
# Populate each next pointer to point to its next right node. 
# If there is no next right node, the next pointer should be set to NULL.
# Initially, all next pointers are set to NULL.
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        old_root = root 
        prekid = Node(0)
        kid = prekid   # Let kid point to prekid 
        while root:
            while root:
                if root.left:
                    kid.next = root.left
                    kid = kid.next
                if root.right:
                    kid.next = root.right
                    kid = kid.next
                root = root.next
            root, kid = prekid.next, prekid
            kid.next = None  # Reset the chain for prekid
        return old_root
  1. Lowest Common Ancestor of a Binary Search Tree
# Lowest Common Ancestor of a Binary Search Tree
class Solution:
    # def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    #     while root:
    #         if p.val < root.val > q.val:
    #             root = root.left
    #         elif p.val > root.val < q.val:
    #             root = root.right
    #         else:
    #             return root
            
    def lowestCommonAncestor(self, root, p, q):
        if p.val < root.val > q.val:
            return self.lowestCommonAncestor(root.left, p, q)
        if p.val > root.val < q.val:
            return self.lowestCommonAncestor(root.right, p, q)
        return root
  1. Lowest Common Ancestor of a Binary Tree
# binary tree==>Lowest Common Ancestor==>
# 236. Lowest Common Ancestor of a Binary Tree
class Solution:
    def lowestCommonAncestor(self, root, p, q):
        if root in (None, p, q): return root
        left, right = (self.lowestCommonAncestor(kid, p, q)
                       for kid in (root.left, root.right))
        return root if left and right else left or right
    
    def lowestCommonAncestor(self, root, p, q):
        stack = [root]
        parent = {root: None}
        while p not in parent or q not in parent:
            node = stack.pop()
            if node.left:
                parent[node.left] = node
                stack.append(node.left)
            if node.right:
                parent[node.right] = node
                stack.append(node.right)
        ancestors = set()
        while p:
            ancestors.add(p)
            p = parent[p]
        while q not in ancestors:
            q = parent[q]
        return q
  1. Given preorder and inorder traversal of a tree, construct the binary tree.
# 105. Construct Binary Tree from Preorder and Inorder Traversal
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if inorder:
            ind = inorder.index(preorder.pop(0))
            root = TreeNode(inorder[ind])
            root.left = self.buildTree(preorder, inorder[0:ind])
            root.right = self.buildTree(preorder, inorder[ind+1:])
            return root
  1. Number of Islands
# Number of Islands
# Given a 2d grid map of '1's (land) and '0's (water),
# count the number of islands. 
# An island is surrounded by water;
# formed by connecting adjacent lands horizontally or vertically. 
# assume all four edges of the grid are all surrounded by water.
class Solution:
    def numIslands(self, grid):
        if not grid:
            return 0     
        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    self.dfs(grid, i, j)
                    count += 1
        return count
    def dfs(self, grid, i, j):
        if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1':
            return
        grid[i][j] = '#'
        self.dfs(grid, i+1, j)
        self.dfs(grid, i-1, j)
        self.dfs(grid, i, j+1)
        self.dfs(grid, i, j-1)
  1. Clone Graph
"""
# Definition for a Node.
class Node:
    def __init__(self, val = 0, neighbors = []):
        self.val = val
        self.neighbors = neighbors
"""
# Clone Graph
# Given a reference of a node in a connected undirected graph.
# Return a deep copy (clone) of the graph.
# Each node in the graph contains a val (int) and a list (List[Node]) of its neighbors.

from collections import deque
class Solution(object):

    def cloneGraph(self, node):

        if not node:
            return node

        # Dictionary to save the visited node and it's respective clone
        # as key and value respectively. This helps to avoid cycles.
        visited = {}

        # Put the first node in the queue
        queue = deque([node])
        # Clone the node and put it in the visited dictionary.
        visited[node] = Node(node.val, [])

        # Start BFS traversal
        while queue:
            # Pop a node say "n" from the from the front of the queue.
            n = queue.popleft()
            # Iterate through all the neighbors of the node
            for neighbor in n.neighbors:
                if neighbor not in visited:
                    # Clone the neighbor and put in the visited, if not present already
                    visited[neighbor] = Node(neighbor.val, [])
                    # Add the newly encountered node to the queue.
                    queue.append(neighbor)
                # Add the clone of the neighbor to the neighbors of the clone node "n".
                visited[n].neighbors.append(visited[neighbor])

        # Return the clone of the node from visited.
        return visited[node]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,888评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,677评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,386评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,726评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,729评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,337评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,902评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,807评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,349评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,439评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,567评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,242评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,933评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,420评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,531评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,995评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,585评论 2 359

推荐阅读更多精彩内容