【问题】输入一个链表,反转链表后,输出新链表的表头。
【思路】第一种思路,使用一个堆栈去保存所有的节点,然后再进行依次弹出后并连接起来即可!
1/* 2struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8};*/ 9class Solution { 10public: 11 ListNode* ReverseList(ListNode* pHead) { 12 stack<ListNode*> sta; 13 ListNode* cur = pHead; 14 ListNode* newHead; // 要返回的头结点 15 if(pHead == nullptr || pHead->next == nullptr){ 16 return pHead; 17 } 18 while(cur->next != nullptr){ 19 sta.push(cur); 20 cur = cur->next; 21 } 22 newHead = cur; // 最后一个节点为新链表的头结点 23 while(!sta.empty()){ 24 cur->next = sta.top(); 25 sta.pop(); 26 cur = cur->next; 27 } 28 cur->next = nullptr; 29 return newHead; 30 } 31};
第二种,如果不使用额外的空间的话,我们可以使用两个指针pre和next, 对链表相邻的两个节点进行交换调整,这才是面试官想要看到的算法!循环中主要有四步:
-
保存当前节点的next节点,下一步要改变,需要保存
-
修改当前节点的next节点为pre(前驱节点)
-
pre指针直到当前节点
-
pHead指针指向next节点(向后移动)
-
1/* 2struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8};*/ 9class Solution { 10public: 11 ListNode* ReverseList(ListNode* pHead) { 12 if(pHead == nullptr || pHead->next == nullptr){ 13 return pHead; 14 } 15 ListNode* pre = nullptr; 16 ListNode* next = nullptr; 17 while(pHead != nullptr){ 18 next = pHead->next; // 保存next节点,因为下一步要修改pHead.next 19 pHead->next = pre; // 第一次pre=null,即第一个节点指向空 20 pre = pHead; 21 pHead = next; 22 } 23 return pre; 24 } 25};