LeetCode 654._最大二叉树
public TreeNode ConstructMaximumBinaryTree(int[] nums)
{
return BuildMax(nums,0,nums.Length-1);
}
TreeNode BuildMax(int[] nums,int left,int right)
{
if (left > right) return null;
// 找到数组中的最大值和对应的索引
int max = int.MinValue;
int index = 0;
for (int i = left; i <= right; i++)
{
if (max < nums[i])
{
max = nums[i];
index = i;
}
}
// 先构造出根节点
TreeNode root = new TreeNode(max);
// 递归调用构造左右子树
root.left = BuildMax(nums, left, index - 1);
root.right = BuildMax(nums, index + 1, right);
return root;
}
LeetCode 105._从前序与中序遍历序列构造二叉树
// 存储 inorder 中值到索引的映射
Dictionary<int, int> inorMap = new Dictionary<int, int>();
public TreeNode BuildTree(int[] preorder, int[] inorder)
{
for (int i = 0; i < inorder.Length; i++)
inorMap.Add(inorder[i], i);
return Build(preorder, 0, preorder.Length - 1,
inorder, 0, inorder.Length - 1);
}
TreeNode Build(int[] preorder,int preLeft,int preRight,
int[] inorder,int inoLeft,int inoRight)
{
if (preLeft > preRight)
return null;
// root 节点对应的值就是前序遍历数组的第一个元素
int rootVal = preorder[preLeft];
int index = inorMap[rootVal];
// 左子树节点个数
int leftSize = index - inoLeft;
// 先构造出当前根节点
TreeNode root = new TreeNode(rootVal);
// 递归构造左右子树
root.left = Build(preorder, preLeft + 1, leftSize + preLeft,
inorder, inoLeft, index - 1);
root.right = Build(preorder, leftSize + preLeft + 1, preRight,
inorder, index + 1, inoRight);
return root;
}
LeetCode 106._从中序与后序遍历序列构造二叉树
Dictionary<int, int> inoMap = new Dictionary<int, int>();
public TreeNode BuildTree(int[] inorder, int[] postorder)
{
for (int i = 0; i < inorder.Length; i++)
{
inoMap.Add(inorder[i], i);
}
return Build(inorder, 0, inorder.Length - 1,
postorder, 0, postorder.Length - 1);
}
TreeNode Build(int[] inorder, int inoLeft,int inoRight,
int[] postorder,int posLeft,int posRight)
{
if (posLeft > posRight) return null;
int rootVal = postorder[posRight];
int index = inoMap[rootVal];
int leftSize = index - inoLeft;
TreeNode root = new TreeNode(rootVal);
// 递归构造左右子树
root.left = Build(inorder, inoLeft, index - 1,
postorder, posLeft, posLeft + leftSize - 1);
root.right = Build(inorder, index + 1, inoRight,
postorder, posLeft + leftSize, posRight - 1);
return root;
}
LeetCode 889._根据前序和后序遍历构造二叉树
Dictionary<int, int> postMap = new Dictionary<int, int>();
public TreeNode ConstructFromPrePost(int[] preorder, int[] postorder)
{
for (int i = 0; i < postorder.Length; i++)
{
postMap.Add(postorder[i], i);
}
return Build(preorder, 0, preorder.Length - 1,
postorder, 0, postorder.Length - 1);
}
TreeNode Build(int[] preorder,int preLeft,int preRight,
int[] postorder,int posLeft,int posRight)
{
if (preLeft > preRight) return null;
if(preLeft == preRight) return new TreeNode(preorder[preLeft]);
// root 节点对应的值就是前序遍历数组的第一个元素
int rootVal = preorder[preLeft];
// root.left 的值是前序遍历第二个元素
// 通过前序和后序遍历构造二叉树的关键在于通过左子树的根节点
// 确定 preorder 和 postorder 中左右子树的元素区间
int leftVal = preorder[preLeft + 1];
// leftVal 在后序遍历数组中的索引
int index = postMap[leftVal];
// 左子树的元素个数
int leftSize = index - posLeft + 1;
// 先构造出当前根节点
TreeNode root = new TreeNode(rootVal);
// 递归构造左右子树
// 根据左子树的根节点索引和元素个数推导左右子树的索引边界
root.left = Build(preorder, preLeft + 1, preLeft + leftSize,
postorder, posLeft, index);
root.right = Build(preorder, preLeft + leftSize + 1, preRight,
postorder, index + 1, posRight - 1);
return root;
}