【题目集2】链表经典题目
创始人
2024-04-08 06:26:51

文章目录

        • 移除链表元素
        • 合并两个有序链表
        • 链表的中间节点
        • 链表中的倒数第k个结点
        • 反转链表
        • 链表分割
        • 链表的回文结构
        • 相交链表
        • 环形链表
        • 环形链表II(找到如环的节点)
        • 复制带随机指针的链表

移除链表元素

image-20221107152834165

思路:先要判断这个链表是不是空链表,如果是空链表就直接返回NULL,就可以

代码:

struct ListNode* removeElements(struct ListNode* head, int val){if(head == NULL){return NULL;}struct ListNode* cur = head;struct ListNode* newnode, *tail;newnode = tail = NULL;while(cur != NULL){if(cur->val != val){if(tail == NULL){newnode = tail = cur;}else {tail->next = cur;tail = tail->next;}cur = cur->next;}else{struct ListNode* next = cur->next;free(cur);cur = next;}}if(tail){tail->next = NULL;}return newnode;
}

注意:这个题最后需要注意的是tail的下一个应该也是NULL,否则就有可能将最后一个链表连接。

image-20221107153412182

合并两个有序链表

image-20221107161447520

思路:重新用一个新的链表头来表示节点,如果小于的数就加入到链表当中。

代码:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){if(list1 == NULL) {return list2;}if(list2 == NULL) {return list1;}struct ListNode* head, *tail;head = tail = NULL;while(list1 && list2) {if(list1->val < list2->val) {if(tail == NULL) {head = tail = list1;}else {tail->next = list1;tail = tail->next;}list1 = list1->next;}else {if(tail == NULL) {head = tail = list2;}else {tail->next = list2;tail = tail->next;}list2 = list2->next;}}if(list1) {tail->next = list1;}if(list2) {tail->next = list2;}return head;
}

链表的中间节点

image-20221108153220143

思路:这个题目只需要根据速度差,一个指针的速度是另一个指针速度的二倍,当快的指针到达终点的时候,慢指针刚好到达中间节点。

代码:

struct ListNode* middleNode(struct ListNode* head){struct ListNode *fast, *slow;fast = slow = head;while(fast && fast->next) {slow = slow->next;fast = fast->next->next;}return slow;
}

链表中的倒数第k个结点

image-20221108154323978

思路:先让快的链表走k步,然后两个指针一起往后移动,如果快的指针到达最后,慢的指针就是最后的结果。

代码:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code herestruct ListNode *fast, *slow;fast = slow = pListHead;while(k) {if(fast == NULL) {return NULL;}fast = fast->next;k --;}while(fast) {fast = fast->next;slow = slow->next;}return slow;
}

反转链表

image-20221111173758852

image-20221111173913597

代码:

struct ListNode* reverseList(struct ListNode* head){if(head == NULL) {return NULL;}struct 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;
}

链表分割

image-20221112155443108

对于最后一个数字,还有不同的情况考虑:

image-20221112155805638

代码:

class Partition {
public:ListNode* partition(ListNode* pHead, int x) {// write code herestruct ListNode* lessHead, *lessTail, *greaterHead, *greaterTail;lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));lessTail->next = greaterTail->next = NULL;struct ListNode* cur = pHead;while(cur) {if(cur->val < x) {lessTail->next = cur;lessTail = lessTail->next;}else {greaterTail->next = cur;greaterTail = greaterTail->next;}cur = cur->next;}lessTail->next = greaterHead->next;greaterTail->next = NULL;pHead = lessHead->next;free(lessHead);free(greaterHead);return pHead;}
};

链表的回文结构

image-20221114151032185

思路:直接找到中间节点,然后反转中间节点到最后的链表就可以。

代码:

struct ListNode* findMid(struct ListNode* A) {struct ListNode* slow = A, *fast = A;while(fast && fast->next) {slow = slow->next;fast = fast->next->next;}return slow;
}struct ListNode* reverse(struct ListNode* mid) {struct ListNode* n1 = NULL, *n2 = mid, *n3 = n2->next;while(n2) {n2->next = n1;n1 = n2;n2 = n3;if(n3) {n3 = n3->next;}}return n1;
}class PalindromeList {
public:bool chkPalindrome(ListNode* A) {// write code herestruct ListNode* mid = findMid(A);struct ListNode* rhead = reverse(mid);while(A && rhead) {if(A->val != rhead->val) {return false;}A = A->next;rhead = rhead->next;}return true;}
};

相交链表

image-20221114152805524

思路:找到两个其中长的一个链表,然后走差值步,一起走看是否有相等的地址。

代码:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* curA = headA, *curB = headB;int lenA = 0, lenB = 0;//分别找到链表A和链表B的长度while(curA) {lenA ++;curA = curA->next;}while(curB) {lenB ++;curB = curB->next;}//如果最后不相等,则绝对不存在公共节点//如果相等,则一定存在公共节点if(curA != curB) {return NULL;}int gap = abs(lenA - lenB);//假设A>Bstruct ListNode* LongList = headA, *ShortList = headB;if(lenB > lenA) {LongList = headB;ShortList = headA;}while(gap --) {LongList = LongList->next;}while(LongList != ShortList) {LongList = LongList->next;ShortList = ShortList->next;}return LongList;
}

环形链表

image-20221114153632036

思路:两个指针,一个指针每次跑一步,另一个指针每次跑两步,如果有环两个指针肯定能够相遇。

代码:

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

image-20221114154758953

环形链表II(找到如环的节点)

image-20221114155737474

image-20221114155742679

结论:让一个指针从链表的起始位置开始遍历链表,同时让一个指针从判环相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。

代码:

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

复制带随机指针的链表

image-20221114163044019

思路:

  1. 拷贝节点在源节点的后面

image-20221114164111905

代码实现:

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while(cur) {struct Node* next = cur->next;struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;cur->next = copy;copy->next = next;cur = next;}
}
  1. 设置拷贝节点的random

image-20221114164648509

代码实现:

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while(cur) {struct Node* next = cur->next;struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;cur->next = copy;copy->next = next;cur = next;}//设置拷贝节点的randomcur = head;while(cur) {struct Node* copy = cur->next;if(cur->next == NULL) {copy->random = NULL;}else {copy->random = cur->random->next;}cur = cur->next->next;}
}
  1. 拷贝节点解下来,连接组成拷贝链表

代码实现:

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while(cur) {struct Node* next = cur->next;struct Node* copy = (struct Node*)malloc(sizeof(struct Node));copy->val = cur->val;cur->next = copy;copy->next = next;cur = next;}cur = head;while(cur) {struct Node* copy = cur->next;if(cur->random == NULL) {copy->random = NULL;}else {copy->random = cur->random->next;}cur = cur->next->next;}cur = head;struct Node* copyHead = NULL, *copyTail = NULL;while(cur) {struct Node* copy = cur->next;struct Node* next = copy->next;cur->next = next;if(copyTail == NULL) {copyHead = copyTail = copy;}else {copyTail->next = copy;copyTail = copyTail->next;}cur = next;}return copyHead;
}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...