PAT乙级 1075 链表元素分类 java(20/25) 测试点5超时

思路:由于不需要真的自己写一个链表,所以可以用uitl下的LinkedList来实现,只需要更新LinkedList中元素的address和next使打印的结果符合一个真链表的形式即可。

创建Node类,属性包含int类型的地址、数据、下一个节点的地址。重写toString()方法以便打印Node对象。

初始化Node类型的数组,读取所有元素的属性信息,创建对应的Node对象并以对象的地址属性为索引存储在数组中。

创建三个LinkedList对象,对应题目中的三个类别,分别为:小于0、0到K、大于K。通过数组索引遍历所有的元素,分类存入三者。

创建最终目标链表对象,按题目要求的顺序将之前的三个链表中的元素存入目标链表中,更新元素的地址和下一个节点的地址使打印的结果符合一个真链表的形式。

和1025 反转链表类似,也是有一个测试点爆了,不过1025貌似是内存超限

代码如下:

import java.io.*;
import java.util.*;

public class Main {

    //匿名内部类提升效率
    static class Node{
        int address;
        int data;
        int next;

        public Node(int address,int data,int next){
            this.address=address;
            this.data=data;
            this.next=next;
        }

        //按题目要求重写toString()
        @Override
        public String toString(){
            if(this.next!=-1){
                return String.format("%05d",address)+" "+data+" "+String.format("%05d",next);
            }
            else{
                return String.format("%05d",address)+" "+data+" "+String.format("%02d",next);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

        in.nextToken();
        int head=(int)in.nval;
        in.nextToken();
        int total=(int)in.nval;
        in.nextToken();
        int k=(int)in.nval;

        //数据范围1到100000的整数,初始化一个同范围的数组
        Node[] node=new Node[100000];

        for(int i=1;i<=total;i++){
            in.nextToken();
            int address=(int)in.nval;
            in.nextToken();
            int data=(int)in.nval;
            in.nextToken();
            int next=(int)in.nval;

            node[address]=new Node(address,data,next);
        }

        classify(node,k,head);
    }

    private static void classify(Node[] node, int k,int head) {
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        //通过next来寻找数组中的下一个Node元素,头指针就是head
        int index=head;

        //创建三个链表对象,对应三种元素类别:小于0的、0到K的、大于K的
        List<Node> negative=new LinkedList<>();
        List<Node> lessThanK=new LinkedList<>();
        List<Node> moreThanK=new LinkedList<>();

        //分类添加
        while(node[index].next!=-1){
            if(node[index].data<0){
                negative.add(node[index]);
            }
            else if(node[index].data>=0&&node[index].data<=k){
                lessThanK.add(node[index]);
            }
            else{
                moreThanK.add(node[index]);
            }
            index=node[index].next;
        }
        //这种while写法会导致最后一个没添加进去,手动添加一遍
        if(node[index].data<0){
            negative.add(node[index]);
        }
        else if(node[index].data>=0&&node[index].data<=k){
            lessThanK.add(node[index]);
        }
        else{
            moreThanK.add(node[index]);
        }

        //创建一个链表,用来存储最后的结果,并按照题目要求顺序把之前三个链表的元素全部添加进去
        List<Node> result = new LinkedList<>(negative);
        result.addAll(lessThanK);
        result.addAll(moreThanK);

        //假的链表,因为LinkedList中的顺序已经对了,只是address和next对不上,这一步是为了让打印的结果符合真链表的形式
        int addressTemp=-1;
        for(int i=result.size()-1;i>=0;i--){
            Node data=result.get(i);
            data.next=addressTemp;
            addressTemp=data.address;
        }

        for(Node data:result){
            out.println(data);
        }

        out.flush();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值