前端算法小白攻略41-leetcode(N叉树的前序遍历)

136 阅读2分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战

前言

二叉树的前序遍历我们已经练过了,那么今天N叉树的前序遍历理解起来就较为容易了,同样,递归法和迭代法我们都会使用。

题目描述

589. N 叉树的前序遍历

给定一个 n 叉树的根节点  root ,返回 其节点值的 前序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。

示例 1:

image.png

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

解题思路

同样,题目给我们n叉树的根节点,每组节点由null值分隔,节点的子节点放在children指针指向的内存中,我们来看下children里节点的格式,其实children就是一个节点数组

image.png
有了前道题二叉树的前序遍历的基础,我们来整理n叉树前序遍历的解题思路:

递归法思路:

N叉树与二叉树的区别在于,N叉树的子节点是在children数组里,我们在写递归转换函数的时候,push完根节点后不再是对左右节点进行转换,而是要遍历children数组,每遍历一次对当前遍历节点转换一次
注意:我们这里是递归调用,每次调用都会往结果数组里添加节点值,而不是以往的深度优先执行

迭代法思路:

和二叉树类似,我们同样需要两个数组来存我们的操作节点及存储结果,不同的有两点:

  1. 我们需要从节点栈的栈首开始操作节点,因为N叉树的最左边的节点是在children数组的第一项,我们需要从前往后取节点然后把节点的值放到结果数组中
  2. 处理子节点的时候,我们要把子节点的children合并到操作栈的栈首,这样下一次就是操作它的子节点了。

开始解题

递归法解题:
var preorder = function(root) {
   if(!root) return [];
   let resArr = [];
   transfer(root,resArr);
   return resArr;
};

var transfer = function(root, resArr) {
    if(!root) return null;
    resArr.push(root.val);
    if(root.children.length) { // 如果当前节点有子节点,我们就按顺序遍历操作children节点数组即可,即前序遍历
       for(node of root.children) { // 遍历子节点数组中子节点
           transfer(node,resArr);  // 依次进行转换,最左边的节点先发起递归先进行节点操作
       } 
    }
}
迭代法解题:
var preorder = function(root) {
   if(!root) return [];
   let stack = [root];  // 操作节点栈
   let resArr = [];

   while(stack.length) {
       const node = stack.shift();  // 每次取队首的节点
       resArr.push(node.val);

       if(node.children.length) {   // 判断当前子节点数组有没有值
           stack = node.children.concat(stack); // 把子节点合并到队首,当前节点遍历操作之后就是从对首取出并操作它的子节点
       }
   }
   return resArr;
};