将数组转换为树结构
在leetcode刷题经常会遇到有关树的题目,题目的测试用例都是以满二叉树数组的形式给出,我们不方便调试,需要转换成真正的树形结构才方便调试,以下给出转换的代码
// 二叉树构造函数
function TreeNode(val) {
this.val = val || undefined;
this.left = null;
this.right = null;
}
// 由于题目给出的都是满二叉树数组,所以我们不去考虑其它二叉树的形式
const arrayToTree = (arr) => {
// 判断需要返回null的情况
if(arr === null || arr.length === 0 || arr[0] === null) {
return null;
}
let len = arr.length;
// 将数组里的所有值转换成树的结点再放进新的数组里
const nodeArr = arr.map(val => val && new TreeNode(val));
// [3,9,20,null,null,15,7],对于所有的满二叉树,叶子节点都有Math.ceil(len/2)+1个,根节点+子节点有Math(len/2)-1个
// 也就是说叶子节点是总结点数的一半多一个,根节点加子节点是总节点数的一半减一个
// 那么数组的前一半减1个节点全部有左右节点,数组的后一半加1个节点全部是叶子节点
// 并且有一个规律,数组的下标×2+1,数组的下标×2+2的两个位置恰好就是字节点的左右节点的位置
// 至此,我们就可以遍历数组的前一半减一个元素,让下标×2+1,下标×2+2的位置成为它的左右节点即可
// 注意:需要判断一下子节点是否为null,不为null才需要放到子节点之下
for(let i=0; i<Math.ceil(len/2)-1; i++) {
if(nodeArr[i*2+1] !== null) {
nodeArr[i].left = nodeArr[i*2+1];
}
if(nodeArr[i*2+2] !== null) {
nodeArr[i].right = nodeArr[i*2+2];
}
}
// 最后返回节点数组的第一个元素,即为根节点
return nodeArr[0];
}
数组转换为链表
有了树的转换,链表的转换就显得微不足道了,代码如下:
function Node(val) {
this.val = val || undefined;
this.next = null;
}
const arrayToLinkList = (arr) => {
// 返回null的情况
if(arr === null || arr.length === 0 || arr[0] === null) {
return null;
}
// 定义一个根节点与一个可移动的指针节点
const root = new Node(arr[0]);
let tmpRoot = root;
// 指针节点不断向右移动给当前节点的next赋值
for(let i=1,len=arr.length; i<len; i++) {
tmpRoot.next = new Node(arr[i]);
tmpRoot = tmpRoot.next;
}
// 最终返回根节点
return root;
}