在preorder递归和迭代版本做略微修改就行了。迭代版本我们第二次访问节点的时候调整左右指针,注意只要备份右指针,然后去到原右子结点。左子节点不需要备份因为之后我们不会去左子树了。递归版本是类似的,只需备份右子结点,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class flattenToDoublyLinkedListAsInorder { | |
private TreeNode head = null; | |
private TreeNode tail = null; | |
public TreeNode flattenRecursively(TreeNode root) { | |
InOrder(root); | |
return head; | |
} | |
private void InOrder(TreeNode node) { | |
if (node == null) | |
return; | |
InOrder(node.left); | |
TreeNode rightCopy = node.right; | |
if(head == null) { | |
head = node; | |
head.left = null; | |
tail = node; | |
tail.right = null; | |
} else { | |
tail.right = node; | |
node.left = tail; | |
tail = tail.right; | |
tail.right = null; | |
} | |
InOrder(rightCopy); | |
} | |
public TreeNode flattenIteratively(TreeNode root) { | |
TreeNode curr = root, head = null, tail = null; | |
Stack<TreeNode> path = new Stack<TreeNode>(); | |
while (!path.isEmpty() || curr != null) { | |
while (curr != null) { | |
path.push(curr); | |
curr = curr.left; | |
} | |
curr = path.pop(); | |
TreeNode rightCopy = curr.right; | |
if (head == null) { | |
head = curr; | |
tail = curr; | |
head.left = null; | |
head.right = null; | |
} else { | |
tail.right = curr; | |
curr.left = tail; | |
tail = tail.right; | |
tail.right = null; | |
} | |
curr = rightCopy; | |
} | |
return head; | |
} | |
//for test use, serialize doubly linked list | |
public String serialize(TreeNode head) { | |
String res = ""; | |
while(head != null) { | |
res += "<-"; | |
res += head.val; | |
res += "->"; | |
head = head.right; | |
} | |
return res; | |
} | |
public static void main(String[] args) { | |
test1(); | |
test2(); | |
test3(); | |
test4(); | |
test5(); | |
test6(); | |
} | |
//test cases | |
private static void test1() { | |
TreeNode root = new TreeNode(1); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenRecursively(root)).equals("<-1->")) | |
System.out.println("test case 1 passed!"); | |
else | |
System.out.println("test case 1 failed!"); | |
} | |
private static void test2() { | |
TreeNode root = new TreeNode(1); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenIteratively(root)).equals("<-1->")) | |
System.out.println("test case 2 passed!"); | |
else | |
System.out.println("test case 2 failed!"); | |
} | |
private static void test3() { | |
TreeNode root = new TreeNode(1); | |
root.left = new TreeNode(2); | |
root.right = new TreeNode(3); | |
root.left.right = new TreeNode(4); | |
root.right.right = new TreeNode(5); | |
root.right.right.left = new TreeNode(6); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenRecursively(root)).equals("<-2-><-4-><-1-><-3-><-6-><-5->")) | |
System.out.println("test case 3 passed!"); | |
else | |
System.out.println("test case 3 failed!"); | |
} | |
private static void test4() { | |
TreeNode root = new TreeNode(1); | |
root.left = new TreeNode(2); | |
root.right = new TreeNode(3); | |
root.left.right = new TreeNode(4); | |
root.right.right = new TreeNode(5); | |
root.right.right.left = new TreeNode(6); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenIteratively(root)).equals("<-2-><-4-><-1-><-3-><-6-><-5->")) | |
System.out.println("test case 4 passed!"); | |
else | |
System.out.println("test case 4 failed!"); | |
} | |
private static void test5() { | |
TreeNode root = new TreeNode(3); | |
root.left = new TreeNode(7); | |
root.right = new TreeNode(6); | |
root.left.left = new TreeNode(4); | |
root.left.right = new TreeNode(2); | |
root.right.right = new TreeNode(5); | |
root.left.left.left = new TreeNode(12); | |
root.left.left.left.right = new TreeNode(0); | |
root.left.right.right = new TreeNode(10); | |
root.right.right.left = new TreeNode(8); | |
root.right.right.right = new TreeNode(9); | |
root.right.right.left.left = new TreeNode(17); | |
root.right.right.right.right= new TreeNode(20); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenRecursively(root)).equals("<-12-><-0-><-4-><-7-><-2-><-10-><-3-><-6-><-17-><-8-><-5-><-9-><-20->")) | |
System.out.println("test case 5 passed!"); | |
else | |
System.out.println("test case 5 failed!"); | |
} | |
private static void test6() { | |
TreeNode root = new TreeNode(3); | |
root.left = new TreeNode(7); | |
root.right = new TreeNode(6); | |
root.left.left = new TreeNode(4); | |
root.left.right = new TreeNode(2); | |
root.right.right = new TreeNode(5); | |
root.left.left.left = new TreeNode(12); | |
root.left.left.left.right = new TreeNode(0); | |
root.left.right.right = new TreeNode(10); | |
root.right.right.left = new TreeNode(8); | |
root.right.right.right = new TreeNode(9); | |
root.right.right.left.left = new TreeNode(17); | |
root.right.right.right.right= new TreeNode(20); | |
flattenToDoublyLinkedListAsInorder f = new flattenToDoublyLinkedListAsInorder(); | |
if (f.serialize(f.flattenIteratively(root)).equals("<-12-><-0-><-4-><-7-><-2-><-10-><-3-><-6-><-17-><-8-><-5-><-9-><-20->")) | |
System.out.println("test case 6 passed!"); | |
else | |
System.out.println("test case 6 failed!"); | |
} | |
} |
如果要求是constant space的话,用类似morris遍历的方法,第一次访问的时候把前驱结点的右指针链接到当前节点上,第二次访问的时候把节点链接到list上去,记得备份右子结点。然后去到原右子结点。
No comments:
Post a Comment