题目
解题:深度优先搜索
解题一:栈
// javascript
var flatten = function(head) {
// prevNode 记录链表的最后一个非 null 节点
let curNode = head, prevNode = null;
// 模拟递归的栈,用显式的栈来存放断点
const stack = [];
while (curNode !== null || stack.length > 0) {
// 情况:如题目中的 12 处理完后,curNode指向null,prevNode指向节点12
// 要返回最近一个断点节点9(之前已经存入stack栈中)
if (curNode === null) {
// 将之前的断点出栈
curNode = stack.pop();
// 将当前链表最后一个非 null 节点与断点相连接
prevNode.next = curNode;
curNode.prev = prevNode;
}
// 如果有子节点,那么首先处理子节点
if (curNode.child !== null) {
// 如果 next 不为空,就将它存入栈中
if (curNode.next !== null) {
stack.push(curNode.next);
}
// 将 curNode 与 curNode.child 相连
// **很重要**:并且设置 curNode.child = null;
curNode.next = curNode.child;
curNode.child.prev = curNode;
curNode.child = null;
}
prevNode = curNode;
curNode = curNode.next;
}
return head;
};
解题二:递归
递归的写法注意点反而要比上面的写法多,因为有 child 和无 child 的情况下,curNode 指向的值不一样,所以 prevNode 更新要分情况,curNode.next 的更新可以在循环一开始记录 next 并在之后获取。
// javascript
var flatten = function(head) {
const dfs = (head) => {
// prevNode 记录链表的最后一个非 null 节点
let curNode = head, prevNode = null;
while (curNode !== null) {
// 要记录下一个节点!!!
const nextNode = curNode.next;
// 如果有子节点,那么首先处理子节点
if (curNode.child !== null) {
const childLast = dfs(curNode.child);
// 如果 curNode.next 不为空,就将 childLast 与 curNode.next 相连
if (curNode.next !== null) {
childLast.next = curNode.next;
curNode.next.prev = childLast;
}
// 将 curNode 与 curNode.child 相连
// **很重要**:并且设置 curNode.child = null;
curNode.next = curNode.child;
curNode.child.prev = curNode;
curNode.child = null;
prevNode = childLast;
} else {
prevNode = curNode;
}
curNode = nextNode;
}
return prevNode;
};
dfs(head);
return head;
};