【说明】:
本文是左程云老师所著的《程序员面试代码指南》第二章中“反转部分单向链表”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
给定一个单向链表的头节点 head,以及两个整数 from 和 to,在单向链表上把第 from 个节点到第 to 个节点这一部分进行反转。
例如:
1->2->3->4->5->NULL,from=2,to=4
调整结果为:1->4->3->2->5->NULL
再如:
1->2->3->NULL,from=1,to=3
调整结果为:3->2->1->NULL
【要求】:
1、如果链表长度为 N,时间复杂度的要求为 O(N),额外的空间复杂度要求为O(1)。
2、如果不满足1<=from<=to<=N,则不用调整。
【思路】:
整体的思路与链表的反转是差不多的,但是判断 from 的前一个节点和 to 的后一个节点的位置是有技巧的。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
实现及测试代码:
1 /* 2 *文件名:lists_reversePart.cpp 3 *作者: 4 *摘要:单链表部分反转的C++实现 5 */ 6 7 #include <iostream> 8 9 using namespace std; 10 11 struct Node 12 { 13 int value; 14 Node *next; 15 }; 16 17 Node* reversePart(Node *head,int from,int to) 18 { 19 if(NULL == head || from > to || from < 1) 20 return head; 21 int len = 0; 22 Node *node1 = head; 23 Node *fPre = NULL; //from位置的前一个节点 24 Node *tPos = NULL; //to位置的后一个节点 25 while(NULL != node1) //计算链表的长度,并确定fPre 和 tPos 26 { 27 len++; 28 fPre = (len == from-1 ? node1 : fPre); 29 tPos = (len == to+1 ? node1 : tPos); 30 node1 = node1->next; 31 } 32 if(to > len) 33 return head; 34 35 node1 = (fPre == NULL ? head : fPre->next); //from位置的节点 36 Node *node2 = node1->next; 37 node1->next = tPos; //from->next指向to之后的第一个节点tPos 38 Node *next = NULL; 39 //反转from至to之间的节点 40 while(node2 != tPos) //node2为当前;node1为之前;next为之后 41 { 42 next = node2->next; 43 node2->next = node1; 44 node1 = node2; 45 node2 = next; 46 } 47 if(NULL != fPre) //from节点非head节点时 48 { 49 fPre->next = node1; 50 return head; 51 } 52 return node1; 53 } 54 55 void printLists(Node *head) 56 { 57 while(NULL != head) 58 { 59 cout << head->value << " " ; 60 head = head->next; 61 } 62 cout << endl; 63 } 64 65 int main() 66 { 67 Node *head = NULL; 68 Node *ptr = NULL; 69 70 for(int i =0;i<10;i++)//构造链表 71 { 72 if(NULL == head) 73 { 74 head = new Node; 75 head->value = i; 76 head->next = NULL; 77 ptr = head; 78 continue; 79 } 80 ptr->next = new Node; 81 ptr = ptr->next; 82 ptr->value = i; 83 ptr->next = NULL; 84 } 85 86 cout << "Before part reversed: " << endl; 87 printLists(head); 88 head = reversePart(head,3,8); 89 cout << "After remove mid: " << endl; 90 printLists(head); 91 return 0; 92 }
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。