【剑指offer】3.反转链表
总目录:
1.问题描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0<=≤n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
2.题目解析:
注意题干,
1要求空间复杂度为O(1),即过程中不允许使用导致内存增加的操作;
2.要求时间复杂度为O(n),
想到的方法有
1简单地迭代,逐个由从前向后指变为从后向前指,需要注意边界条件;
2.递归,最后一个非空节点即为返回值,往回迭代的过程中改变指向,注意最开始的head最终要指向null;
3.不能用栈,会造成空间复杂度上升,从而不符合=O(1)的要求;
3.cpp代码
简单迭代法
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* ReverseList(ListNode* pHead) { 12 if (pHead == NULL) { 13 return pHead; 14 } 15 16 ListNode* pPre = NULL; 17 ListNode* pNext = NULL; 18 while (pHead != NULL) { 19 20 //获取next 21 pNext = pHead->next; 22 23 //翻转指向 24 pHead->next = pPre; 25 26 //更新指针 27 if (pNext == NULL) { 28 return pHead; 29 } 30 pPre = pHead; 31 pHead = pNext; 32 } 33 34 return pHead; 35 } 36 };
递归法
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 void recurve(ListNode* cur, ListNode* next, ListNode*& newHead) { 12 //终止条件 13 if (next == NULL) { 14 newHead = cur;//cherry pick 15 return; 16 } 17 18 //递归调用 19 recurve(next, next->next, newHead); 20 21 //本级任务 22 //下一个非空节点指向当前节点 23 cur->next->next = cur; 24 cur->next=NULL; 25 } 26 27 28 ListNode* ReverseList(ListNode* pHead) { 29 //防止输入为空 30 if (pHead == NULL) { 31 return pHead; 32 } 33 34 //去接收最终的head 35 ListNode* newHead = NULL; 36 recurve(pHead, pHead->next, newHead); 37 38 return newHead; 39 } 40 };
虽然但是,用栈的方法,参考一下
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* ReverseList(ListNode* pHead) { 12 //存入栈中 13 stack<ListNode*> sp; 14 while (pHead != NULL) { 15 sp.push(pHead); 16 pHead = pHead->next; 17 } 18 19 if (sp.empty()) { 20 return NULL; 21 } 22 23 //取head 24 ListNode* cur=sp.top(); 25 pHead=cur;//维护返回值 26 sp.pop(); 27 28 //依次翻转指向 29 while (!sp.empty()) { 30 ListNode* temp = sp.top(); 31 sp.pop(); 32 cur->next=temp; 33 cur=temp; 34 } 35 36 //最后一个非空节点,不要让其维持原指向 37 cur->next=NULL; 38 39 return pHead; 40 } 41 };