2021/3/18,Leetcode206. 反转链表题意如下:
反转链表有很多种做法,可以用栈之类的操作,时间复杂度都是O(N),但是用栈会增加空间复杂度。这里我们用时间复杂度和空间复杂度都最低的双指针法。简单点说就是头插法,将每一个节点都插在当前链表的表头。说起来容易,代码实现要特别注意指针赋值的顺序。
c++参考代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head)
return nullptr;
ListNode *now=head;//head可以当做当前翻转过的的尾节点,now是链表的头结点
while(head->next!=nullptr)
{
ListNode* tmp=head->next->next;
head->next->next=now;
now=head->next;
head->next=tmp;
}
return now;
}
};
还有一种递归的解法,将反转这个问题拆成头结点和之后节点的翻转。这样两个节点的翻转就很简单了。递归具体操作可以参考这个图:(截图来自老汤《视频讲解:迭代 和 递归【很容易理解】》)
递归方法c++代码:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr)
return nullptr;
if(head->next==nullptr)
return head;
ListNode* p=reverseList(head->next);
head->next->next=head;
head->next=nullptr;
return p;
}
};
Leetcode92. 反转链表 II,题意如下:
和上面的题差不多,我们将left前一个节点记下来,然后翻转left到right后再把头结点接到记下来的节点后就行了。
c++参考代码如下:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
int n=1;
ListNode* hhead = new ListNode(0);//记录表头
hhead->next=head;
ListNode *pre=hhead;//left前的节点
while(n<left)
{
pre=pre->next;
n++;
}
ListNode *now=pre->next;
while(n<right)
{
ListNode *p=now->next;
now->next=p->next;
p->next=pre->next;
pre->next=p;
n++;
}
return hhead->next;
}
};
参考资料
·力扣官方题解
·老汤《视频讲解:迭代 和 递归【很容易理解】》