当前位置:   article > 正文

Leetcode——中级部分——树和图部分——Python实现_leetcode python图算法

leetcode python图算法

中序遍历二叉树

给定一个二叉树,返回它的中序 遍历

示例:

  1. 输入: [1,null,2,3]
  2. 1
  3. \
  4. 2
  5. /
  6. 3
  7. 输出: [1,3,2]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

 

我的解答:

方法1——递归实现:

  1. # Definition for a binary tree node.
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. def inorderTraversal(self, root):
  9. """
  10. :type root: TreeNode
  11. :rtype: List[int]
  12. """
  13. res = []
  14. def recurse(node):
  15. if node != None:
  16. recurse(node.left)
  17. res.append(node.val)
  18. recurse(node.right)
  19. recurse(root)
  20. return res

方法2——迭代实现(主要会用到数据结构 stack):

  1. class Solution:
  2. def inorderTraversal(self, root):
  3. """
  4. :type root: TreeNode
  5. :rtype: List[int]
  6. """
  7. if root == None:
  8. return []
  9. stack = []
  10. result = []
  11. node = root
  12. while node or (len(stack) > 0):
  13. if node != None:
  14. stack.append(node)
  15. node = node.left
  16. else:
  17. node = stack.pop()
  18. result.append(node.val)
  19. node = node.right
  20. return result

 

二叉树的锯齿形层次遍历

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

例如:
给定二叉树 [3,9,20,null,null,15,7],

  1. 3
  2. / \
  3. 9 20
  4. / \
  5. 15 7

返回锯齿形层次遍历如下:

  1. [
  2. [3],
  3. [20,9],
  4. [15,7]
  5. ]

 

我的解答:

层次遍历采用队列实现。
相比于标准层次遍历,这里只是在result中加入templist时加了一步判断flag是否为负的步骤,如果为负,表示是偶数次遍历应该从右往左,将templist更新为逆序

  1. # Definition for a binary tree node.
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. def zigzagLevelOrder(self, root):
  9. """
  10. :type root: TreeNode
  11. :rtype: List[List[int]]
  12. """
  13. if root == None:
  14. return []
  15. result = []
  16. queue = [root]
  17. flag = 1
  18. while queue:
  19. length = len(queue)
  20. tempList = []
  21. #下面是一层的结点的遍历
  22. for i in range(length):
  23. node = queue.pop(0)
  24. tempList.append(node.val)
  25. if node.left != None:
  26. queue.append(node.left)
  27. if node.right != None:
  28. queue.append(node.right)
  29. #判断是否为偶数层(flag),如果是就需要逆序tempList
  30. if flag == -1:
  31. tempList = tempList[::-1]
  32. result.append(tempList)
  33. flag = flag * (-1)
  34. return result

 

从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

  1. 前序遍历 preorder = [3,9,20,15,7]
  2. 中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

  1. 3
  2. / \
  3. 9 20
  4. / \
  5. 15 7

 

我的解答:

前序遍历先访问根节点,因此前序遍历序列的第一个字母肯定就是根节点,即A是根节点;然后,由于中序遍历先访问左子树,再访问根节点,最后访问右子树,所以我们找到中序遍历中A的位置,然后A左边的字母就是左子树了,也就是CBD是根节点的左子树;同样的,得到EF为根节点的右子树。将前序遍历序列分成BCD和EF,分别对左子树和右子树应用同样的方法,递归下去,二叉树就成功构建好了。

  1. # Definition for a binary tree node.
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. def buildTree(self, preorder, inorder):
  9. """
  10. :type preorder: List[int]
  11. :type inorder: List[int]
  12. :rtype: TreeNode
  13. """
  14. if preorder == []:
  15. return None
  16. root = TreeNode(preorder[0]) #构建一个树对象
  17. i = inorder.index(root.val) #在中序遍历序列中找到根节点索引
  18. root.left = self.buildTree(preorder[1:1+i],inorder[:i])
  19. root.right = self.buildTree(preorder[1+i:],inorder[i+1:])
  20. return root

 

每个节点的右向指针

给定一个二叉树

  1. struct TreeLinkNode {
  2. TreeLinkNode *left;
  3. TreeLinkNode *right;
  4. TreeLinkNode *next;
  5. }

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

说明:

  • 你只能使用额外常数空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
  • 你可以假设它是一个完美二叉树(即所有叶子节点都在同一层,每个父节点都有两个子节点)。

示例:

给定完美二叉树,

  1. 1
  2. / \
  3. 2 3
  4. / \ / \
  5. 4 5 6 7

调用你的函数后,该完美二叉树变为:

  1. 1 -> NULL
  2. / \
  3. 2 -> 3 -> NULL
  4. / \ / \
  5. 4->5->6->7 -> NULL

 

我的解答:

采用BFS遍历(层次遍历),每一层遍历后,遍历节点列表,列表中前一节点next指针指向后一节点。

  1. # Definition for binary tree with next pointer.
  2. # class TreeLinkNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. # self.next = None
  8. class Solution:
  9. # @param root, a tree link node
  10. # @return nothing
  11. def connect(self, root):
  12. node = [root]
  13. while node:
  14. temp = []
  15. for i in node:
  16. if i != None:
  17. if i.left != None:
  18. temp.append(i.left)
  19. if i.right != None:
  20. temp.append(i.right)
  21. for index,nodeValue in enumerate(node[:-1]):
  22. nodeValue.next = node[index+1]
  23. node = temp

 

二叉搜索树中第K小的元素

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 个最小的元素。

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

示例 1:

  1. 输入: root = [3,1,4,null,2], k = 1
  2. 3
  3. / \
  4. 1 4
  5. \
  6.   2
  7. 输出: 1

示例 2:

  1. 输入: root = [5,3,6,2,4,null,null,1], k = 3
  2. 5
  3. / \
  4. 3 6
  5. / \
  6. 2 4
  7. /
  8. 1
  9. 输出: 3

进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?

 

我的解答:

层次遍历得到二叉搜索树每一个元素,进行排序(list的sort函数),返回第k小元素。

  1. # Definition for a binary tree node.
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. def kthSmallest(self, root, k):
  9. """
  10. :type root: TreeNode
  11. :type k: int
  12. :rtype: int
  13. """
  14. #下面是层次遍历过程
  15. queue = [root]
  16. lyst = []
  17. while queue:
  18. node = queue.pop(0)
  19. lyst.append(node.val) #list保存每一个元素
  20. if node.left != None:
  21. queue.append(node.left)
  22. if node.right != None:
  23. queue.append(node.right)
  24. #下面是排序过程
  25. lyst.sort()
  26. #下面是返回第k小元素过程
  27. return lyst[k-1]

 

岛屿的个数

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

  1. 输入:
  2. 11110
  3. 11010
  4. 11000
  5. 00000
  6. 输出: 1

示例 2:

  1. 输入:
  2. 11000
  3. 11000
  4. 00100
  5. 00011
  6. 输出: 3

 

我的解答:

我们遍历矩阵的每一个点,对每个点都尝试进行一次深度优先搜索,如果搜索到1,就继续向它的四周搜索。同时我们每找到一个1,就将其标为0,这样就能把整个岛屿变成0。我们只要记录对矩阵遍历时能进入多少次搜索,就代表有多少个岛屿。

  1. class Solution:
  2. def numIslands(self, grid):
  3. """
  4. :type grid: List[List[str]]
  5. :rtype: int
  6. """
  7. #注意:这个题目里面每个数字都是字符!!!
  8. row = len(grid)
  9. if row == 0:
  10. return 0
  11. column = len(grid[0])
  12. if column == 0:
  13. return 0
  14. res = 0
  15. for i in range(row):
  16. for j in range(column):
  17. if grid[i][j] == '1':
  18. res = res + 1 #岛屿数+1
  19. self.DFS(grid,i,j) #保证这个岛屿所有连接的位置都置零
  20. return res
  21. #深度优先遍历(所有相连岛屿置零操作)
  22. def DFS(self,grid,i,j):
  23. #注意:这里需要一个判断是否溢出边界的条件
  24. if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]):
  25. return
  26. if grid[i][j] == '1':
  27. grid[i][j] = '0'
  28. self.DFS(grid,i-1,j)
  29. self.DFS(grid,i+1,j)
  30. self.DFS(grid,i,j-1)
  31. self.DFS(grid,i,j+1)

注意:这里列表中不是整数数字而是字符!!

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/256978
推荐阅读
相关标签
  

闽ICP备14008679号