java成长日记(15)

7-4 列出叶结点

分数 300

全屏浏览题目

切换布局

作者 陈越

单位 浙江大学

对于给定的二叉树,本题要求你按从上到下、从左到右的顺序输出其所有叶结点。

输入格式:

首先第一行给出一个正整数 N(≤10),为树中结点总数。树中的结点从 0 到 N−1 编号。随后 N 行,每行给出一个对应结点左右孩子的编号。如果某个孩子不存在,则在对应位置给出 "-"。编号间以 1 个空格分隔。

输出格式:

在一行中按规定顺序输出叶结点的编号。编号间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

输出样例:

4 1 5

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

这是我一开始的代码,思路之后再讲解:

import java.util.*;

class NewNode {
    int val = -1;
    int look = 0;

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    NewNode left;

    public NewNode getLeft() {
        return left;
    }

    public void setLeft(NewNode left) {
        this.left = left;
    }

    NewNode right;

    public NewNode getRight() {
        return right;
    }

    public void setRight(NewNode right) {
        this.right = right;
    }

    NewNode parent;

    public NewNode getParent() {
        return parent;
    }

    public void setParent(NewNode parent) {
        this.parent = parent;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        ArrayList<NewNode> node = new ArrayList<>();
        if(N > 10){
            N = 10;
        }
        for (int i = 0; i < N; i++) {
            NewNode tmp_l = new NewNode();
            NewNode tmp_r = new NewNode();
            String left = scanner.next();
            if(!left.equals("-")){
                tmp_l.setVal(Integer.valueOf(left));
            }
            String right = scanner.next();
            if(!right.equals("-")){
                tmp_r.setVal(Integer.valueOf(right));
            }
            NewNode tmp = new NewNode();
            tmp.setVal(i);
            tmp.setLeft(tmp_l);
            tmp.setRight(tmp_r);
            node.add(tmp);
        }
        NewNode root = GetTree(node , N);
        StringBuilder sb = new StringBuilder();
        sb = cengci(root , N);
        String infor = sb.substring(0 , sb.length() - 1);
        System.out.print(infor);
    }
    static NewNode GetTree(ArrayList<NewNode> node , int N){
        NewNode root = node.get(0);
        node.remove(0);
        NewNode current = root;
        int flag;
        while (!node.isEmpty()){
            flag = 0;
            for (int i = 0; i < node.size(); i++) {
                if(current.look >= 2 && current.parent != null){
                    current = current.parent;
                    i = 0;
                }
                NewNode newNode = node.get(i);
                if(current.parent == null){
                    root = current;
                }
                if(current.left != null && current.right != null && current.left.val == newNode.val && current.right.val != -1){
                    current.look++;
                    current.left = newNode;
                    newNode.parent = current;
                    current = current.left;
                    flag = i;
                    break;
                } else if (current.left != null && current.right != null && current.right.val == newNode.val && current.left.val != -1) {
                    current.look++;
                    current.right = newNode;
                    newNode.parent = current;
                    current = current.right;
                    flag = i;
                    break;
                } else if (current.left != null && current.right != null && current.left.val == newNode.val && current.right.val == -1) {
                    current.look = current.look + 2;
                    current.left = newNode;
                    newNode.parent = current;
                    current = current.left;
                    flag = i;
                    break;
                }else if (current.left != null && current.right != null && current.right.val == newNode.val && current.left.val == -1) {
                    current.look = current.look + 2;
                    current.right = newNode;
                    newNode.parent = current;
                    current = current.right;
                    flag = i;
                    break;
                } else if (newNode.left != null && newNode.right != null && newNode.left.val == current.val && newNode.right.val != -1) {
                    current.parent = newNode;
                    newNode.left = current;
                    current = current.parent;
                    current.look++;
                    flag = i;
                    break;
                }else if (newNode.left != null && newNode.right != null && newNode.right.val == current.val && newNode.left.val != -1) {
                    current.parent = newNode;
                    newNode.right = current;
                    current = current.parent;
                    current.look++;
                    flag = i;
                    break;
                } else if (newNode.left != null && current.right != null && newNode.left.val == current.val && newNode.right.val == -1) {
                    current.parent = newNode;
                    newNode.left = current;
                    current = current.parent;
                    flag = i;
                    break;
                }else if (newNode.left != null && current.right != null && newNode.right.val == current.val && newNode.left.val == -1) {
                    current.parent = newNode;
                    newNode.right = current;
                    current = current.parent;
                    flag = i;
                    break;
                } else if (current.left.val == -1 && current.right.val == -1 && current.val != -1 && current.parent != null) {
                    current = current.parent;
                    flag = -1;
                    break;
                }
            }
            if(flag != -1)
            node.remove(flag);
        }
        return root;
    }

    static StringBuilder cengci(NewNode node , int n){
        StringBuilder sb = new StringBuilder();
        Queue<NewNode> queue = new LinkedList<>();
        if(node == null){
            return null;
        }
        int nums = 0;
        queue.add(node);
        while (!queue.isEmpty()){
            NewNode front = queue.peek();
            nums++;
            if(front.right != null && front.left != null && front.right.val == -1 && front.left.val == -1  && front.val != -1)
                sb.append(front.val + " ");
            else if (front.right == null && front.left == null && front.val != -1) {
                sb.append(front.val + " ");
            }
            queue.poll();
            if(front.left != null){
                queue.add(front.left);
            }
            if(front.right != null){
                queue.add(front.right);
            }
        }
        return sb;
    }
}

提交的结果如下- -:

  这个题我一开始是想用“拼拼图”的思想来写的,如下图:

  

然后这是我根据题目画的“拼图”:

 

 这思路确实是挺麻烦的,要细致地考虑多种情况。针对上面测试样例3的提示,我也尝试了不少例子,输出没错,但就是过不了T T

  然后今天早上我向老师请教了这个问题,老师说可以用顺序表,一开始就把它们的父节点找到并记录下来,之后根据顺序表构建二叉树,这可比我之前那个思路清晰多了。于是一下课,我就立马回宿舍尝试一下这个思路。

 首先观察下面这个图:

  仔细观察,我们可以发现可以根据每一行的Left值和Right值找到它们的父节点(即编号)。

  所以经过修改后,我的代码变成了这样:

import java.util.*;

class NewNode {
    int val = -1;
    int look = 0;

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    NewNode left;

    public NewNode getLeft() {
        return left;
    }

    public void setLeft(NewNode left) {
        this.left = left;
    }

    NewNode right;

    public NewNode getRight() {
        return right;
    }

    public void setRight(NewNode right) {
        this.right = right;
    }

    NewNode parent;

    public NewNode getParent() {
        return parent;
    }

    public void setParent(NewNode parent) {
        this.parent = parent;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        NewNode node[] = new NewNode[N];
        if(N > 10){
            N = 10;
        }
        for (int i = 0; i < N; i++) {
            NewNode tmp_l = new NewNode();
            NewNode tmp_r = new NewNode();
            String left = scanner.next();
            if(!left.equals("-")){
                tmp_l.setVal(Integer.valueOf(left));
            }
            String right = scanner.next();
            if(!right.equals("-")){
                tmp_r.setVal(Integer.valueOf(right));
            }
            NewNode tmp = new NewNode();
            tmp.setVal(i);
            tmp.setLeft(tmp_l);
            tmp.setRight(tmp_r);
            node[i] = tmp;
        }
        NewNode root = new NewNode();
        for (int i = 0; i < node.length; i++) {
            NewNode tmp = node[i];
            if(tmp.left.val != -1){
                NewNode tmp1 = node[tmp.left.val];
                tmp1.parent = tmp;
            }
            if(tmp.right.val != -1){
                NewNode tmp1 = node[tmp.right.val];
                tmp1.parent = tmp;
            }
        }
        int rot = 0;
        for (int i = 0; i < node.length; i++) {
            NewNode tmp = node[i];
            if(tmp.parent == null){
                root = tmp;
                rot = i;
                break;
            }
        }
        NewNode tree = buildTree(rot , node);
        StringBuilder sb = new StringBuilder();
        sb = cengci(tree , N);
        String infor = sb.substring(0 , sb.length() - 1);
        System.out.print(infor);
    }

    static NewNode buildTree(int rot , NewNode[] node){
        NewNode t = node[rot];
        NewNode tr = new NewNode();
        tr.val = t.val;
        if(t.left.val != -1){
            tr.left = buildTree(t.left.val, node);
        }else tr.left = null;
        if(t.right.val != -1){
            tr.right = buildTree(t.right.val, node);
        }else tr.right = null;
        return tr;
    }

    static StringBuilder cengci(NewNode node , int n){
        StringBuilder sb = new StringBuilder();
        Queue<NewNode> queue = new LinkedList<>();
        if(node == null){
            return null;
        }
        int nums = 0;
        queue.add(node);
        while (!queue.isEmpty()){
            NewNode front = queue.peek();
            nums++;
            if(front.right != null && front.left != null && front.right.val == -1 && front.left.val == -1  && front.val != -1)
                sb.append(front.val + " ");
            else if (front.right == null && front.left == null && front.val != -1) {
                sb.append(front.val + " ");
            }
            queue.poll();
            if(front.left != null){
                queue.add(front.left);
            }
            if(front.right != null){
                queue.add(front.right);
            }
        }
        return sb;
    }
}

   在主函数中,我用数组替换了一开始用的Arrayslist(其实都差不多的- -,这个细节可以忽略)。第一个循环我用来储存输入的值;第二个循环我就开始利用上图的特性找到它们的父节点;第三个循环我用来找其根节点以及根节点所在的位置。之后用buildTree()的方法来生成二叉树。之后用StringBuilder来储存要输出的值,最后利用.substring(0 , sb.length() - 1)的技巧把多余的空格删去。

  运行结果如下:

  

  这是我写代码时试过的用例:

7
1 2
3 4
5 6
- -
- -
- -
- -

7
1 2
3 4
- -
5 6
- -
- -
- -

10
1 2
- -
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- -

7
1 -
2 3
- -
4 5
- 6
- -
- -

7
1 2
3 4
- -
- -
5 6
- -
- -

7
4 1
- -
3 0
5 6
- -
- -
- - 

7
- 1
- -
3 0
4 5
6 -
- -
- -

9
1 2
3 4
- -
5 6
- -
- -
7 8
- -
- -

10
1 2
3 4
5 6
7 8
9 -
- -
- -
- -
- -
- -

7
1 4
2 3
- -
6 5
- -
- -
- -

10
1 2
3 4
8 9
5 6
- -
7 -
- -
- -
- -
- -

5
- -
- -
- -
0 2
3 1 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值