中国大学生mooc——02-线性结构3 Reversing Linked List (25 分)

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 (≤10​5​​) 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真的慢!!!

猜你喜欢

转载自blog.csdn.net/a429367172/article/details/88428145