关于#递归#的问题,如何解决?

关于力扣题目:判断一棵树是否为另一颗子树
原思路:先找到一个和subroot节点相同值的节点,然后递归找,但是后面发现这样做会有个别节点值重复的数测试不会通过,但是现在又不知道怎么改了,然后卡在这了

img

img


```java
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
       TreeNode target= preoreder(root,subRoot.val);
       return isSub(target,subRoot);
    }
    //先找一个返回与目标值相同的节点:
    public static TreeNode preoreder(TreeNode root, int val) {
        if (root == null || root.val == val)
            return root;
        TreeNode foundNode = preoreder(root.left, val);
        if (foundNode == null)
            foundNode = preoreder(root.right, val);
        return foundNode;
    }
    //从节点值与子树相等的节点开始进行递归判断是否相等:
    public static boolean isSub(TreeNode root, TreeNode subRoot){
        if(root==null&&subRoot==null)
            return true;
        if(root==null||subRoot==null|| root.val!=subRoot.val)
            return false;
        return isSub(root.left,subRoot.left)&&isSub(root.right,subRoot.right);
    }


```


public boolean isSubtree(TreeNode root, TreeNode subRoot) {
    List<TreeNode> targetNodes = findNodesWithSameValue(root, subRoot.val);
    for (TreeNode target : targetNodes) {
        if (isSub(target, subRoot)) {
            return true;
        }
    }
    return false;
}

// 找到所有和目标值相同的节点
public List<TreeNode> findNodesWithSameValue(TreeNode root, int val) {
    List<TreeNode> result = new ArrayList<>();
    if (root == null) {
        return result;
    }

    if (root.val == val) {
        result.add(root);
    }

    result.addAll(findNodesWithSameValue(root.left, val));
    result.addAll(findNodesWithSameValue(root.right, val));
    return result;
}

// 从节点值与子树相等的节点开始进行递归判断是否相等
public boolean isSub(TreeNode root, TreeNode subRoot) {
    if (root == null && subRoot == null) {
        return true;
    }
    if (root == null || subRoot == null || root.val != subRoot.val) {
        return false;
    }
    return isSub(root.left, subRoot.left) && isSub(root.right, subRoot.right);
}

public boolean isSubtree(TreeNode root, TreeNode subRoot) {
    TreeNode target = preOrder(root, subRoot.val);
    return isSub(target, subRoot);
}

public TreeNode preOrder(TreeNode root, int val) {
    if (root == null || root.val == val) {
        return root;
    }
    TreeNode foundNode = preOrder(root.left, val);
    if (foundNode == null) {
        foundNode = preOrder(root.right, val);
    }
    return foundNode;
}

public boolean isSub(TreeNode root, TreeNode subRoot) {
    if (root == null && subRoot == null) {
        return true;
    }
    if (root == null || subRoot == null) {
        return false;
    }
    if (root.val != subRoot.val) {
        return false;
    }
    return isSub(root.left, subRoot.left) && isSub(root.right, subRoot.right);
}

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答由chatgpt基于相关博客总结生成:

    解决方案

    在你的代码实现中,问题出现在preorder方法中。你目前只是简单地通过递归在左子树和右子树中查找与目标值相同的节点,但这种方式会导致找到的节点可能不是预期的子树的根节点。因此,你需要对preorder方法进行修改,使其能够找到与subRoot节点结构相同的节点。

    下面是优化后的代码:

    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        // 使用递归判断两棵树是否相等
        if (root == null && subRoot == null)
            return true;
        if (root == null || subRoot == null)
            return false;
        if (isSameTree(root, subRoot))
            return true;
        // 递归在左子树和右子树中查找
        return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
    }
    
    // 递归判断两棵树是否相等
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null)
            return true;
        if (p == null || q == null || p.val != q.val)
            return false;
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
    

    这样,通过递归判断两棵树是否相等的方法,我们可以直接在主函数中判断当前树和子树是否相等,如果相等则返回true,否则递归在左右子树中继续查找。

    希望这个解决方案能够帮到你!如有更多问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^