Trees and Graphs

2020-01-19  本文已影响0人  inspiredhss
  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]
上一篇下一篇

猜你喜欢

热点阅读