算法day10 反转链表
问题描述
思路一:双指针法
对于要反转的链表,我们为了便于操作,可以设置两个指针:pre以及cur,见词知意,这里的pre指针即是cur的前驱指针(当然,反转过后它就是后驱指针),初始时为nullptr,而cur就是当前指针,初始时为head。这里我们在cur存在的判断条件下循环,在整个过程中,每一次更新时由于我们要将链接方向反转会导致丢失后续的链接,所以我们设置一个临时指针temp,赋值为cur的后驱,这样我们就保留住了下一个位置。随后令当前的指针指向的后驱指向它的前驱pre,达到反转,待循环结束后,返回pre指针即可,此时pre是头指针。
代码如下
ListNode* reverseList(ListNode* head) {
ListNode *pre = nullptr;
ListNode *cur = head;
while(cur){
ListNode *temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
时间复杂度:O(n)
空间复杂度:O(1)
思路二:递归(不推荐)
思路二即利用递归的方式来代替思路一中的pre与cur指针迭代过程,最后当cur为空时返回pre即可。个人不推荐递归方式,对于不熟悉的朋友,可能在考虑出口以及递归条件时抓耳挠腮,而且递归对于栈区是有危害的,在规模稍大的情况下容易造成栈溢出。
代码如下
ListNode* reverselist(ListNode *pre,ListNode *cur){
if(!cur){
return pre;
}
ListNode *temp = cur -> next;
cur -> next = pre;
return reverselist(cur,temp);
}
ListNode* reverseList(ListNode* head) {
ListNode *cur = head;
ListNode *pre = nullptr;
return reverselist(pre,cur);
}
时间复杂度:O(n)
空间复杂度:O(n)
END