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代码如下:
008 | const int iMaxLen = 100004; |
012 | Node NodeList[iMaxLen]; |
014 | void doPrint( int iListHead) { |
015 | while (-1 != iListHead) { |
016 | if (NodeList[iListHead].iNext == -1) { |
017 | printf ( "%.5d %d -1\n" , |
019 | NodeList[iListHead].iData); |
022 | printf ( "%.5d %d %.5d\n" , |
024 | NodeList[iListHead].iData, |
025 | NodeList[iListHead].iNext); |
026 | iListHead = NodeList[iListHead].iNext; |
030 | int reverseK( int iStartHead, int iK, |
031 | int *pHead, int *pTail) { |
032 | if (-1 == iStartHead || iK <= 1) |
035 | int node1 = iStartHead; |
036 | int node2 = NodeList[iStartHead].iNext; |
037 | NodeList[node1].iNext = NodeList[node2].iNext; |
038 | NodeList[node2].iNext = node1; |
045 | int node1 = iStartHead; |
046 | int node2 = NodeList[iStartHead].iNext; |
048 | for ( int i = 0; i < iK - 1; ++i) { |
049 | nodeTmp = NodeList[node2].iNext; |
050 | NodeList[node2].iNext = node1; |
055 | NodeList[*pTail].iNext = node2; |
060 | int iNodeTmp = iHead; |
061 | int iEffectiveLength = 1; |
062 | while (-1 != NodeList[iNodeTmp].iNext) { |
064 | iNodeTmp = NodeList[iNodeTmp].iNext; |
067 | if (K > iEffectiveLength) { |
071 | N = iEffectiveLength; |
075 | int iTheHead, iTheTail; |
078 | reverseK(iHead, K, &iTheHead, &iTheTail); |
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; |
094 | for ( int i = 0; i < iMaxLen; ++i) { |
095 | NodeList[i].iData = 0; |
096 | NodeList[i].iNext = -1; |
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; |
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,请勿用于任何商业用途)