day4
Leetcode 24 两两交换链表中节点
题目比较简单,定义好虚拟头节点dummyhead开始遍历就行,需要注意判断遍历结束条件
cur->next!=nullptr&&cur->next->next!=nullptr
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode*dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode*cur=new ListNode(0);
cur=dummyHead;
while(cur->next!=nullptr&&cur->next->next!=nullptr)
{
ListNode*temp=new ListNode(0);
ListNode*temp1=new ListNode(0);
temp=cur->next->next->next;
temp1=cur->next;
cur->next=cur->next->next;
cur->next->next=temp1;
cur->next->next->next=temp;
cur=cur->next->next;
}
ListNode *result=dummyHead->next;
delete dummyHead;
return result;
}
};
Leetcode 19 删除链表的倒数第n个节点
本题第一眼是笨办法,先得到链表总长度size,再转化为删除第size-n个节点的问题,方法一
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode*cur=dummyHead;
int size=0;
while(cur->next!=nullptr)
{
cur=cur->next;
size++;
}
int index=size-n;
cur=dummyHead;
for(int i=0;i<index;i++)
{
cur=cur->next;
}
cur->next=cur->next->next;
ListNode*result=dummyHead->next;
delete dummyHead;
return result;
}
};
代码随想录采用双指针法,也可以理解为设置一个定长为n的滑动窗口,窗口停止滑动的条件是fast指针到达nullptr
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode*slow=dummyHead;
ListNode*fast=dummyHead;
while(n--&&fast!=nullptr)
{
fast=fast->next;
}
fast=fast->next;
while(fast!=nullptr)
{
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
ListNode*result=dummyHead->next;
delete dummyHead;
return result;
}
};
Leetcode 面试题02.07.链表相交
见到这道题的思路就是先得到两个链表的长度,进行比较,长的链表先将cur遍历到短的head位置,将链表按照结尾对其,然后再同时开始遍历,直到两个cur相等位置。整个过程包括sizeA>sizeB、sizeB>sizeA、sizeA=sizeB。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
ListNode*curA=headA;
ListNode*curB=headB;
int sizeA=0;
int sizeB=0;
int temp=0;
while(curA!=NULL)
{
curA=curA->next;
sizeA++;
}
while(curB!=NULL)
{
curB=curB->next;
sizeB++;
}
curA=headA;
curB=headB;
int delta=0;;
if(sizeA>sizeB)
{
delta=abs(sizeA-sizeB);
temp=sizeB;
while(delta--)
{
curA=curA->next;
}
while(curA!=curB&&temp--)
{
curA=curA->next;
curB=curB->next;
}
if(temp==0)return NULL;
return curA;
}
else if(sizeB>sizeA)
{
delta=abs(sizeA-sizeB);
temp=sizeA;
while(delta--)
{
curB=curB->next;
}
while(curB!=curA&&temp--)
{
curA=curA->next;
curB=curB->next;
}
if(temp==0)return NULL;
return curB;
}
else
{
temp=sizeA;
while(curA!=curB&&temp--)
{
curA=curA->next;
curB=curB->next;
}
if(temp==0)return NULL;
return curA;
}
}
};
看到代码随想录才知道可以通过交换长短的cur只进行一次遍历,不需要进行分类进行判断。
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
Leetcode 142 环形链表Ⅱ
这道题主要是通过数学方面进行分析,刚开始分析时把它当作一个追击问题,快指针每次走两步,慢指针每次走一步,这样总会在环中相遇,本来向通过计算环的长度来反求出环的入口,但是发现得不到整个链表的长度,卡了很久。
看了代码随想录才知道通过数学来分析
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode*slow=head;
ListNode*fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
fast =fast->next->next;
slow=slow->next;
if(slow==fast)
{
ListNode*fast1=fast;
ListNode*slow1=head;
while(slow1!=fast1)
{
slow1=slow1->next;
fast1=fast1->next;
}
return fast1;
}
}
return NULL;
}
};
一般涉及到增删改操作,用虚拟头结点都会方便很多, 如果只能查的话,用不用虚拟头结点都差不多。 对于链表题,想不明白边界条件的时候通过画图能够辅助理解,更好的判断遍历的过程
浙公网安备 33010602011771号