博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从数组形式创建一棵树(用于leetcode测试)
阅读量:4039 次
发布时间:2019-05-24

本文共 3637 字,大约阅读时间需要 12 分钟。

这段时间时不时地会在leetcode上做些题,最近做到的大部分是与树相关的题。由于是在本地的IDE上码代码,如果每次测试都要到leetcode上来测的话,不仅要选中复制粘贴一遍,而且每次测试还要读一会条,一次两次还好,次数多了还是比较烦。而如果在本地的类内的main()函数里测试的话,每次构建一个树也比较麻烦,而且仅仅更换数值还好,若要更换树的结构,那工程量就有点大了。

所以在这里准备写一个创建树的函数来解决这个问题,后面做起题来效率也能高一些。

话不多说,下面先直接放上所用的代码:

本例中所构建的树的结构      5     / \    4   8   /   / \  11  13  4 /  \      \7    2      1
package learning_java;import LeetCode.TreeNode;import java.util.Deque;import java.util.LinkedList;public class ConstructTree {
public static TreeNode constructTree(Integer[] nums){
if (nums.length == 0) return new TreeNode(0); Deque
nodeQueue = new LinkedList<>(); // 创建一个根节点 TreeNode root = new TreeNode(nums[0]); nodeQueue.offer(root); TreeNode cur; // 记录当前行节点的数量(注意不一定是2的幂,而是上一行中非空节点的数量乘2) int lineNodeNum = 2; // 记录当前行中数字在数组中的开始位置 int startIndex = 1; // 记录数组中剩余的元素的数量 int restLength = nums.length - 1; while(restLength > 0) {
// 只有最后一行可以不满,其余行必须是满的// // 若输入的数组的数量是错误的,直接跳出程序// if (restLength < lineNodeNum) {
// System.out.println("Wrong Input!");// return new TreeNode(0);// } for (int i = startIndex; i < startIndex + lineNodeNum; i = i + 2) {
// 说明已经将nums中的数字用完,此时应停止遍历,并可以直接返回root if (i == nums.length) return root; cur = nodeQueue.poll(); if (nums[i] != null) {
cur.left = new TreeNode(nums[i]); nodeQueue.offer(cur.left); } // 同上,说明已经将nums中的数字用完,此时应停止遍历,并可以直接返回root if (i + 1 == nums.length) return root; if (nums[i + 1] != null) {
cur.right = new TreeNode(nums[i + 1]); nodeQueue.offer(cur.right); } } startIndex += lineNodeNum; restLength -= lineNodeNum; lineNodeNum = nodeQueue.size() * 2; } return root; } public static void main(String[] args) {
Integer[] nums = {
5,4,8,11,null,13,4,7,2,null,null,null,1}; TreeNode root = ConstructTree.constructTree(nums); System.out.println(root); }}

使用时,像上面main()方法中一样,只需要调用类内的静态方法constructTree(Integer[] nums),输入的参量为一个整型的数组,数组中的元素是按层次遍历的二叉树的值(若某节点在下一层中的某个儿子或两个儿子为空,则在下一层的这一个或两个位置填null),与Leetcode中树的表示方法相同,即可以直接把Leetcode上的测试用例按它的形式拖过来直接使用。

简单解释一下所用的方法,核心思想是在每一层,用一个队列nodeQueue来存储该层的所有节点,然后用父节点的数量的两倍来遍历输入的数组(从上一层结束的地方开始),并从队列中取出(位于上一层的)对应的父节点(此时已从队列中删去,因为用的方法为poll()而不是peek()),对于每一个值,创建相应的子节点链接到父节点,并加入到队列中,依次不断循环,直到遍历完整个数组。

这里一个踩过的坑是,其中因为一部分数值为null,而如果用int基本类型的数组的话,数组内是不能用null的,因此这里用了int的包装类Integer的数组来作为传入的参数的声明。

最后,让我们测试一下我们的代码,测试用的树与上面一样,测试中我们采用先序遍历来进行输出,查看结果是否正确:

/*用于测试的树,与上例中相同      5     / \    4   8   /   / \  11  13  4 /  \      \7    2      1 */package learning_java.sortTry;import LeetCode.TreeNode;import learning_java.ConstructTree;public class ConstructTreeTest {
public void preOrder(TreeNode root) {
if (root == null) return; System.out.print(root.val + " "); preOrder(root.left); preOrder(root.right); } public static void main(String[] args) {
Integer[] nums = {
5,4,8,11,null,13,4,7,2,null,null,null,1}; TreeNode root = ConstructTree.constructTree(nums); new ConstructTreeTest().preOrder(root); }}

测试结果:

5 4 11 7 2 8 13 4 1

可以看到,我们得到了一棵所需要的树。

更新

在实际使用中发现,leetcode中所给的case经常并不是标准的个数,最后一行往往是不满的,如

5     /     4

这样一棵树,给出的数组中仅有两个数字:[5, 4],即最后一行中的末尾的null会被舍弃,因此,在我们的程序中,应在遍历过程中加入停止条件(更严谨的方式是保存判定错误输入的条件,并仅在树的最后一行的遍历过程中进行停止判定)。

转载地址:http://eqsdi.baihongyu.com/

你可能感兴趣的文章
慢慢欣赏linux make uImage流程
查看>>
linux内核学习(7)脱胎换骨解压缩的内核
查看>>
以太网基础知识
查看>>
慢慢欣赏linux 内核模块引用
查看>>
kprobe学习
查看>>
慢慢欣赏linux phy驱动初始化2
查看>>
慢慢欣赏linux CPU占用率学习
查看>>
2020年终总结
查看>>
Homebrew指令集
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
React Native(二):属性、状态
查看>>
JSX使用总结
查看>>
React Native(四):布局(使用Flexbox)
查看>>
React Native(七):Android双击Back键退出应用
查看>>
Android自定义apk名称、版本号自增
查看>>
adb command not found
查看>>
Xcode 启动页面禁用和显示
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>
二叉树的非递归遍历
查看>>
【leetcode】Reorder List (python)
查看>>