首页 > 编程语言 >PAT-basic-1025 反转链表 java c++

PAT-basic-1025 反转链表 java c++

时间:2023-02-18 22:14:03浏览次数:53  
标签:1025 Node PAT int list next 链表 java data

一、题目


给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。

输入格式:

每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。

接下来有 N 行,每行格式为:

Address Data Next

其中 Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

输出样例:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

二、解析


这题可以偷懒,倒序后先改变在数组中的位置,不用更新每一个节点的next值就能正常输出了。有坑,不一定所有节点都有效。第五个测试点不用水桶法会超时。第六个测试点需要考虑并不是所有节点都有效。用正常的思维来说,先用一个list来存储所有节点,然后二重循环遍历这个list,把乱序的整成连续的,并用另外一个list存起来。但是这样第五个测试点是超时的。

三、代码


java 超时版:

查看代码

查看代码
 package org.example.shuati;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class PAT_basic_1025 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] str = br.readLine().split("\\s+");
        String start = str[0];
        int n = Integer.parseInt(str[1]);
        int k = Integer.parseInt(str[2]);
        ArrayList<Node> list = new ArrayList<>();
        Node root = new Node();
        for (int i = 0; i < n; i++) {
            String[] s = br.readLine().split("\\s+");
            Node newNode = new Node(s[0], Integer.parseInt(s[1]), s[2]);
            if(s[0].equals(start))
                root = newNode;
            list.add(newNode);
        }
        Node[] lList = new Node[n];
        lList[0] = root;
        Node cur = root;

        int effectiveNode = 1;

        for (int i = 1; i < n; i++) {
            for (Node node : list) {
                if(node.address.equals(cur.next)){
                    lList[i] = node;
                    cur = node;
                    effectiveNode++;
                    break;
                }
            }
        }

        for(int i=0; i<effectiveNode; i+=k){
            if(i+k > effectiveNode) break;
            for(int j=i,p=i+k-1; j<p; j++,p--){
                Node temp = lList[j];
                lList[j] = lList[p];
                lList[p] = temp;
            }
        }

        for(int i=0; i<effectiveNode; i++){
            if(i+1 < effectiveNode)
                System.out.printf("%s %d %s\n", lList[i].address, lList[i].data, lList[i+1].address);
            else
                System.out.printf("%s %d -1", lList[i].address, lList[i].data);
        }
    }
    static class Node{
        private String address;
        private int data;
        private String next;

        public Node() {
        }

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

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }

        public String getNext() {
            return next;
        }

        public void setNext(String next) {
            this.next = next;
        }
    }
}

 

c++超时版,用c++改写上面的java版本仍然是超时的,将无序的输入连成一个有序的链表的二重循环花了太多时间:

查看代码

查看代码
 //
// Created by yaodong on 2023/2/18.
//
#include <vector>
#include "iostream"
using namespace std;

class Node{
    
public:
    int address,data,next;
    Node(int address, int data, int next) : address(address), data(data), next(next) {}
    Node() {}
};
int main(){
    int initAddress, n, k;
    cin>>initAddress>>n>>k;
    vector<Node> vec;
    Node lList[n];
    Node root;

    int add,data,next;
    for(int i=0; i<n; i++){
        cin>>add>>data>>next;
        Node newNode = Node(add, data, next);
        if(add == initAddress)
            root = newNode;
        vec.push_back(newNode);
    }
    lList[0] = root;
    Node cur = root;

    //有效节点,不一定所有的输入都有效
    int eNode = 1;
    for (int i = 1; i < n; ++i) {
        for (auto item: vec){
            if(item.address == cur.next){
                lList[i] = item;
                cur = item;
                eNode++;
                break;
            }
        }
    }


    for(int i=0; i<eNode; i+=k){
        if(i+k > eNode) break;
        for(int j=i,p=i+k-1; j<p; j++,p--){
            Node temp = lList[j];
            lList[j] = lList[p];
            lList[p] = temp;
        }
    }

    for(int i=0; i<eNode; i++){
        if(i+1 < eNode)
            printf("%05d %d %05d\n", lList[i].address, lList[i].data, lList[i+1].address);
        else
            printf("%05d %d -1", lList[i].address, lList[i].data);
    }
    return 0;
}

 

c++ AC版,用水桶法,仔细想想,水桶法也是合理的,因为实际生活中,地址位数肯定是一样的,但是题目没有说明,每一个测试用例都是5位。或许其实连这个也应该想到的。至少猜一下。

//
// Created by yaodong on 2023/2/18.
//

#include "iostream"
using namespace std;
int main(){
    int initAddress, n, k;
    cin>>initAddress>>n>>k;
    int list[100001], data[100001], next[100001];
    int index;
    for(int i=0; i<n; i++){
        cin>>index;
        cin>>data[index]>>next[index];
    }
    //不一定所有节点都有效
    int eNode = 0;
    int nextAdd = initAddress;
    while(nextAdd != -1){
        list[eNode++] = nextAdd;
        nextAdd = next[nextAdd];
    }
    for(int i=0; i<eNode; i+=k){
        if(i+k > eNode) break;
        for(int j=i,p=i+k-1; j<p; j++,p--){
            int temp = list[j];
            list[j] = list[p];
            list[p] = temp;
        }
    }
    for(int i=0; i<eNode; i++){
        if(i+1 < eNode)
            printf("%05d %d %05d\n", list[i], data[list[i]], list[i+1]);
        else
            printf("%05d %d -1", list[i], data[list[i]]);
    }
}

 

标签:1025,Node,PAT,int,list,next,链表,java,data
From: https://www.cnblogs.com/langweixianszu/p/17133760.html

相关文章

  • PAT-basic-1024 科学计数法 java
    一、题目科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该......
  • pat1008
    这个还是比较简单的1#include<iostream>2#include<stdio.h>3usingnamespacestd;45intmain()6{7intn,m;8scanf("%d%d",&n,&m);9......
  • pat1007
    刚开始打算用数组储存的,总是把问题想得太复杂了。1#include<iostream>2#include<math.h>3#include<stdio.h>4usingnamespacestd;56boolIsPrime(i......
  • PAT-basic-1023 组个最小数 java
    一、题目给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:给定两个0,两个1,三个5,一个8,......
  • PAT-basic-1021 个位数统计 java
    一、题目给定一个 k 位整数 N=dk−1​10k−1+⋯+d1​101+d0​ (0≤di​≤9, i=0,⋯,k−1, dk−1​>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定 N=1......
  • PAT-basic-1022 D进制的A+B java
    一、题目输入两个非负10进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数。输入格式:输入在一行中依次给出3个整数 A、B 和 D。输出格式:输出......
  • pat1006
    第一次写的实在太垃圾,没必要对n进行判定的。1#include<iostream>2#include<stdio.h>3usingnamespacestd;45intmain()6{7intn;8sca......
  • PAT 甲级 1002 A+B for Polynomials(25)
    Thistime,youaresupposedtofindA+BwhereAandBaretwopolynomials.InputSpecification:Eachinputfilecontainsonetestcase.Eachcaseoccupies2li......
  • 计算机的数据算法-内存|顺序表|链表|单链表|双端链表
    内存计算机的作用用来存储和运算二进制的数据问题:计算机如何计算1+2?将1和2的二进制类型的数据加载到计算机的内存中,然后使用寄存器进行数值的运算变量......
  • 代码随想录算法训练营 第三天 | 203.移除链表元素 707.设计链表 206.反转链表
    移除链表元素1,双指针pre和cur(如果cur.val等于target pre.next=cur.next)2,虚拟头结点可以保证头结点的处理方式也一致设计链表1,注意审题 ......