BST 中兩個節點被錯誤交換,恢復樹結構不變,僅交換節點值。要求 O(1) 空間(Morris 遍歷)或 O(n) 空間均可。
BST 中序遍歷應為嚴格遞增。兩個節點交換會導致序列中出現兩處逆序(相鄰交換則一處)。
list[i] > list[i+1] 和最後一個 list[j] < list[j-1]public void recoverTree(TreeNode root) {
List<TreeNode> list = new ArrayList<>();
inorder(root, list);
int l = -1, r = -1;
for (int i = 0; i < list.size()-1; ++i)
if (list.get(i).val > list.get(i+1).val) { l = i; break; }
for (int j = list.size()-1; j > 0; --j)
if (list.get(j).val < list.get(j-1).val) { r = j; break; }
int tmp = list.get(l).val;
list.get(l).val = list.get(r).val;
list.get(r).val = tmp;
}
void inorder(TreeNode n, List<TreeNode> list) {
if (n == null) return;
inorder(n.left, list);
list.add(n);
inorder(n.right, list);
}
利用線索二叉樹思想,無需棧/遞歸,修改右空指針指向後繼,遍歷後恢復。代碼較長,此處略。