原创...翻版必究...
目录
Problem:
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
Solution:
看网上都是用数组来实现的.因为此题考察的是链表,故觉得使用链表更贴切出题者的意图.另外给定的输入是不固定的,如果使用数组必然开辟最大空间,是一种资源浪费.代码只有100行,思路也没多巧妙,和大家分享下.(有个最大的时间限制,如果超时,多试几次)
//
// Created by wyz on 20-3-24.
//
#include <array>
#include <string>
#include <iostream>
#include <unordered_map>
using namespace std;
struct ListNode{
string curAdd;
int data;
string nextAdd;
ListNode* next;
ListNode(string sc = "", int d = 0, string sn = "", ListNode* nex = nullptr)
:curAdd(sc), data(d), nextAdd(sn), next(nex){}
};
void printListNode(ListNode*& head){
ListNode* cur = head;
while(cur){
cout << cur->curAdd << " " << cur->data << " "
<< cur->nextAdd << endl;
cur = cur->next;
}
};
ListNode* initialList(string& headCurAdd, int& num){
ListNode* dummyHead = new ListNode;
ListNode* cur = dummyHead;
string curAdd;
int data;
string nextAdd;
unordered_map<string, ListNode> myMap;
for(int i = 0; i < num; ++i){
cin >> curAdd >> data >> nextAdd;
myMap.insert(pair<string, ListNode>(curAdd, ListNode{curAdd, data, nextAdd}));
}
//cnt记录不连续节点,由于表头已经给出,
// 地址必须连续当前节点(curNode)nextAdd和下一个节点curAdd相等,
// 如果不等有效节点数到此(curNode)为止.
int cnt{0};
for(int i = 0; i < num; ++i){
if(myMap[headCurAdd].curAdd == ""){++cnt; break;}
ListNode* arrListNode = new ListNode(myMap[headCurAdd]);
cur->next = arrListNode;
cur = cur->next;
//下一个节点curAdd等于当前节点的nextAdd
headCurAdd = cur->nextAdd;
}
num -= cnt;
ListNode* del = dummyHead;
dummyHead = dummyHead->next;
delete del;
return dummyHead;
}
//按照输入的k值反转链表
void reverseListResult(ListNode*& head, int numNodes, int numDivide){
int groups = numNodes/numDivide;
//上一组的链表的尾,后面用到了->next,需要有对象的实体.
ListNode* lastTail = new ListNode;
ListNode* pre = lastTail;
ListNode* del = pre;
//当前组链表的尾和头,只起到变量的作用,没有用到内部元素,创建在栈上.
ListNode* newTail;
ListNode* newHead;
ListNode* cur = head;
for(int j = 0; j < groups; ++j){
newTail = cur;
for(int i = 0; i < numDivide; ++i){
if(cur){
ListNode* next = cur->next;
cur->next = pre;
cur->nextAdd = pre->curAdd;
pre = cur;
cur = next;
}else{ break;}
}
//总的链表头
if(j==0) {head = pre;}
//pre是该组链表旋转后的头节点
newHead = pre;
lastTail->next = newHead;
lastTail->nextAdd = newHead->curAdd;
lastTail = newTail;
}
//不管cur是否为空,反转之后的链表指向下一个节点
lastTail->next = cur;
if(cur){ lastTail->nextAdd = cur->curAdd;}
else{lastTail->nextAdd = "-1";}
delete del;
}
void deleteListNode(ListNode*& head){
ListNode* del;
while(head){
del = head;
head = head->next;
delete del;
}
}
string headCurAdd;
int numNodes, numDivide;
int main(){
cin >> headCurAdd >> numNodes >> numDivide;
ListNode* head = initialList(headCurAdd, numNodes);
reverseListResult(head, numNodes, numDivide);
printListNode(head);
deleteListNode(head);
}