算法day04|24. 两两交换链表中的节点19.删除链表的倒数第N个节点 面试题 02.07. 链表相交142.环形链表II
day04 2.18
快慢指针、找倒数第n个结点、判断是否有环
24. 两两交换链表中的节点
链接: 代码随想录-24. 两两交换链表中的节点
题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
解题思路:对某个点进行操作,要先将该点前驱和后续结点保存
struct ListNode* swapPairs(struct ListNode* head){
//使用双指针避免使用中间变量
typedef struct ListNode ListNode;
ListNode *dummyhead = (ListNode *)malloc(sizeof(ListNode));
dummyhead->next = head;
ListNode* cur = dummyhead;
while(cur->next != NULL && cur->next->next != NULL ){
ListNode* tmp = cur->next; //临时保存1结点
ListNode* tmp1 = cur->next->next->next; //临时保存3结点
cur->next = cur->next->next; //指向2
cur->next->next = tmp; //2指向1;
tmp->next = tmp1; //1指向3
cur = cur->next->next; //开始下一轮
}
return dummyhead->next;//返回头结点
}
19.删除链表的倒数第N个节点
链接: 代码随想录-19.删除链表的倒数第N个节点
题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
解题思路:难点在于如何找到第n个节点
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
//定义虚拟头结点dummy,并初始化使其指向head
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->next = head;
//定义快慢指针
struct ListNode* fast = head;
struct ListNode* slow = dummy; //这样定义省去了加一操作,删除第N个结点,一定要使它的操作指针指向前一个结点
for(int i = 1;i <= n;i ++){
fast = fast->next;
}
while(fast){
fast = fast->next;
slow = slow->next;
}
//执行删除操作
slow->next = slow->next->next;
head = dummy->next;
free(dummy);
return head;
}
面试题 02.07. 链表相交
链接: 代码随想录-面试题 02.07. 链表相交
题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
解题思路:就是求两个链表交点节点的指针。 这里要注意,交点不是数值相等,而是指针相等。
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *l = NULL;
struct ListNode *s = NULL;
int lenA = 0,lenB = 0, gap = 0;
//求出两个链表的长度
s = headA;
while(s){
lenA ++;
s = s->next;
}
s = headB;
while(s){
lenB ++;
s = s->next;
}
//求出两个链表长度差
if(lenA > lenB){
l = headA, s = headB;
gap = lenA - lenB;
}else{
l = headB, s = headA;
gap = lenB - lenA;
}
//尾部对齐
while(gap --) l = l->next;
//移动,并检查是否有相同元素
while(l){
if(l == s) return l;
l = l->next,s = s->next;
}
return NULL;
}
142.环形链表II
链接: 代码随想录-142.环形链表II
题目:
解题思路:如何判断有环,快指针一次走两个结点,慢指针走一个结点,快指针相对于慢指针走一个结点,一定会追上慢指针