02-线性结构3 Reversing Linked List (25 分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address
is the position of the node, Data
is an integer, and Next
is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
- 作者: 陈越
- 单位: 浙江大学
- 时间限制: 400 ms
- 内存限制: 64 MB
- 代码长
分析
一开始,以为就是简单的将链表的前K个元素转置,然后就按照链表的方式应对,需要注意的是,单链表只能从前往后找,不能从后往前找,所以我们需要三个指针cur,front,back(以当前节点为2时为例):
要逆序,所以需要记录前一个的位置(front),然后利用cur->next = front,实现逆序,需要注意的是,直接这么做会导致2后面的节点丢失,需要提前用back记录cur的下一个位置。代码如下:
import java.io.Reader;
import java.util.Scanner;
import java.io.*;
class Node{
public int data;
public int next;
public Node(int data, int next)
{
this.data = data;
this.next = next;
}
}
public class Main{
private static int MAX_SIZE = 100010;
private static Node List[] = new Node[MAX_SIZE];
private static Reader reader;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
reader = new InputStreamReader(System.in);
int head = scan.nextInt();
int N = scan.nextInt();
int K = scan.nextInt();
int addr, data, next;
for(int i = 0; i < N; i++)
{
addr = scan.nextInt();
data = scan.nextInt();
next = scan.nextInt();
List[addr] = new Node(data,next);
}
int front = head;
int back = head;
int cur = 0;
for(int i = 0; i < K; i++) {
cur = back;
back = List[back].next;//保存下一个back
List[cur].next = front;//逆序
front = cur;
}
List[head].next = back;
head = front;
int p = head;
while(List[p].next != -1)
{
data = List[p].data;
next = List[p].next;
System.out.printf("%05d %d %05d\n", p, data,next);
p = List[p].next;
}
data = List[p].data;
next = List[p].next;
System.out.printf("%05d %d %d\n", p, data,next);
}
}
However
这个代码只得了19分,看了别人的博客之后,仔细读题发现:
you are supposed to reverse the links of every K elements on L;
if K=3, then you must output 3→2→1→6→5→4;
原来,他要每过K个元素就逆序,这。。。
按照网上的思路,更改之后的代码:
import java.io.Reader;
import java.util.*;
import java.util.Collections;
import java.util.Scanner;
import java.io.*;
class Node{
public int data;
public int next;
public Node(int data, int next)
{
this.data = data;
this.next = next;
}
}
public class Main{
// private static long ans = 0;
// private static long mod = 1000000007;
private static int MAX_SIZE = 100010;
private static Node node[] = new Node[MAX_SIZE];
private static Integer list[] = new Integer[MAX_SIZE];
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int head = scan.nextInt();
int N = scan.nextInt();
int K = scan.nextInt();
int addr, data, next;
for(int i = 0; i < N; i++)
{
addr = scan.nextInt();
data = scan.nextInt();
next = scan.nextInt();
node[addr] = new Node(data,next);
}
int real_num = 0;
int p = head;
while(p != -1)/*记录链表的连接顺序,同时记录链表的个数*/
{
list[real_num++] = p;
p = node[p].next;
}
int i = 0;
while(i + K <= real_num)
{
Integer tmp[] = new Integer[K];
System.arraycopy(list, i, tmp, 0, K);//获取list的从i开始的K个元素
Collections.reverse(Arrays.asList(tmp));//逆序
System.arraycopy(tmp, 0, list, i, K);//拷贝回去
i = i + K;
}
i = 0;
while(i < real_num-1)
{
System.out.printf("%05d %d %05d\n", list[i], node[list[i]].data, list[i+1]);
i++;
}
System.out.printf("%05d %d %d\n", list[i], node[list[i]].data, -1);
}
}
但是发现:
5 | 最大N,最后剩K-1不反转 | 运行超时 | 0 ms | 0 KB |
JAVA也是真的慢,利用InputStreamReader之后,还是不行。尝试直接输入,然后不逆序直接输出也超时了。。。JAVA真的慢!!!