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

思路:由于不需要真的自己写一个链表出来,所以可以用util下的LinkedList来实现题目要求的顺序,只要更新一遍链表中元素的地址和下一个元素的地址就可以了。

创建Node类,属性包括地址,存储的数据,以及下一个节点的地址。重写toString()方法方便打印。读取所有的链表元素的属性信息,创建对象并存储在数组中。创建三个链表对象,分别对应题目中小于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、付费专栏及课程。

余额充值