python二叉搜索树建立_二叉搜索树--LeetCode(python)

几种遍历方式:

验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。 节点的右子树只包含大于当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:

2

/ \

1   3

输出: true

示例 2:

输入:

5

/ \

1   4

/ \

3   6

输出: false

解释: 输入为: [5,1,4,null,null,3,6]。

根节点的值为 5 ,但是其右子节点值为 4 。

解法

一开始想的是直接和左右值比较,但是忽略了隔层之间可能存在不符合规定的可能性,代码是错的。最后参考了别人的代码,发现别人是从上往下比较的,将每个节点往左就是最大,往右就是最小值,太机智了。还有就是在传输过程中原函数不能够传递最大最小值,又重新定义了一个函数调用遍历方法:使用中序遍历,基本上所有二叉搜索树的操作都可以这样做

解法一:

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def validBST(self,root,small,large):

if root==None:

return True

if small>=root.val or large<=root.val:

return False

return self.validBST(root.left,small,root.val) and self.validBST(root.right,root.val,large)

def isValidBST(self, root):

"""

:type root: TreeNode

:rtype: bool

"""

return self.validBST(root,-2**32,2**32-1)

解法二:

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

pre=None

def isValidBST(self, root):

"""

:type root: TreeNode

:rtype: bool

"""

if root is None:

return True

Bool= self.isValidBST(root.left)

if self.pre!=None:

Bool=Bool and (self.pre.val

self.pre=root

Bool=Bool and self.isValidBST(root.right)

return Bool

二叉搜索树迭代器

实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。 调用 next() 将返回二叉搜索树中的下一个最小的数。

示例:

BSTIterator iterator = new BSTIterator(root); iterator.next(); // 返回 3 iterator.next(); // 返回 7 iterator.hasNext(); // 返回 true iterator.next(); // 返回 9 iterator.hasNext(); // 返回 true iterator.next(); // 返回 15 iterator.hasNext(); // 返回 true iterator.next(); // 返回 20 iterator.hasNext(); // 返回 false

提示: next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。 你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。

解法 开始一直没想出来,一直想怎么找到输出节点后删除节点。其实可以用数组存储的。参考:https://blog.csdn.net/qq_17550379/article/details/86082379 有三种方法:

通过遍历(中序)将二叉树的数据存放到数组中,然后每次next操作时取出最小值即可。用heapq实现最小堆将左边不断压栈,那么栈中存放的就是从大到小的值。调用next的时候,我们只需要弹出栈顶元素即可,同时我们需要将right加入栈中(非递归先序遍历二叉树的思路)

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class BSTIterator(object):

def __init__(self, root):

"""

:type root: TreeNode

"""

self.root = root

self.stack = []

self.pushleft(self.root)

def pushleft(self, cur):

while cur:

self.stack.append(cur)

cur = cur.left

def next(self):

"""

@return the next smallest number

:rtype: int

"""

tmp = self.stack.pop()

self.pushleft(tmp.right)

return tmp.val

def hasNext(self):

"""

@return whether we have a next smallest number

:rtype: bool

"""

return True if self.stack else False

# Your BSTIterator object will be instantiated and called as such:

# obj = BSTIterator(root)

# param_1 = obj.next()

# param_2 = obj.hasNext()

Search in a Binary Search Tree

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

给定二叉搜索树:

4

/ \

2   7

/ \

1   3

和值: 2 你应该返回如下子树:

2

/ \

1   3

在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。

解法 比较简单

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def searchBST(self, root, val):

"""

:type root: TreeNode

:type val: int

:rtype: TreeNode

"""

if not root:

return None

cur = root

while cur:

if val == cur.val:

return cur

elif val < cur.val:

cur = cur.left

else:

cur = cur.right

return None

Insert into a Binary Search Tree

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 保证原始二叉搜索树中不存在新值。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。

例如,

给定二叉搜索树:

4

/ \

2   7

/ \

1   3

和 插入的值: 5

你可以返回这个二叉搜索树:

4

/   \

2     7

/ \   /

1   3 5

或者这个树也是有效的:

5

/   \

2     7

/ \

1   3

\

4

解法 正常的搜索,就按照叶子节点的方法插入

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def insertIntoBST(self, root, val):

"""

:type root: TreeNode

:type val: int

:rtype: TreeNode

"""

if not root:

return TreeNode(val)

cur = root

while cur:

if val < cur.val:

if not cur.left:

cur.left = TreeNode(val)

return root

else:

cur = cur.left

else:

if not cur.right:

cur.right = TreeNode(val)

return root

else:

cur = cur.right

return root

Delete Node in a BST

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点; 如果找到了,删除它。 说明: 要求算法时间复杂度为 O(h),h 为树的高度。

示例:

root = [5,3,6,2,4,null,7]

key = 3

5

/ \

3   6

/ \   \

2   4   7

给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。

一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

5

/ \

4   6

/     \

2       7

另一个正确答案是 [5,2,6,null,4,null,7]。

5

/ \

2   6

\   \

4   7

解法 参考:https://blog.csdn.net/qq_39315740/article/details/89034263 删除节点主要有三种情况:

节点只存在左子树,那么我们直接用左子树代替根节点即可;节点只存在右子树,同样地,我们直接用右子树代替根节点;同时存在左右子树是比较复杂的情况,这是我们重点关注的情况。

这里我们优先采用右子树替换根节点的原则(当然左子树也可以)。 当我们找到需要删除的节点后,必须以右子树的最小节点(也就是右子树最左的节点)来代替被删除的节点

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def deleteNode(self, root, key):

"""

:type root: TreeNode

:type key: int

:rtype: TreeNode

"""

if not root:

return None

if root.val < key:

root.right = self.deleteNode(root.right, key)

elif root.val > key:

root.left = self.deleteNode(root.left, key)

else:

if not root.left or not root.right:

root = root.left if root.left else root.right

else:

cur = root.right

while cur.left:

cur = cur.left

root.val = cur.val

root.right = self.deleteNode(root.right, cur.val)

return root

Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure.

Example 1:

Input: [1,3,null,null,2]

1

/

3

\

2

Output: [3,1,null,null,2]

3

/

1

\

2

Example 2:

Input: [3,1,4,null,null,2]

3

/ \

1   4

/

2

Output: [2,1,4,null,null,3]

2

/ \

1   4

/

3

Follow up:

A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

同样使用中序遍历即可,所以还是需要定义pre节点表示前驱节点。 有两个节点颠倒了,只需要找到两个节点的位置。用n1存储第一个错位的元素,n2存储第二个,然后交换就可以了。

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def recoverTree(self, root):

"""

:type root: TreeNode

:rtype: None Do not return anything, modify root in-place instead.

"""

self.n1, self.n2, self.pre = None, None, None

self.inorder(root)

self.n1.val, self.n2.val = self.n2.val, self.n1.val

def inorder(self, root):

if root ==None:

return

self.inorder(root.left)

if self.pre!=None and self.pre.val > root.val:

if self.n1 == None:

self.n1=self.pre

self.n2=root

self.pre=root

self.inorder(root.right)

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

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

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

示例 1:

输入: root = [3,1,4,null,2], k = 1

3

/ \

1   4

\

2

输出: 1 示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3

5

/ \

3   6

/ \

2   4

/

1

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

解法 二叉搜索树BST,左子树不大于父节点,右子树不小于父节点,要找到第k小的数字,也就是把树整理成从小到大的顺序,也就是中序遍历。

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def kthSmallest(self, root, k):

"""

:type root: TreeNode

:type k: int

:rtype: int

"""

res = []

self.inorder(root, res, k)

return res[k-1]

def inorder(self, root, res, k):

if root:

self.inorder(root.left, res, k)

if len(res) >= k:

return res

res.append(root.val)

self.inorder(root.right, res, k)

Kth Largest Element in a Stream

设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。

你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。

示例:

int k = 3; int[] arr = [4,5,8,2]; KthLargest kthLargest = new KthLargest(3, arr); kthLargest.add(3); // returns 4 kthLargest.add(5); // returns 5 kthLargest.add(10); // returns 5 kthLargest.add(9); // returns 8 kthLargest.add(4); // returns 8 说明: 你可以假设 nums 的长度≥ k-1 且k ≥ 1。

解法 两种解法:

最小堆:比较简单,维护一个size为K的小顶堆,则堆顶元素即为第K大的元素。BST:给每个Node维护一个cnt,表示以它为根的树共多少节点。那么每个节点的所有右子树如果有m个节点,则该节点就是第m+1大的数。

最小堆:

from heapq import *

class KthLargest(object):

def __init__(self, k, nums):

"""

:type k: int

:type nums: List[int]

"""

self.heap = nums

self.k = k

heapify(self.heap)

while len(self.heap) > k:

heappop(self.heap)

def add(self, val):

"""

:type val: int

:rtype: int

"""

if len(self.heap) < self.k:

heappush(self.heap, val)

elif val > self.heap[0]:

heapreplace(self.heap, val)

return self.heap[0]

BST:

class Node(object):

def __init__(self, val):

self.val = val

self.cnt = 1

self.left = None

self.right = None

class KthLargest(object):

def __init__(self, k, nums):

"""

:type k: int

:type nums: List[int]

"""

self.root = None

self.k = k

for x in nums:

self.insert(x)

def add(self, val):

"""

:type val: int

:rtype: int

"""

self.insert(val)

return self.get_k(self.root, self.k)

def insert(self, x):

if not self.root:

self.root = Node(x)

return

cur = self.root

while cur:

cur.cnt += 1

if x < cur.val:

if not cur.left:

cur.left = Node(x)

return

else:

cur = cur.left

else:

if not cur.right:

cur.right = Node(x)

return

else:

cur = cur.right

def get_k(self, cur, k):

if not cur.right and k == 1:

return cur.val

if not cur.right:

return self.get_k(cur.left, k - 1)

if cur.right.cnt == k - 1:

return cur.val

if cur.right.cnt >= k:

return self.get_k(cur.right, k)

else:

return self.get_k(cur.left, k - cur.right.cnt - 1)

# Your KthLargest object will be instantiated and called as such:

# obj = KthLargest(k, nums)

# param_1 = obj.add(val)

二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]  示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点 2 和节点 8 的最近公共祖先是 6。 示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。 p、q 为不同节点且均存在于给定的二叉搜索树中。

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def lowestCommonAncestor(self, root, p, q):

"""

:type root: TreeNode

:type p: TreeNode

:type q: TreeNode

:rtype: TreeNode

"""

if root.val == p.val or root.val == q.val:

return root

if (p.val < root.val and q.val > root.val) or (q.val < root.val and p.val > root.val):

return root

if p.val < root.val and q.val < root.val:

return self.lowestCommonAncestor(root.left, p, q)

else:

return self.lowestCommonAncestor(root.right, p, q)

class Solution(object):

def lowestCommonAncestor(self, root, p, q):

"""

:type root: TreeNode

:type p: TreeNode

:type q: TreeNode

:rtype: TreeNode

"""

pointer = root

while pointer:

if q.val < pointer.val and p.val < pointer.val:

pointer = pointer.left

elif q.val > pointer.val and p.val > pointer.val:

pointer = pointer.right

else:

return pointer

将有序数组转换为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

0

/ \

-3   9

/   /

-10  5

解法 数组nums是一个升序数组,所以根节点的位置一定是m = len(nums)//2 nums中索引值小于m的树都位于根节点的左子树上,而另一半位于根节点的右子树上,然后进行递归调用。

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def sortedArrayToBST(self, nums):

"""

:type nums: List[int]

:rtype: TreeNode

"""

if not nums:

return None

mid = len(nums) // 2

root = TreeNode(nums[mid])

root.left = self.sortedArrayToBST(nums[:mid])

root.right = self.sortedArrayToBST(nums[mid + 1:])

return root

不同的二叉搜索树

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

示例:  解法 动态规划:假设n个节点存在二叉排序树的个数是G(n),因为根节点值不同,形成的二叉搜索树就不同,那么[1:n]范围内的n个数就有n个不同的选择 假设选取i作为根节点值,根据二叉搜索树的规则,[1:i−1]这i-1个数在其左子树上,[i+1:n]这n-i个数在其右子树上;对于左子树,又可以采用上述方法进行分解;对于右子树,同样可以采用上述方法进行分解。 让G(n)表示由连续的n个数形成的二叉搜索树的个数。所以当x为根节点时,其左子树节点个数为x - 1个,右子树节点为n - x,即f(i) = G(x - 1) * G(n - x),需要对G(0)和G(1)特殊处理,令其为1,即G(0)=G(1)=1

具体做法:让i表示连续i个数,dp[i]表示连续i个数能形成的BST的个数;j表示根节点的位置;最后返回dp[n]即可

class Solution:

def numTrees(self, n: 'int') -> 'int':

'''

'''

dp = [0] * (n+1)

dp[0],dp[1] = 1,1

#状态转移公式:dp(n) = dp(0)*dp(n-1)+dp(1)*dp(n-2)+...+dp(n-1)*dp(0)

for i in range(2,n+1):

for j in range(i):

dp[i] += dp[j] * dp[i-j-1]

return dp[n]

不同的二叉搜索树 II

给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。

示例:

输入: 3

输出:

[

[1,null,3,2],

[3,2,null,1],

[3,1,null,null,2],

[2,1,3],

[1,null,2,null,3]

]

解释:

以上的输出对应以下 5 种不同结构的二叉搜索树:

1         3     3      2      1

\       /     /      / \      \

3     2     1      1   3      2

/     /       \                 \

2     1         2                 3

解法 类似于上一题,从序列 1 …n 取出数字 i 并以它作为当前树的根节点。 那么就有 i - 1 个元素可以用来构造左子树,而另外的 n - i 个元素可以用于构造右子树。最后我们将会得到 G(i - 1) 棵不同的左子树,以及 G(n - i) 棵不同的右子树。 所以可以使用递归的方法,在序列 1 … i - 1 上重复前面的步骤来构造所有的左子树,之后对序列 i + 1 … n 也这样做以得到所有的右子树。 这么一来,我们就得到了根节点 i 和两个可能的左右子树列表。 最后一步是遍历两个列表,将左右子树和根节点链接起来。

注意:边界值的处理;属于排列组合的算法

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

def generateTrees(self, n):

"""

:type n: int

:rtype: List[TreeNode]

"""

def generate_trees(start, end):

if start > end:

return [None,]

all_trees = []

for i in range(start, end + 1):  # pick up a root

# all possible left subtrees if i is choosen to be a root

left_trees = generate_trees(start, i - 1)

# all possible right subtrees if i is choosen to be a root

right_trees = generate_trees(i + 1, end)

# connect left and right subtrees to the root i

for l in left_trees:

for r in right_trees:

current_tree = TreeNode(i)

current_tree.left = l

current_tree.right = r

all_trees.append(current_tree)

return all_trees

return generate_trees(1, n) if n else []

二叉搜索树的后序遍历序列

题目描述:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

解法 后序遍历中,最后一个数字是根结点的值,数组的前面数字部分可分为两部分,一部分是左子树,一部分是右子树。我们根据二叉搜索树的性质可知,左子树的值要比根节点小,而右子树所有值要比根节点大。以此递归来判断所有子树。

# -*- coding:utf-8 -*-

class Solution:

def VerifySquenceOfBST(self, sequence):

# write code here

if not sequence:

return False

else:

return self.verify(sequence)

def verify(self, sequence):

if not sequence:

return True

# 根节点就是最后一个树,获取一下这个值,然后从数组中弹出去

root = sequence.pop()

# 找一下左右子树

index = self.findIndex(sequence, root)

# 细分到没有子结点作为终止条件

if not sequence[index:]:

return True

# 如果右边数组最小值都大于root,则说明没有问题。进一步细分

elif min(sequence[index:]) > root:

left = sequence[:index]

right = sequence[index:]

return self.verify(left) and self.verify(right)

return False

# 定义一个函数,来找到左右子树的分界线

# 左子树的值比根节点小,右子树的值比根节点大,以此为左右子树的界限

def findIndex(self, sequence, root):

for i, seq in enumerate(sequence):

if sequence[i]>root:

return i

return len(sequence)

二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

解法 参考:https://www.nowcoder.com/questionTerminal/947f6eb80d944a84850b0538bf0ec3a5?answerType=1&f=discussion

辅助数组:最容易想到的,是用一个数组来存储中序遍历的节点,然后再从头到尾,建立节点前后的连接关系。线索化二叉树:因为二叉排序树中序遍历的结果是排好序的,很容易联想到用线索化二叉树的方法去做,用一个全局变量去保存前一个节点,然后再去创建节点之间的关系。只要pre不空,就创建关系,创建后就是链表了。但是要注意,返回的双向链表是降序排列的,那我们有两种解决方法,第一种是再遍历一遍得到的结果,将节点的最后一个结果返回。第二种是设置一个变量来记录。优化:我们受到惯性思维的约束,每次都是想着中序遍历先遍历左子树,再遍历根节点,再遍历右子树。那既然第二种方法得到的二叉树是降序的,那我先遍历右子树,再遍历根节点,再遍历左子树不就可以了么

方法二:

class Solution:

def __init__(self):

self.pre = None

self.root = None

def Convert(self, pRootOfTree):

# write code here

if not pRootOfTree:

return None

self.Convert(pRootOfTree.left)

if self.root == None:

self.root = pRootOfTree

if self.pre:

pRootOfTree.left = self.pre

self.pre.right = pRootOfTree

self.pre = pRootOfTree

self.Convert(pRootOfTree.right)

return self.pre

方法三:

# -*- coding:utf-8 -*-

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

def __init__(self):

self.pre = None

def Convert(self, pRootOfTree):

# write code here

if pRootOfTree == None:

return None

self.Convert(pRootOfTree.right)

if self.pre != None:

pRootOfTree.right = self.pre

self.pre.left = pRootOfTree

self.pre = pRootOfTree

self.Convert(pRootOfTree.left)

return self.pre

二叉搜索树转换成循环双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。  我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。  特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

解法 同上,两类方法

进行中序遍历的时候,将所有 node 存放在一个数组中,依次遍历数组,改造 right 指针指向下一个元素,left 指针指向前一个元素,单独处理首尾的连接为了能够完成双向的指向,我们必须同时有两个 node。让第一个 node 的 right 指向第二个 node,同时让第二个 node 的 left 指向第一个node。第一个 node 使用一个全局遍历 self.pre,第二个 node 使用当前点 root。

方法一:

class Solution:

def __init__(self):

self.list = []

def inOrderTraverse(self, root):

if not root:

return None

self.inOrderTraverse(root.left)

self.list.append(root)

self.inOrderTraverse(root.right)

def treeToDoublyList(self, root: 'Node') -> 'Node':

if not root:

return None

self.inOrderTraverse(root)

l = len(self.list)

for i in range(l-1):

self.list[i].right = self.list[i+1]

self.list[l-1-i].left = self.list[l-2-i]

self.list[l-1].right = self.list[0]

self.list[0].left = self.list[l-1]

return self.list[0]

方法二:

class Solution:

def __init__(self):

self.pre = None

self.head = None

def inOrderTraverse(self, root):

if not root:

return None

# left DFS

self.inOrderTraverse(root.left)

if self.pre == None:

self.pre = root

self.head = root # This is the left most node -> head

else:

self.pre.right = root   # Pre.right -> current node

root.left = self.pre    # current node.left -> pre

self.pre = root         # change pre to current node

# right DFS

self.inOrderTraverse(root.right)

def treeToDoublyList(self, root: 'Node') -> 'Node':

if not root:

return None

# Inorder traverse

self.inOrderTraverse(root)

# Link head and tail

self.head.left = self.pre

self.pre.right = self.head

return self.head

二叉搜索树序列

从左向右遍历一个数组,通过不断将其中的元素插入树中可以逐步地生成一棵二叉搜索树。给定一个由不同节点组成的二叉搜索树,输出所有可能生成此树的数组。

示例: 给定如下二叉树

2

/ \

1   3

返回:

[ [2,1,3], [2,3,1] ]

解法  会出现这样的一个结果 [[3,0,1,2,4],[3,0,1,4,2],[3,0,4,1,2],[3,4,0,1,2]] 我们发现其实并不是每个节点的后面都是他的一个子节点,0后面也可能出现4,1后面也可能出现4,…,说明左右节点也可以交替出现!

具体做法:

3这个节点的左右节点[0, 4],那么下一个节点就要在[0, 4]中选择如果下个节点是0,其左右节点[1], 那么0后面的节点可能有哪些呢?–> [4]+[1]如果下个节点是4,没有子节点[ ], 那么1后面的节点可能有哪些呢?–> [0]+[]

所以还是dfs递归全排列的方法:除了res和tmp外,还需要多加一个queue的队列,用来存储左右子节点。

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

def BSTSequences(self, root):

"""

:type root: TreeNode

:rtype: List[List[int]]

"""

if not root:

return [[]]

res, queue = [], []

tmp = [root.val]

self.dfs(root, queue, tmp, res)

return res

def dfs(self, root, queue, tmp, res):

if root.left:

queue.append(root.left)

if root.right:

queue.append(root.right)

if not queue:

res.append(tmp)

return

for i, node in enumerate(queue):

self.dfs(node, queue[:i] + queue[i + 1:], tmp + [node.val], res)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值