当前位置: 首页> 房产> 家装 > 【数据结构】——链表经典OJ(leetcode)

【数据结构】——链表经典OJ(leetcode)

时间:2025/8/23 9:20:19来源:https://blog.csdn.net/super_coders/article/details/139902956 浏览次数:0次

文章目录

  • 一、 相交链表
  • 二、 反转链表
  • 三、 回文链表
  • 四、 环形链表
  • 五、 环形链表 II
  • 六、 合并两个有序链表
  • 七、 两数相加
  • 八、 删除链表的倒数第N个节点
  • 九、 随机链表的复制

一、 相交链表

在这里插入图片描述
双指针法

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* curA = headA;struct ListNode* curB = headB;int lenA = 1,lenB = 1;while(curA->next){curA = curA->next;lenA++;}while(curB->next){curB = curB->next;lenB++;}//终点相同才能进行下一步if(curB != curA){return NULL;}//假设法//长的先走int gap = abs(lenA - lenB);struct ListNode* longlist = headA;struct ListNode* shortlist = headB;if(lenB>lenA){longlist = headB;shortlist = headA;}while(gap--){longlist = longlist->next;}while(shortlist != longlist){shortlist = shortlist->next;longlist = longlist->next;}return shortlist;
}

二、 反转链表

在这里插入图片描述

注意第一个节点的next要为空

 typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {if(head == NULL){return head;}ListNode* n1,* n2, *n3;n1 = NULL;n2 = head;n3 = n2->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3){n3 = n3->next;}} return n1;}

三、 回文链表

在这里插入图片描述
这题两个选择,反转前半部分再对比,或者反转后半部分再对比
如果反转前半部分,那么找中间值的条件就为fast->next && fast->next->next不为空,我选择反转后半部分,相对更容易理解
反转的部分参考反转链表

 typedef struct ListNode ListNode;ListNode* reverse(ListNode* head){if(head == NULL){return head;}ListNode* n1,* n2, *n3;n1 = NULL;n2 = head;n3 = n2->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3){n3 = n3->next;}} return n1;}
bool isPalindrome(struct ListNode* head) {//先找到中间节点ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}//反转后一半节点ListNode* p = reverse(slow);ListNode* q = head;//对比while(q != slow){if(q->val != p->val)return false;q = q->next;p = p->next;}return true;
}

四、 环形链表

在这里插入图片描述
快慢指针:用fast先走,等fast进圈后再去追slow

bool hasCycle(struct ListNode *head) {typedef struct ListNode ListNode;ListNode* slow = head;ListNode* fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(fast == slow){return true;}}return false;
}

五、 环形链表 II

在这里插入图片描述
先看代码,这题的代码很简单,但是要明白所以然

 typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {ListNode* fast = head;ListNode* slow = head;;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast){ListNode* meet = slow;while(head != meet){head = head->next;meet = meet->next;}return head;}}return NULL;
}

在这里插入图片描述
当fast和slow相遇后,我们将meet点设为新的起点,然后head点和meet点往后走,终究会相遇,相遇的点就是环的入口。
在这里插入图片描述

六、 合并两个有序链表

在这里插入图片描述
这题需要注意返回新链表的头节点,所以新链表创建两个节点来记录头和尾节点最方便

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {ListNode* l1 = list1;ListNode* l2 = list2;//判断链表为空if(l1 == NULL){return l2;}if(l2 == NULL){return l1;}//创建新的链表ListNode* newhead,* newtail;newhead = newtail = (ListNode*)malloc(sizeof(ListNode));while(l1 && l2){if(l1->val < l2->val){   //l1尾插newtail->next = l1  ;newtail = newtail->next;l1 = l1->next;}else{  //l2尾插newtail->next = l2;newtail = newtail->next;l2 = l2->next;}}//跳出循环后还有两种情况,不是l1走到空,就是l2先走到空if(l1){newtail->next = l1;}if(l2){newtail->next = l2;}//手动释放动态内存空间ListNode* ret = newhead->next;free(newhead);newhead = NULL;return ret;
}

七、 两数相加

在这里插入图片描述
这题使用递归的方法最好理解

 typedef struct ListNode ListNode;
ListNode* _addTwoNumbers(ListNode* l1,ListNode* l2,int cur)
{int sums = cur;if(l1 == NULL && l2 == NULL && cur == 0){return NULL;}else{if(l1 != NULL){sums += l1->val;l1 = l1->next;}if(l2 != NULL){sums += l2->val;l2 = l2->next;}}ListNode* a = (ListNode*)malloc(sizeof(ListNode));a->val = sums%10;a->next = _addTwoNumbers(l1,l2,sums/10);return a;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {return _addTwoNumbers(l1,l2,0);
}

cur为进位值,所以和就为l1->val+l2->val+cur
在这里插入图片描述
判断cur是防止极端情况的发生,例如:
在这里插入图片描述

八、 删除链表的倒数第N个节点

在这里插入图片描述

先记录链表长度,再找到要删除节点的上一个节点

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {int length = 1;struct ListNode* p = head;struct ListNode* q = head;//记录链表长度while(p->next){p = p->next;length++;}int del = length - n + 1;int j = 1;//找到要删除节点的上一个节点while(j + 1 < del){q = q->next;j++;}if(del != 1){q->next = q->next->next;return head;}else{return head = q->next;}}

九、 随机链表的复制

在这里插入图片描述
创建一个copy链表

在这里插入图片描述

在这里插入图片描述
再控制random
在这里插入图片描述
把copy取出尾插为新的链表(恢复原链表)
在这里插入图片描述
源代码:

typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {Node* cur = head;//创建copy链表while(cur){Node* copy = (Node*)malloc(sizeof(Node));copy->val = cur->val;copy->next = cur->next;cur->next = copy;cur = copy->next;}//完善random cur = head;   while(cur){Node* copy = cur->next;if(cur->random == NULL){copy->random = NULL;}else{copy->random = cur->random->next;}cur = copy->next;}//copy取出尾插成为新的链表cur = head;Node* copyhead = NULL;Node* copytail = NULL;while(cur){Node* copy = cur->next;Node* next = copy->next;if(copyhead == NULL){copyhead = copytail = copy;}else{copytail->next = copy;copytail = copy;}//cur->next = next;cur = next;next = copy->next;}return copyhead;
}
关键字:【数据结构】——链表经典OJ(leetcode)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: