树型中序迭代器
相信很多小伙伴在面试中都会遇到面试手撕题,然后当时可能会大脑有一些宕机,但在事后却宛若诸葛亮一般奇妙的相出了最优解哈哈哈。没错就是我,面试中只想出了暴力的想法,最优解只有一点点头绪。当面试过后再去想一下确实会文思泉涌。
算法题是这样的:有两棵树,判断他们中序遍历的结果是否一致。
那好家伙,0.1s想出最暴力的方法,直接给他一个中序遍历并存储结果,后面一个边遍历边校验即可。(但是复杂度有点高)
有没有更好的方法?有的兄弟,有的。🤓🤞
那不如我们来给他优雅的做一个中序迭代器,这样每次我们都可以边走边比较,那效率不嘎嘎快吗?当然我们还得考虑说树的节点树不同的问题,那这个好整,如果一个树还能遍历,另外一个树已经无法遍历了,那不就铁定不一样吗!
好的,如下就是我花费大量脑细胞做出来的一个中序迭代器(自己测了一下,确实没问题哈,如果有问题跟我说一声) 总共有两个版本 第二个版本更好
/**
* ELEGANT
* TODO 做一个树形遍历器(弥补面试的遗憾)
*/
class TreeNode {
public int value;
public TreeNode left;
public TreeNode right;
public TreeNode father;
// flag表示为是否遍历过
public Boolean flag;
public TreeNode(int value, TreeNode left, TreeNode right){
this.value = value;
this.left = left;
this.right = right;
flag = Boolean.FALSE;
}
public void setFather(TreeNode father){
this.father = father;
}
}
/**
* 树的遍历器
*/
class Iterator{
public TreeNode cur;
public Iterator(TreeNode cur){
// 落地先找最左边
this.cur = findLeft(cur);
}
/**
* 一股脑找最左边
* @param cur
* @return
*/
private TreeNode findLeft(TreeNode cur){
if (cur == null){
return null;
}
while (cur.left != null){
cur = cur.left;
}
return cur;
}
public boolean hasNext(){
return cur != null;
}
/**
* 遍历
* @return
*/
public TreeNode next(){
TreeNode resp = cur;
// 表示该节点已经访问
cur.flag = true;
// 看能不能往右边走
if (cur.right != null && !cur.right.flag){
cur = cur.right;
// 一直找左边
cur = findLeft(cur);
}else {
// 走到这的话只能往上走
cur = cur.father;
while (cur != null && cur.flag){
cur = cur.father;
}
}
return resp;
}
}
public class TreeIterator {
public static void main(String[] args) {
TreeNode root = buildTree();
Iterator iterator = new Iterator(root);
while (iterator.hasNext()){
TreeNode next = iterator.next();
System.out.println(next.value);
}
}
/**
* 构建树
* @return
*/
private static TreeNode buildTree(){
TreeNode r6 = new TreeNode(5, null, null);
TreeNode r5 = new TreeNode(4, null, null);
TreeNode r4 = new TreeNode(9, null, null);
TreeNode r3 = new TreeNode(6, r4, null);
TreeNode r2 = new TreeNode(8,r5,r6);
TreeNode r1 = new TreeNode(7, null,r3);
TreeNode root = new TreeNode(10,r1,r2);
r1.setFather(root);
r2.setFather(root);
r3.setFather(r1);
r5.setFather(r2);
r6.setFather(r2);
r4.setFather(r3);
root.setFather(null);
return root;
}
// TODO 判断两个树的中序遍历是否相同
// 时间复杂度 O(Min(t1.size,t2.size)) 且运气好的话 直接匹配到当前项不同就直接return
public static boolean isSame(TreeNode t1,TreeNode t2){
// 获取他们的迭代器
Iterator iterator1 = new Iterator(t1);
Iterator iterator2 = new Iterator(t2);
while (iterator1.hasNext() && iterator2.hasNext()){
TreeNode next1 = iterator1.next();
TreeNode next2 = iterator2.next();
if (next1.value != next2.value){
return false;
}
}
return iterator1.hasNext() == iterator2.hasNext();
}
}
🤔 又有一个更优雅的版本 减少了内存消耗
/**
* TODO 做一个树形遍历器(弥补面试的遗憾)
*/
class TreeNode {
public int value;
public TreeNode left;
public TreeNode right;
public TreeNode(int value, TreeNode left, TreeNode right){
this.value = value;
this.left = left;
this.right = right;
}
}
/**
* 树的遍历器
*/
class Iterator{
public Stack<TreeNode> stack = new Stack<>();
public Iterator(TreeNode cur){
// 落地先找最左边
findLeft(cur);
}
/**
* 一股脑找最左边
* @param cur
* @return
*/
private voidfindLeft(TreeNode cur){
if (cur == null){
return;
}
while (cur.left != null){
stack.add(cur);
cur = cur.left;
}
stack.add(cur);
}
public boolean hasNext(){
return !stack.isEmpty();
}
/**
* 遍历
* @return
*/
public TreeNode next(){
TreeNode resp = stack.pop();
// 看能不能往右边走
if (resp.right != null){
// 一直找左边
findLeft(resp.right);
}
return resp;
}
}
public class TreeIterator2 {
public static void main(String[] args) {
TreeNode root = buildTree();
Iterator iterator = new Iterator(root);
while (iterator.hasNext()){
TreeNode next = iterator.next();
System.out.println(next.value);
}
}
/**
* 构建树
* @return
*/
private static TreeNode buildTree(){
TreeNode r6 = new TreeNode(5, null, null);
TreeNode r5 = new TreeNode(4, null, null);
TreeNode r4 = new TreeNode(9, null, null);
TreeNode r3 = new TreeNode(6, r4, null);
TreeNode r2 = new TreeNode(8,r5,r6);
TreeNode r1 = new TreeNode(7, null,r3);
TreeNode root = new TreeNode(10,r1,r2);
return root;
}
// TODO 判断两个树的中序遍历是否相同
// 时间复杂度 O(Min(t1.size,t2.size)) 且运气好的话 直接匹配到当前项不同就直接return
public static boolean isSame(TreeNode t1,TreeNode t2){
// 获取他们的迭代器
Iterator iterator1 = new Iterator(t1);
Iterator iterator2 = new Iterator(t2);
while (iterator1.hasNext() && iterator2.hasNext()){
TreeNode next1 = iterator1.next();
TreeNode next2 = iterator2.next();
if (next1.value != next2.value){
return false;
}
}
return iterator1.hasNext() == iterator2.hasNext();
}
}

浙公网安备 33010602011771号