深度优先搜索(leetcode)

深度优先搜索

  1. 判断一棵树是不是二叉搜索树

注:

  1. 判断两个二叉树是否相同
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL && q==NULL)
            return true;
        if(p==NULL || q==NULL)
            return false;
        if(p->val != q->val)
            return false;
        return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
    }
};
  1. (LeetCode 101) 判断一棵树是不是镜像二叉树
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root==NULL)
            return true;
        return Symmetric(root->left,root->right);
    }
private :
    bool Symmetric(TreeNode*a, TreeNode *b){
        if(!a && !b)
            return true;
        if(!a||  !b)
            return false;
        return (a->val==b->val)&&Symmetric(a->left,b->right) && Symmetric(a->right,b->left);
    }
};
  1. (LeetCode 102) 树的层次遍历
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if TreeNode is None:
            return []
        result = []
        que = [root]
        que2 = []
        tmp = []
        while(len(que)>0):
            vv= que.pop(0)
            if vv== None:
                continue
            if vv.left!=None:
                que2.append(vv.left)
            if vv.right!=None:
                que2.append(vv.right)
            tmp.append(vv.val)
            if(len(que)==0):
                result.append(tmp)
                tmp = []
                que = que2.copy()
                que2 = []
        return result     
  1. (leetcode 104) 二叉树最大深度
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root)
            return 0;
        return max(maxDepth(root->left)+1,maxDepth(root->right)+1);
    }
};
  1. (leetcode 105) 从前序与中序遍历构造二叉树
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if len(preorder)==0:
            return None
        root = preorder[0]
        indx = inorder.index(root)
        root = TreeNode(root)
        root.left = self.buildTree(preorder[1:1+indx],inorder[:indx])
        root.right = self.buildTree(preorder[1+indx:],inorder[indx+1:])
        return root

7.(leetcode 106) 从后序中序建立树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        if len(postorder)==0:
            return None
        root = postorder[-1]
        indx = inorder.index(root)
        root = TreeNode(root)
        root.left=self.buildTree(inorder[:indx],postorder[:indx])
        root.right=self.buildTree(inorder[indx+1:],postorder[indx:-1])
        return root
  1. (leetcode 108) 有序数组转为二叉树
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if len(nums)==0:
            return None
        lent = len(nums)
        root = TreeNode(nums[int(lent/2)])
        root.left = self.sortedArrayToBST(nums[:int(lent/2)])
        root.right = self.sortedArrayToBST(nums[int(lent/2)+1:]) 
        return root
  1. (leetcode 109) 有序链表转为二叉搜索树
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sortedListToBST(self, head: ListNode) -> TreeNode:
        if (head==None):
            return None
        nums = []
        while(head):
            nums.append(head.val)
            head = head.next
        return self.sortedArrayToBST(nums)

    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if len(nums)==0:
            return None
        lent = len(nums)
        root = TreeNode(nums[int(lent/2)])
        root.left = self.sortedArrayToBST(nums[:int(lent/2)])
        root.right = self.sortedArrayToBST(nums[int(lent/2)+1:]) 
        return root
  1. (leetcode 110) 判断平衡二叉树
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if(root==None):
            return True
        if (self.calHigh(root.left) - self.calHigh(root.right) >1) or (self.calHigh(root.left) - self.calHigh(root.right) <-1):
            return False
        return self.isBalanced(root.left) and self.isBalanced(root.right)
    
    def calHigh(self,a):
        if(a==None):
            return 0
        return max(self.calHigh(a.left)+1, self.calHigh(a.right)+1)
        
  1. (leetcode 111)二叉树的最小深度

注:和最大深度不一样

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if(root==None):
            return 0
        if(root.left==None) and (root.right==None):
            return 1
        elif not root.left:
            return self.minDepth(root.right) +1
        elif not root.right:
            return self.minDepth(root.left) +1
        else:
            return min(self.minDepth(root.left),self.minDepth(root.right)) +1

12.(leetcode 112) 路径总和

注:当树为空且sum为0时,需要特殊考虑

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if not root:
            return False
        if not root.left and sum==root.val and not root.right:
            return True
        return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right,sum-root.val)
  1. (leetcode 113)路径总和及路径

注:这题需要好好琢磨一下,思路和上一题类似,但是多了添加满足条件的点。这应该涉及到递归工作的原理,需要看看相关原理。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        if not root:
            return []
        self.path = []
        self.tmp = sum
        
        def calSum(tmp_path,now,root):
            if not root:
                return False
            if not root.left and not root.right and root.val + now== self.tmp:
                self.path.append(tmp_path+[root.val])
            if root.left:
                calSum(tmp_path+[root.val],now+root.val,root.left)
            if root.right:
                calSum(tmp_path+[root.val],now+root.val,root.right)
        calSum([],0,root)
        return self.path
  1. (leetcode 114)二叉树展开为链表

注:代码中注释掉的有问题。涉及到深拷贝,浅拷贝?

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if not root:
            return None
        pre = []
        def preOrder(root):
            if not root:
                return 
            pre.append(root.val)
            preOrder(root.left)
            preOrder(root.right)
        preOrder(root)
        copy = root
        # copy = TreeNode(pre[0])
        for v in pre[1:]:
            copy.right = TreeNode(v)
            copy.left = None
            copy = copy.right
  1. (lletcode 116)填充下一个右侧节点指针
"""
# Definition for a Node.
class Node:
    def __init__(self, val, left, right, next):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""
class Solution(object):
    def connect(self, root):
        """
        :type root: TreeLinkNode
        :rtype: nothing
        """
        if not root:
            return None
        cur  = root
        next = root.left
        while cur.left :
            cur.left.next = cur.right
            if cur.next:
                cur.right.next = cur.next.left
                cur = cur.next
            else:
                cur = next
                next = cur.left
        return root
  1. (leetcode 117) 填充每个节点的下一个节点
# Definition for binary tree with next pointer.
# class TreeLinkNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None

class Solution(object):
    def connect(self, root):
        """
        :type root: TreeLinkNode
        :rtype: nothing
        """
        if root:
            tmp,tmp1,tmp2 = root,None,None
            while tmp:
                if tmp.left:
                    if tmp1:
                        tmp1.next = tmp.left
                    tmp1 = tmp.left
                    if not tmp2:
                        tmp2 = tmp1
                if tmp.right:
                    if tmp1:
                        tmp1.next = tmp.right
                    tmp1 = tmp.right
                    if not tmp2:
                        tmp2 = tmp1
                tmp = tmp.next
            self.connect(tmp2)
            return root
  1. (leetcode 124) 二叉树的最大路径和

注:需要重新体会

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.maxsum = float('-inf')
        self.calMax(root)
        return self.maxsum
            
    def calMax(self,root):
        if not root:
            return 0
        left = self.calMax(root.left)
        right = self.calMax(root.right)
        left = left if left > 0 else 0
        right = right if right > 0 else 0
        self.maxsum = max(self.maxsum, root.val+left+right)
        return max(left,right) + root.val
  1. (leetcode 129)求根到叶子节点数字之和

从根到叶子节点到底是怎么样放置顺序的,tmp + [root.val] ?

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sumNumbers(self, root: TreeNode) -> int:
        self.result = []
        self.findPath([],root)
        sumr = 0
        for v in self.result:
            sumr += int("".join(map(str,v)))
        return sumr
    def findPath(self,tmp,root):
        if not root:
            return
        if not root.left and not root.right:
            self.result.append(tmp+[root.val])
        self.findPath(tmp + [root.val],root.left)
        self.findPath(tmp + [root.val],root.right)
  1. (leetcode 130) 被围住的区域

注: 思路很精妙

class Solution:
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        def fill(x,y):
            if x<0 or x> row-1 or y<0 or y > col - 1 or board[x][y] != 'O':
                return
            queue.append((x,y))
            board[x][y] = 'D'

        def bfs(x,y):
            if board[x][y] == "O":
                queue.append((x,y))
                fill(x,y)
            while queue:
                curr=queue.pop(0); i=curr[0]; j=curr[1]
                fill(i+1,j);fill(i-1,j);fill(i,j+1);fill(i,j-1)

        
        if len(board) == 0:
            return
        row = len(board)
        col = len(board[0])
        queue = []
        for i in range(row):
            bfs(i,0)
            bfs(i,col-1)
        for i in range(col):
            bfs(0,i)
            bfs(row-1,i)
        for i in range(row):
            for j in range(col):
                if board[i][j] == 'D': board[i][j] = 'O'
                elif board[i][j] == 'O': board[i][j] = 'X'
  1. (leetcode 897) 给定一个树,按中序遍历重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def increasingBST(self, root: TreeNode) -> TreeNode:
        self.mid = []
        self.midOrder(root)
        if len(self.mid)==0:
            return None
        tmp = root = TreeNode(self.mid[0])
        for v in self.mid[1:]:
            tmpNode = TreeNode(v)
            tmp.left = None
            tmp.right = tmpNode
            tmp = tmp.right
        return root
    def midOrder(self,root):
        if not root:
            return
        self.midOrder(root.left)
        self.mid.append(root.val)
        self.midOrder(root.right)
  1. (leetcode 559)给定一个 N 叉树,找到其最大深度。
"""
# Definition for a Node.
class Node:
    def __init__(self, val, children):
        self.val = val
        self.children = children
"""
class Solution:
    def maxDepth(self, root: 'Node') -> int:
        if not root:
            return 0
        return self.calDepth(root)
    
    def calDepth(self,root):
        if len(root.children)==0:
            return 1
        return max([self.calDepth(v) for v in root.children]) + 1
  1. (leetcode 773) 为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

注:广度优先遍历,注意如果初始像素点和新像素点相等,直接返回。涉及到会不会陷入死循环。

class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:
        
        def fill(x,y):
            if x<0 or x> row-1 or y<0 or y>col-1 or image[x][y] != pix:
                return
            queue.append((x,y))
            image[x][y] = newColor
        
        def bfs(x,y):
            if image[x][y]==pix:
                fill(x,y)
            while queue:
                cur = queue.pop(0)
                i = cur[0]; j = cur[1]
                fill(i+1,j);fill(i-1,j);fill(i,j+1);fill(i,j-1)
        
        row = len(image)
        col = len(image[0])
        pix = image[sr][sc]
        if pix == newColor:
            return image
        queue = []
        judge = [[0 for i in range(col)] for j in range(row)]
        bfs(sr,sc)
        return image
  1. (leetcode 872) 叶子相似的树
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def leafSimilar(self, root1: TreeNode, root2: TreeNode) -> bool:
        def findLeaf(root,leaf):
            if not root:
                return
            if not root.left and not root.right:
                leaf.append(root.val)
            findLeaf(root.left,leaf)
            findLeaf(root.right,leaf)
            
        leaf1 = []
        leaf2 = []
        findLeaf(root1,leaf1)        
        findLeaf(root2,leaf2)
        for i in range(len(leaf1)):
            if leaf1[i] != leaf2[i]:
                return False
        return True
  1. (leetcode 690) 员工的重要性

这道题思路挺简单,但是在id的使用上出现了问题

"""
# Employee info
class Employee:
    def __init__(self, id, importance, subordinates):
        # It's the unique id of each node.
        # unique id of this employee
        self.id = id
        # the importance value of this employee
        self.importance = importance
        # the id of direct subordinates
        self.subordinates = subordinates
"""
class Solution:
    def getImportance(self, employees, id):
        """
        :type employees: Employee
        :type id: int
        :rtype: int
        """
        def computeImportance(id):
            # if len(employees[id].subordinates)==0:
            #     return employees[id].importance
            score = sum([computeImportance(v) for v in emps[id].subordinates]) + emps[id].importance
            return score
        emps = {employee.id: employee for employee in employees}
        return computeImportance(id)
  1. (leetcode 257) 给定一个二叉树,返回所有从根节点到叶子节点的路径。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        
        def findPath(root,tmp):
            if not root:
                return None
            if not root.left and not root.right:
                path.append(tmp + [root.val])
            findPath(root.left,tmp+[root.val])
            findPath(root.right,tmp+[root.val])
        
        path = []
        findPath(root,[])    
        path = ["->".join(map(str,v)) for v in path]
        return path
posted @ 2019-04-04 11:38  静_渊  阅读(684)  评论(0编辑  收藏  举报