算法学习day4
1. 力扣24题-两两交换链表中的节点
1.1 分析
1.链表的相邻的两个节点交换。
2.每次循环遍历两个节点。
3.循环条件当为偶数个节点cur->next 为NULL,当为奇数个节点cur->next->next 为NULL。
4.节点交换步骤如下图所示。
图片来源:代码随想录
1.2 代码
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);//实例化一个虚拟头节点
dummyHead->next = head;//将虚拟头节点指向头节点
ListNode* cur = dummyHead;//临时节点指向虚拟头节点
//cur->next !=NULL && cur->next->next !=NULL顺序不能反,若先写后面如果cur->next为空。cur->next->next对空指针操作。引发错误
while(cur->next !=NULL && cur->next->next !=NULL){
ListNode* temp = cur->next;//保存节点1
ListNode* temp1 = cur->next->next->next;//保存节点3
//开始交换
cur->next = cur->next->next;//步骤1
cur->next->next = temp;//步骤2
temp->next = temp1;//步骤3
//移动
cur = cur->next->next;
}
return dummyHead->next;
}
};
2. 力扣19题-删除链表的倒数第N个节点
2.1 分析
1.设置一个虚拟头节点。
2.要删除倒数第N个节点,要找到倒数第N个节点的前一个节点。
3.利用双指针法,先让快指针移动n+1步,然后快慢指针一起移动。
4.当fast到达尾部NULL,删除slow->next即可。
2.2 代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);//实例化一个虚拟头节点
dummyHead->next = head;//虚拟头节点指向head节点
ListNode* fast = dummyHead;//快指针
ListNode* slow = dummyHead;//慢指针
//快指针移动n+1步,然后快慢指针一起移动
n++;
while(n-- && fast !=NULL){
fast = fast->next;
}
//快慢指针一起移动
while( fast !=NULL){
fast = fast->next;
slow = slow->next;
}
ListNode* temp = slow->next;//释放操作
slow->next = slow->next->next;//删除操作
delete temp;
return dummyHead->next;
}
};
3. 面试题 02.07. 链表相交
3.1 分析
1.定义两个指针,在两个链表的头节点上。
2.遍历两个指针,求出 A,B 的长度。
3.求出长度差gap,让更长的链表先走 gap个单位。
4.然后同时遍历直到两个指针相同,相同即为相交,返回交点。
5.到最后为空就是没有交点。
3.2 代码
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
ListNode* fast;
ListNode* slow;
int lenA = 0;
int lenB = 0;
int gap = 0;
//求A的长度
while(curA !=NULL){
curA = curA->next;
lenA++;
}
//求B的长度
while(curB !=NULL){
curB =curB->next;
lenB++;
}
//若求出长度差值,若B大设置快指针指向B的头节点
if(lenB>lenA){
gap = lenB - lenA;
fast = headB;
slow = headA;
}
//若求出长度差值,若A大设置快指针指向A的头节点
else
{
gap = lenA - lenB;
fast = headA;
slow = headB;
}
//更长的链表先走gap个单位
while(gap--){
fast = fast->next;
}
//同时遍历直到两个指针相同,相同即为相交。返回
while( fast != slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
};
4. 力扣142题-环形链表II
4.1 分析
代码随想录视频:把环形链表讲清楚!LeetCode:142.环形链表Il
4.2 代码
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;//快指针指向头
ListNode* slow = head;//慢指针指向头
//快指针一次走两步
while(fast!= NULL && fast->next !=NULL){
//开始移动
slow = slow->next;//走一步
fast = fast->next->next;//走两步
//判断fast与slow在环中是否相遇
if(fast == slow){
//在相遇点定义指针index1,在头节点定义index2.同时移动一个单位,在一次相遇的位置即为入口点
ListNode* index1 = fast;//在相遇点定义指针index1
ListNode* index2 = head;//在头节点定义index2
while(index1 != index2){
//同时移动一个单位,在一次相遇的位置即为入口点
index2 = index2->next;
index1 = index1->next;
}
return index1;
}
}
return NULL;
}
};