🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:分析力扣中有关链表的部分题目.
题目来源于:牛客网->题目链接
输入一个链表,输出该链表中倒数第k个结点。
示例:
输入:1,{1,2,3,4,5} 返回值:{5}
特殊情况:
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
SmallHead小链表.
大于等于==目标值x,尾插入BigHead大链表.
BigHead)的尾结点不一定是原有链表的尾结点,即大链表(BigHead)的尾结点不一定为NULL,我们要手动设置为NULL,否则链表无法结束.
malloc手动申请的,c语言阶段,需要我们自己手动释放,释放前记得保存要返回的头指针哦.
图解:

特殊情况:

代码:
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
将链表的后半段逆序,然后与前半段一次比较,都一样则是回文结构,不一样则不是回文结构.
链表中间结点与链表逆置在这篇文章->传送门
图解:

代码:
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;
}
};本文主要记录牛牛学习链表时刷题记录,希望这篇文章对大家有帮助。欢迎小伙伴们私信提意见和提问哦! 最后,小伙伴们的点赞就是给牛牛最大的支持,能不能给牛牛来一个一键三连呢?谢谢支持。