• PAT Basic 反转链表 (25) [链表]


    题目

    给定⼀个常数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(<= 10^5)、以及正整数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

    题目分析

    已知N个结点,以K为步长,反转链表

    解题思路

    1. 定义结点,使用数组存储N个结点,使用order属性记录链表中结点出现序号
    2. 将链表分为n/k个段,对每个段进行反转
      2.1 每个节点的next即为反转后的下一个结点地址
      2.2 每个段最后一个节点的特殊处理:next为下一个段反转前最后一个结点
      2.3 最后一个段的处理
      • 若n%k==0,说明n可以正好分为n/k个段,最后一个段反转,并将最后一个节点置为-1
      • 若n%k!=0,说明最后一段小于k,开始下标为n/k*k,不需要反转,顺序打印,并将最后一个结点置为-1

    知识点

    1. 将n个结点分为n/k个段,最后一段开始下标为n/k*k(下标从0开始)
    2. 链表反转,不一定非要对链表进行反转(即:更换每个结点next值),可以使用本题思想反向打印的办法

    易错点

    1. 已知结点中,有不存在与链表上的无效结点

    Code

    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=100010;
    struct node {
    	int adr;
    	int data;
    	int next;
    	bool flag=false;//初始化为false
    	int order=maxn;
    } nds[maxn];
    bool cmp(node &n1,node &n2) {
    	return n1.order<n2.order;
    }
    int main(int argc,char *argv[]) {
    	int hadr,n,k,adr;
    	scanf("%d %d %d",&hadr,&n,&k);
    	for(int i=0; i<n; i++) {
    		scanf("%d",&adr);
    		scanf("%d %d",&nds[adr].data,&nds[adr].next);
    		nds[adr].adr=adr;
    	}
    	int count=0;
    	for(int i=hadr; i!=-1; i=nds[i].next) {
    //		nds[i].flag=true;
    		nds[i].order=count++;
    	}
    	sort(nds,nds+maxn,cmp);
    	n=count;
    //	for(int i=0; i<n; i++) {
    //		printf("%05d %05d %05d
    ",nds[i].adr,nds[i].data,nds[i].next);
    //	}
    	for(int i=0; i<n/k; i++) {
    		for(int j=(i+1)*k-1; j>i*k; j--) {
    			printf("%05d %d %05d
    ",nds[j].adr,nds[j].data,nds[j-1].adr);
    		}
    		printf("%05d %d",nds[i*k].adr,nds[i*k].data);
    		if(i<n/k-1) {
    			printf(" %05d
    ",nds[(i+2)*k-1].adr);
    		} else {
    			if(n%k==0)printf(" -1
    "); //正好可以分为n/k块,并且打印最后一块
    			else {
    				printf(" %05d
    ",nds[(i+1)*k].adr);
    				for(int j=n/k*k; j<n; j++) {
    					printf("%05d %d",nds[j].adr,nds[j].data);
    					if(j<n-1)printf(" %05d
    ",nds[j+1].adr);
    					else printf(" -1
    ");
    				}
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Eclipse安装Pydev插件时所遇到的问题
    打开Eclipse弹出“No java virtual machine was found..."的解决方法
    使用adb报错;error: unknown host service
    itools安装程序无法创建临时文件夹
    多线程十二之ConcurrentHashMap1.8实现分析
    多线程十一之ConcurrentHashMap1.7源码分析
    多线程十之CopyOnWriteArrayList源码分析
    多线程学习笔记九之ThreadLocal
    多线程学习笔记八之线程池ThreadPoolExecutor实现分析
    多线程学习笔记七之信号量Semaphore
  • 原文地址:https://www.cnblogs.com/houzm/p/12296864.html
Copyright © 2020-2023  润新知