目录
链表中倒数第k个结点
题目
思路
代码
CM11 链表分割
题目
思路
代码
LCR 027.回文链表
题目
思路
代码
链表中倒数第k个结点
链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)
https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&&tqId=11167&rp=2&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目
输入一个链表,输出该链表中倒数第k个结点。
示例:
输入:1,{1,2,3,4,5}
返回值:{5}
思路
创建两个结构体指针fast和slow指向头节点,先让fast往后遍历,fast通过while循环先走k步后停止,fast和slow同时走,当fast为NULL时,slow所在位置就是倒数第k个。
图示如下👇

代码
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    struct ListNode* fast=pListHead,* slow=pListHead;
    while(fast)
    {         
        fast=fast->next;
        k--;
        if(k<0)
        slow=slow->next;
    }
    if(k>0)
    { 
     return NULL;
    }
    return slow;  
} 
 
CM11 链表分割
链表分割_牛客题霸_牛客网 (nowcoder.com)
https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking
题目
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
示例:
输入:{1,2,3,5,1}
返回值:{1,2,1,3,5}
思路
定义两个哨兵节点,将原链表中节点值大于x和小于x的分别接入两个哨兵节点后,再将大于x的链表去掉哨兵节点后接到小于x的链表后面,要注意的是,记得将新链表最后一个节点置空,不然容易成环。
图示如下👇

代码
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* ghead,*gtail,*lhead,*ltail;
        ghead=gtail=(struct ListNode*)malloc(sizeof(struct ListNode));
        lhead=ltail=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* cur=pHead;
        while(cur)
        {
            if(cur->val<x)
            {
                gtail->next=cur;
                gtail=gtail->next;
            }
            else
            {
                ltail->next=cur;
                ltail=ltail->next;
            }
            cur=cur->next;
        }
        gtail->next=lhead->next;
        ltail->next=NULL;
        struct ListNode* head=ghead->next;
        free(lhead);
        free(ghead);
        return head;
    }
}; 
 
LCR 027.回文链表
 LCR 027. 回文链表
https://leetcode.cn/problems/aMhZSa/
题目
给定一个链表的 头节点
head,请判断其是否为回文链表。如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
示例:

思路
判断链表是否是回文结构,我们可以先找出中间节点mid,从中间节点开始后半段逆置处理,得到新的中间节点rmid,我们可以从整个链表头节点head和rmid开始遍历比较head->val和rmid->val是否相等,若直到rmid->next==NULL时均相等,则为回文结构返回true,反之则直接跳出遍历循环,返回false。
由于代码过长,为了代码更加条理和简洁,找出中间节点和逆置的步骤,我们可以用包装函数的方法实现。

代码
//找中间节点
struct ListNode* middleNode(struct ListNode* head) {
    struct ListNode* slow = head, *fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
//逆置
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* cur = head;
    struct ListNode* newhead = NULL;
    while (cur) {
        //保存下一节点
        struct ListNode* next = cur->next;
        //头插
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    return newhead;
}
bool isPalindrome(struct ListNode* head){
    struct ListNode* mid=middleNode(head);
    struct ListNode* rmid=reverseList(mid);
    while(head&&rmid)
    {
        if(head->val!=rmid->val)
        {
            return false;
        }
        head=head->next;
        rmid=rmid->next;
    }
    return true;
}
                


















