我的Preorder遍历有什么问题?

时间:2014-07-26 09:31:37

标签: java recursion tree-traversal preorder

我正在尝试解决这个问题https://oj.leetcode.com/problems/binary-tree-preorder-traversal/,即使用递归洗脱进行前序遍历。

编辑:整个代码:

import java.util.ArrayList;
import java.util.List;

public class Solution {

    public class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
    }
     static List<Integer> res = new ArrayList<Integer>();
     public List<Integer> preorderTraversal(TreeNode root) {
            if(root == null){
                return new ArrayList<Integer>();
            }
            res.add(root.val);
            if(root.left != null){
                res.add(preorderTraversal(root.left));
            }
            if(root.right != null){
                res.add(preorderTraversal(root.right));
            }
            return res;
      }
}

由于以下原因,我的答案错误:

Input:  {1,2}
Output:     [1,1,2]
Expected:   [1,2]

有人可以告诉我如何解决这个问题吗?

编辑:我没有main()方法或单元测试。如果您打开我发布的链接,您会看到这是在线评审系统

7 个答案:

答案 0 :(得分:3)

问题是在每个递归循环中,您将整个数组再次添加到最终结果中。

例如,给定以下树:

  1
 /
2

您的第一次迭代将1添加到'res'变量中。问题在于它到达这一行:

res.add(preorderTraversal(root.left));

然后它以递归方式为左侧调用自己。 preorderTraversal将返回res数组,这将是[1,2]。因此,当[1,2]被添加到res(这是[1],记得吗?),那么你得到[1,1,2]。

以下代码应该有效:

public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<Integer>();

    if(root == null){
        return result;
    }

    result.add(root.val);
    if(root.left != null){
        result.addAll(preorderTraversal(root.left));
    }
    if(root.right != null){
        result.addAll(preorderTraversal(root.right));
    }

    return result;
}

答案 1 :(得分:1)

尝试此方法代码:

public List<Integer> preorderTraversal(TreeNode root) {
        if(root == null){
            return new ArrayList<Integer>();
        }
        res.add(root.val);
        if(root.left != null){
            res = preorderTraversal(root.left);
        }
        if(root.right != null){
            res = preorderTraversal(root.right);
        }
        return res;
   }
不过,你在递归中正在做res.add。你应该在其中res=

答案 2 :(得分:1)

对于左侧和右侧节点,只需递归调用preorderTraversal,它会将值添加到res。使用这些递归调用的结果在add/addAll上调用res是错误的。

public class Solution {
     List<Integer> res = new ArrayList<Integer>();
     public List<Integer> preorderTraversal(TreeNode root) {
            if(root == null){
                return new ArrayList<Integer>();
            }
            res.add(root.val);
            if(root.left != null){
                preorderTraversal(root.left);
            }
            if(root.right != null){
                preorderTraversal(root.right);
            }
            return res;
      }
}

此解决方案存在一些问题 - res会保留先前调用的值,因此在同一实例上多次调用preorderTraversal可能会返回错误的结果。这是一个没有这个缺点的解决方案:

public class Solution {
     public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<Integer>();
            preorderTraversal(root, res);
            return res;
      }
      private void preorderTraversal(TreeNode node, List<Integer> res) {
          if (node != null) {
              res.add(node.val);
              preorderTraversal(node.left, res);
              preorderTraversal(node.right, res);
          }
      }
}

答案 3 :(得分:1)

工作解决方案:

import java.util.ArrayList;
import java.util.List;



class TreeNode 
{
      int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x) { val = x; }
 }

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) 
    {
       ArrayList<Integer> res = new ArrayList<Integer>();

        if(root == null)
            return res;
        else res.add(root.val);

        if(root.left != null)
        {
            res.add(root.left.val);
            preorderTraversal(root.left);
        }

        if(root.right != null)
        {
            res.add(root.right.val);
            preorderTraversal(root.right);
        }


        return res;    
    }
}

public class TreeTest
{


    public static void main(String[] args)
    {

        Solution c = new Solution();

        TreeNode t1 = new TreeNode(1);
        TreeNode t2 = new TreeNode(2);
        TreeNode t3 = new TreeNode(3);

        //Link the nodes of the tree
        t1.left = t2;
        t1.right = t3;


        List<Integer> list = c.preorderTraversal(t1);

        System.out.println(list);
    }
}

答案 4 :(得分:0)

由于您尚未发布完整的代码,如何完成输入并生成输出,因此很难说清楚。对于preorder遍历,它应该是这样的。

 void traverse(TreeNode node){
   if(node != null){
      res.add(node.val);
      traverse(root.left);
      traverse(root.right);
    }
}

答案 5 :(得分:0)

public ArrayList<E> getPreOrderTraversal() {
    return getPreOrderTraversal(root);
}

private ArrayList<E> getPreOrderTraversal(Node tree) {
    ArrayList<E> list = new ArrayList<E>();

    if (tree != null) {
        list.add((E) tree.value);
        list.addAll(getPreOrderTraversal(tree.left));
        list.addAll(getPreOrderTraversal(tree.right));
    }

    return list;
}

答案 6 :(得分:0)

一个可行的且LeetCode接受的解决方案:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        return preOrderTraversalInternal(root, list);
    }
    private List<Integer> preOrderTraversalInternal(TreeNode root, List<Integer> list){
    if(root == null) return list;
    list.add(root.val);
    if(root.left != null){
      preOrderTraversalInternal(root.left, list);
    }
    if(root.right != null){
      preOrderTraversalInternal(root.right, list);
    }
    return list;
  }
}