一、题目描述
二、思路
- 可以使用双指针,一个记录原链表前面节点的地址(pre),另一个记录相邻的后一个节点地址(cur);
- 然后对各个节点的next指针指向反转;
- 最后返回pre,即翻转后的链表的头节点;
- 动图中pre比cur先移动才对。
三、解题过程
-
定义双指针:
struct ListNode* pre = NULL;
struct ListNode* cur = head;
-
进行循环翻转:
- 先用temNode记录cur的后一个地址(temNode = cur -> next);
- 然后将cur指向的节点的next指针指向pre;
- 接着将pre、cur依次沿原链表顺序往后移一位(pre = cur)(cur = temNode);
- 循环条件:while (cur)
while(cur){
struct ListNode* temNode = cur -> next;
cur -> next = pre;
pre = cur;
cur = temNode;
}
-
输出翻转后的链表的头节点
- 输出 pre
return pre;
四、总代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* pre = NULL;
struct ListNode* cur = head;
while(cur){
struct ListNode* temNode = cur -> next;
cur -> next = pre;
pre = cur;
cur = temNode;
}
return pre;
}
时间复杂度O(n),空间复杂度O(1)
五、其他解法
-
正序递归法
其实思路是一样的,写法不同罢了,代码如下:
struct ListNode* reverse(struct ListNode* pre, struct ListNode* cur) {
if(!cur) return pre;
struct ListNode* temNode = cur -> next;
cur -> next = pre;
cur -> next = pre;
/*pre = cur;
cur = temNode;
return reverse(pre, cur);
*/
return reverse(cur, temNode);
}
struct ListNode* reverseList(struct ListNode* head){
return reverse(NULL,head);
}
时间复杂度O(n),空间复杂度O(1)