PAT 解题报告 1074. Reversing Linked List (25)

转载自http://tech-wonderland.net/blog/pat-1074-reversing-linked-list.html

1074. Reversing Linked List 题目描述:

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.

反转链表, 每隔K个反转一次, 例子见上面.

1074. Reversing Linked List 算法分析:

其实就是个模拟题, 改怎么反转就怎么反转, 就是测试用例比较恶心, 注意输入可能不止一个链表的情况, 这种情况下, 要忽略那些不在该链表(输入中的head对应的那个链表)上的节点, 也就是有效节点数(输出的节点个数)比输入中的N要小. 题目的输入使用了数组形式的链表, 可以事先就开好一个足够大的数组, 反转的过程就是一般的反转了, 注意记录下反转以后新的链表头尾, 还有不要忘记把每段反转以后的新的链表接起来. AC代码如下:

001 #include <cstdio>
002  
003 struct Node {
004     int iData;
005     int iNext;
006 };
007  
008 const int iMaxLen = 100004;
009  
010 int iHead;
011 int N, K;
012 Node NodeList[iMaxLen];
013  
014 void doPrint(int iListHead) {
015     while(-1 != iListHead) {
016         if(NodeList[iListHead].iNext == -1) {
017             printf("%.5d %d -1\n",
018                 iListHead,
019                 NodeList[iListHead].iData);
020             break;
021         }
022         printf("%.5d %d %.5d\n",
023             iListHead,
024             NodeList[iListHead].iData,
025             NodeList[iListHead].iNext);
026         iListHead = NodeList[iListHead].iNext;
027     }
028 }
029  
030 int reverseK(int iStartHead, int iK,
031              int *pHead, int *pTail) {
032     if(-1 == iStartHead || iK <= 1)
033         return -1;
034     if(2 == iK) {
035         int node1 = iStartHead;
036         int node2 = NodeList[iStartHead].iNext;
037         NodeList[node1].iNext = NodeList[node2].iNext;
038         NodeList[node2].iNext = node1;
039  
040         *pHead = node2;
041         *pTail = node1;
042         return 0;
043     }
044     *pTail = iStartHead;
045     int node1 = iStartHead;
046     int node2 = NodeList[iStartHead].iNext;
047     int nodeTmp = -1;
048     for(int i = 0; i < iK - 1; ++i) {
049         nodeTmp = NodeList[node2].iNext;
050         NodeList[node2].iNext = node1;
051         node1 = node2;
052         node2 = nodeTmp;
053     }
054     *pHead = node1;
055     NodeList[*pTail].iNext = node2;
056     return 0;
057 }
058  
059 void gao() {
060     int iNodeTmp = iHead;
061     int iEffectiveLength = 1;
062     while(-1 != NodeList[iNodeTmp].iNext) {
063         ++iEffectiveLength;
064         iNodeTmp = NodeList[iNodeTmp].iNext;
065     }
066  
067     if(K > iEffectiveLength) {
068         doPrint(iHead);
069  
070     }
071     N = iEffectiveLength;
072  
073     int iNewHead;
074     if(K > 1) {
075         int iTheHead, iTheTail;
076         int iLastTail;
077         // first init reverse to decide the new head
078         reverseK(iHead, K, &iTheHead, &iTheTail);
079         iNewHead = iTheHead;
080         iLastTail = iTheTail;
081         int iReverseCount = N / K - 1;
082         for(int i = 0; i < iReverseCount; ++i) {
083             reverseK(NodeList[iTheTail].iNext, K, &iTheHead, &iTheTail);
084             NodeList[iLastTail].iNext = iTheHead;
085             iLastTail = iTheTail;
086         }
087     }
088     else
089         iNewHead = iHead;
090     doPrint(iNewHead);
091 }
092  
093 int main() {
094     for(int i = 0; i < iMaxLen; ++i) {
095         NodeList[i].iData = 0;
096         NodeList[i].iNext = -1;
097     }
098     scanf("%d %d %d", &iHead, &N, &K);
099     int iSingleNodeAddress, iSingleNodeData, iSingleNodeNext;
100     for(int i = 0; i < N; ++i) {
101         scanf("%d %d %d", &iSingleNodeAddress, &iSingleNodeData, &iSingleNodeNext);
102         NodeList[iSingleNodeAddress].iData = iSingleNodeData;
103         NodeList[iSingleNodeAddress].iNext = iSingleNodeNext;
104     }
105     gao();
106     return 0;
107 }

1074. Reversing Linked List 注意点:

(1) 这次PAT最坑的一个题目吧, 输入可能不止一个链表, 有些节点不在要反转的那个链表上, 输出的时候应当忽略. 比如

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

(2) 另外注意指针的使用, 还有特例K = 1, K = N之类的情况, 因为上面的特殊坑点, 有可能是打断了的多个链表, 我们的K也有可能大于有效节点数.

(全文完,原创文章,转载时请注明作者和出处)


(转载本站文章请注明作者和出处 烟客旅人 sigmainfy — tech-wonderland.net,请勿用于任何商业用途)

Posted in  AlgorithmPAT

http://www.cnblogs.com/kevin-lwb/p/4283456.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值