代码随想录算法训练营第4天| 24. 两两交换链表中的节点 | 19.删除链表的倒数第N个节点 |面试题 02.07. 链表相交| 142.环形链表II
| 206.反转链表
-
- 两两交换链表中的节点
用虚拟头结点。
题目链接/文章讲解/视频讲解:
https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html
/**
1. Definition for singly-linked list.
2. struct ListNode {
3. int val;
4. struct ListNode *next;
5. };
*/
struct ListNode* swapPairs(struct ListNode* head) {
typedef struct ListNode ListNode;
ListNode *dummyhead=(ListNode *)malloc(sizeof(ListNode));
dummyhead->next=head;
ListNode *p;
p=dummyhead;
ListNode *temp;
ListNode *temp1;
while(p->next !=NULL&&p->next->next!=NULL)
{
temp=p->next;
temp1=p->next->next->next;
p->next=p->next->next;
p->next->next=temp;
p->next->next->next=temp1;
p=p->next->next;
}
return dummyhead->next;
}
总结
- 19.删除链表的倒数第N个节点
双指针的操作,要注意,删除第N个节点,当前遍历的指针一定要指向 第N个节点的前一个节点。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0019.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9.html
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
typedef struct ListNode ListNode;
ListNode *dummyhead;
dummyhead=(ListNode *)malloc(sizeof(ListNode));
dummyhead->val=0;
dummyhead->next=head;
ListNode *front=dummyhead;
ListNode *slow=dummyhead;
int t=n;
t++;
while(front->next!=NULL&&--t)
{
front=front->next;
}
while(front->next!=NULL&&slow!=NULL)
{
front=front->next;
slow=slow->next;
}
ListNode *temp=slow->next;
slow->next=slow->next->next;
free(temp);
return dummyhead->next;
}
总结
面试题 02.07. 链表相交
题目链接/文章讲解:https://programmercarl.com/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4.html
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
typedef struct ListNode ListNode;
ListNode *l = NULL, *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;
}
总结
我解题也是同思路但是leetcode一直说我超时,没头绪,我就把答案cv上去了,里面题目是地址相同,并不是数值相同,所以指针eg:l==s就行。
- 142.环形链表II
算是链表比较有难度的题目,需要多花点时间理解 确定环和找环入口。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
typedef struct ListNode ListNode;
ListNode *fast = head, *slow = head;
/* while (fast && fast->next) {
// 这里判断两个指针是否相等,所以移位操作放在前面
slow = slow->next;
fast = fast->next->next;
if (slow == fast) { // 相交,开始找环形入口:分别从头部和从交点出发,找到相遇的点就是环形入口
ListNode *f = fast, *h = head;
while (f != h) f = f->next, h = h->next;
return h;
}
}
return NULL;*/
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
ListNode *p=head, *q=fast;
while(p!=q)
{
p=p->next;
q=q->next;
}
return p;
}
}
return NULL;
}
总结