题目来源于:牛客网->题目链接
输入一个链表,输出该链表中倒数第k个结点。
示例:
输入:1,{1,2,3,4,5}
返回值:{5}
①:返回指针:ret.
②:后指针:tail
特殊情况:
pListHead=NULL和K不合法.
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) { if(pListHead==NULL||(k<=0))//如果为空链表或者k是<=0,直接返回NULL { return NULL; } struct ListNode*ret=pListHead; struct ListNode*tail=pListHead; //后指针先走k-1步 while((--k)&&tail)//细节,k--和--k的区别 { tail=tail->next; } //k太大 if (tail == NULL)//如果指向的就是最后一个节点的后的NULL,即k太大 { return NULL; } //两个指针一起走 while(tail->next!=NULL) { tail=tail->next; ret=ret->next; } return ret; }
题目来源于:力扣->题目链接
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例1:
输入:
l1 = [1,2,4], l2 = [1,3,4]
输出:
[1,1,2,3,4,4]
可以创建一个头结点,头结点在链表为空等特殊情况时不需要调整头指针,因为即使链表为空,也还有头结点,只需要将头结点的next置空即可.
步骤:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) { //创建带哨兵卫的结点 struct ListNode* phead = (struct ListNode*)malloc(sizeof(struct ListNode)); phead->next = NULL; struct ListNode* ret = phead;//保存这个哨兵卫结点 while (list1 && list2) { if (list1->val < list2->val)//谁小谁尾插 { phead->next = list1; phead = phead->next; list1=list1->next; } else { phead->next = list2; phead = phead->next; list2=list2->next; } } //如果一方为空的情况 if (list1 == NULL) { phead->next = list2; } if (list2 == NULL) { phead->next = list1; } return ret->next;//哨兵卫结点的next }
题目来源于:牛客网->题目链接
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
示例:
①:SmallHead:用于保存比目标值小的结点.
②:BigHead:用于保存比目标值大的结点.
①:SmallTail
②:BigTail
小于目标值x尾插入SmallHead小链表.
大于等于==目标值x,尾插入BigHead大链表.
注意:这里需要注意的是大链表(BigHead)的尾结点不一定是原有链表的尾结点,即大链表(BigHead)的尾结点不一定为NULL,我们要手动设置为NULL,否则链表无法结束.
图解:
特殊情况:
代码:
class Partition { public: ListNode* partition(ListNode* pHead, int x) { //创建两个链表的头结点 ListNode* SmallHead=(ListNode*)malloc(sizeof(ListNode)); ListNode* BigHead=(ListNode*)malloc(sizeof(ListNode)); //代替两个头结点遍历的指针 ListNode* SmallTail= SmallHead; ListNode* BigTail= BigHead; //遍历现有链表 while(pHead) { //小的尾插到小的链表中 if(pHead->val<x) { SmallTail->next=pHead; SmallTail=SmallTail->next; } else {//大的尾插到大的链表中 BigTail->next=pHead; BigTail=BigTail->next; } pHead=pHead->next; } //链接 SmallTail->next=BigHead->next; //大链表的尾结点不一定是NULL,我们要置NULL BigTail->next=NULL; //保留要返回的头指针 pHead=SmallHead->next; //释放自己动态内存申请的空间 free(SmallHead); free(BigHead); return pHead; } };
题目来源于:牛客网->题目链接
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构(从前往后,和从后往前遍历结果一样)。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
示例1:
输入:
1->2->2->1
输出;
true
示例2:
输入:
1->2->3->2->1
输出:
true
将链表的后半段逆序,然后与前半段一次比较,都一样则是回文结构,不一样则不是回文结构.
不相同:则返回false
相同:则返回true
链表中间结点与链表逆置在这篇文章->传送门
图解:
代码:
class PalindromeList { public: bool chkPalindrome(ListNode* A) { //寻找中间结点 ListNode* mid=middleNode(A); //反转链表后半段 ListNode* B=reverseList(mid); //比较 while(A&&B) { if(A->val!=B->val) { return false; } A=A->next; B=B->next; } return true; } };
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者