链表
203. 移除链表元素 - 力扣(LeetCode)
https://leetcode.cn/problems/remove-linked-list-elements/description/
主要就是遍历链表看是否有和val值相同的元素,有就记录,链表重新连接,free节点的操作
先处理头节点 你先单独用 while 循环把所有值等于 val 的头节点删掉,避免了后续逻辑中头节点的特殊处理,就比较简单,不做过多赘述

cpp
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* newhead=NULL;
while(head&&head->val==val)
{
struct ListNode* del=head;
head=head->next;
free(del);
}
newhead=head;
struct ListNode* cur=newhead;
while(cur&&cur->next)
{
if(cur->next->val==val)
{
struct ListNode* del=cur->next;
cur->next=del->next;
free(del);
}
else
{
cur=cur->next;
}
}
return newhead;
}
206. 反转链表 - 力扣(LeetCode)
https://leetcode.cn/problems/reverse-linked-list/description/
主要就是头插和指针的移动
定义一个节点为NULL
一个节点为cur用来遍历链表
一个节点为next来记录下一个指针,不会找不到下一个节点
然后循环链表,先让next记录cur的下一个指针,然后在cur头插到newhead
最后更新newhead和cur

cpp
struct ListNode* reverseList(struct ListNode* head) {
//核心逻辑就是头插
struct ListNode*newhead=NULL;
struct ListNode*cur=head;
while(cur)
{
struct ListNode*next=cur->next;
cur->next=newhead;
newhead=cur;
cur=next;
}
return newhead;
}
21. 合并两个有序链表 - 力扣(LeetCode)
https://leetcode.cn/problems/merge-two-sorted-lists/description/
这道题解题思路比较简单,就是将每个表中相对较小的节点尾插,最终会形成一个不减的链表,注意的是当链表为空的情况,我们线确定头节点的位置,先来一组比较,然后接下来依次进行即可

cpp
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode* cur1=list1;
struct ListNode* cur2=list2;
if(cur1==NULL)
return cur2;
if(cur2==NULL)
return cur1;
struct ListNode* cur=cur1;
struct ListNode* newhead=NULL;
if(cur1->val<=cur2->val)
{
cur=cur1;
cur1=cur1->next;
}
else
{
cur=cur2;
cur2=cur2->next;
}
newhead=cur;
while(cur1&&cur2)
{
if(cur1->val<=cur2->val)
{
cur->next=cur1;
cur=cur->next;
cur1=cur1->next;
}
else
{
cur->next=cur2;
cur=cur->next;
cur2=cur2->next;
}
}
if(cur1)
cur->next=cur1;
else
cur->next=cur2;
return newhead;
}
160. 相交链表 - 力扣(LeetCode)
https://leetcode.cn/problems/intersection-of-two-linked-lists/description/
代码执行流程 首先通过遍历分别统计链表A与链表B的结点总长度,计算两条链表的长度差值。
依据长度差值,使更长链表的指针先向前移动对应差值步数,抵消两条链表的长度差距,此时两个指针后续待遍历的链表剩余长度完全相同。
之后两个指针从各自当前位置同步向后逐个遍历,若过程中两个指针指向同一个结点,则该结点就是链表相交起始结点,直接返回该结点;若遍历结束指针始终不重合,代表链表没有相交结点,返回空指针。
两条单链表相交时,相交结点往后的全部结点为两条链表共用,因此相交段长度完全一致。长链表提前走完多出的结点后,两个指针剩余需要遍历的结点数量相等,同步前进的过程里,有交点就必然在相交起始位置相遇,无交点则会同步走到链表尾部空地址,依靠该规律即可精准定位相交节点。

cpp
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
int lenA=0;
int lenB=0;
struct ListNode *cur=headA;
struct ListNode *curA=headA;
struct ListNode *curB=headB;
while(cur)
{
lenA++;
cur=cur->next;
}
cur=headB;
while(cur)
{
lenB++;
cur=cur->next;
}
int gap=0;
if(lenA>=lenB)
{//说明a链表long
gap=lenA-lenB;
cur=headA;
while(gap--)
{
cur=cur->next;
}
curA=cur;
while(curA&&curB&&curA!=curB)
{
curA=curA->next;
curB=curB->next;
}
if(curA==curB)
return curA;
else
return NULL;
}
else
{
gap=lenB-lenA;
cur=headB;
while(gap--)
{
cur=cur->next;
}
curB=cur;
while(curA&&curB&&curA!=curB)
{
curA=curA->next;
curB=curB->next;
}
if(curA==curB)
return curA;
else
return NULL;
}
}