前言
对于递归来将,可以利用其回溯来做事,但是一定要懂递归的核心在于将大问题分解成多个独立相同的小问题,递归代码非常简洁,但包容性很低。
除此之外,还可以用后出先进的栈来模拟回溯。
一、案例
二、题解
1、回溯
public Node flatten(Node head) {
//回溯解决问题,能用回溯,就可以用栈替代解决试试。
recursion(head);
return head;
}
private Node recursion(Node head) {
if (head == null) return null;
Node child = recursion(head.child);
Node next = recursion(head.next);
if (child == null && next == null) return head;
if (child != null && next != null) {
Node n = head.next;
head.next = head.child;
head.child = null;
head.next.prev = head;
child.next = n;
n.prev = child;
return next;
}
if (child == null && next != null) return next;
head.next = head.child;
head.child.prev = head;
head.child = null;
return child;
}
2、栈
//方法二:用栈模拟链表需要的回溯操作
public Node flatten2(Node head) {
if (head == null) return null;
//回溯解决问题,能用回溯,就可以用栈替代解决试试。
Stack<Node> cache = new Stack<>();
recursion(head, cache);
Node pre = cache.pop();
while (!cache.isEmpty()) {
Node node = cache.pop();
if (node.next != pre) {
node.next = pre;
pre.prev = node;
}
node.child = null;
pre = node;
}
head.child = null;
return head;
}
private void recursion(Node head, Stack<Node> cache) {
if (head == null) return;
cache.push(head);
recursion(head.child, cache);
recursion(head.next, cache);
}
// Definition for a Node.
class Node {
public int val;
public Node prev;
public Node next;
public Node child;
}
总结
1)递归代码简洁,但是包容性低,一定要将大问题分解成多个独立相同的小问题。
2)栈与回溯思路类似,要保持栈对回溯的敏感性,以及栈和回溯对单向链表的敏感性,才能转换问题,举一反三。
参考文献
[1] LeetCode 原题