按指定大小分组反转链表结果异常,请求排查原因
分组反转链表问题排查
问题情况
- 题目要求:给定大小为N的链表,将每k个节点作为一组反转;若节点数不是k的倍数,剩余节点也需反转。
- 示例输入:链表
1->2->2->4->5->6->7->8,K=4 - 预期输出:
4 2 2 1 8 7 6 5 - 实际输出:
8 7 6 5 4 2 2 1
错误原因分析
核心问题出在寻找当前分组尾节点的循环条件:
while(count<k || tail->next!=NULL){ tail = tail->next; count++; }
这个条件会直接遍历到整个链表的末尾,而不是当前组的第k个节点。以示例为例,第一次循环会直接走到最后一个节点8,此时把整个链表截断后反转,得到8->7->6->5->4->2->2->1,后续递归处理的head2为NULL,最终结果就是整个链表被反转,而非按k=4分组反转。
修正方案
将寻找尾节点的循环修改为只遍历k步(或到链表末尾),准确找到当前组的最后一个节点:
int count = 0; node* tail = head; // 找到当前组的第k个节点,或链表末尾 while(count < k-1 && tail != NULL && tail->next != NULL){ tail = tail->next; count++; }
这里循环k-1次是因为从head(第1个节点)出发,走k-1步就能到达第k个节点;同时加入tail != NULL && tail->next != NULL的判断,避免链表长度不足k时出现空指针异常。
修正后的完整代码
//{ Driver Code Starts #include<bits/stdc++.h> using namespace std; struct node { int data; struct node* next; node(int x){ data = x; next = NULL; } }; /* Function to print linked list */ void printList(struct node *node) { while (node != NULL) { printf("%d ", node->data); node = node->next; } printf("\n"); } // } Driver Code Ends /* Reverse a linked list The input list will have at least one element Return the node which points to the head of the new LinkedList Node is defined as struct node { int data; struct node* next; node(int x){ data = x; next = NULL; } }*head; */ class Solution { node* reverseHelper(node* head){ node* pre = NULL; node* curr = head; while(curr!=NULL){ node* nextTocurr = curr->next; curr->next = pre; pre = curr; curr = nextTocurr; } return pre; } public: struct node *reverse (struct node *head, int k) { if(head==NULL){ return head; } int count = 0; node* tail = head; // 修正:找到当前组的第k个节点或链表末尾 while(count < k-1 && tail != NULL && tail->next != NULL){ tail = tail->next; count++; } node* head2 = tail->next; tail->next = NULL; node* ans = reverseHelper(head); head->next = reverse(head2,k); return ans; } }; //{ Driver Code Starts. /* Drier program to test above function*/ int main(void) { int t; cin>>t; while(t--) { struct node* head = NULL; struct node* temp = NULL; int n; cin >> n; for(int i=0 ; i<n ; i++) { int value; cin >> value; if(i == 0) { head = new node(value); temp = head; } else { temp->next = new node(value); temp = temp->next; } } int k; cin>>k; Solution ob; head = ob.reverse(head, k); printList(head); } return(0); } // } Driver Code Ends
验证修正效果
以示例输入为例:
- 第一次循环找到第4个节点4,将链表分为
1->2->2->4和5->6->7->8 - 反转第一组得到
4->2->2->1,原head(1)变为当前组的尾节点 - 递归处理第二组,反转得到
8->7->6->5 - 将第一组尾节点1的next指向第二组反转后的头节点8,最终得到
4->2->2->1->8->7->6->5,与预期输出一致。
内容的提问来源于stack exchange,提问作者Sanchit
相关产品推荐
相关产品推荐

