剑指Offer-链表篇(牛客网)

文章详细介绍了C语言中针对链表进行的操作,包括从尾到头打印、链表反转、合并两个排序链表、求公共节点、查找环的入口、倒数第K个节点以及复杂链表的复制和删除重复节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、JZ6-从头打印链表

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param listNode ListNode类 
 * @return int整型一维数组
 * @return int* returnSize 返回数组行数
 */
 
int* printListFromTailToHead(struct ListNode* listNode, int* returnSize )
{
    int* arr = malloc(40000);
    *returnSize = 0;
     
    while(listNode)
    {
        arr[(*returnSize)++] = listNode->val;
        listNode = listNode->next;
    }
     
    for(int i=0; i<*returnSize/2; i++)
    {
        int tmp = arr[i];
        arr[i] = arr[*returnSize - i -1];
        arr[*returnSize - i -1] = tmp;
    }
    
    return arr;
}

2、JZ24-反转链表

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
​
/**
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
struct ListNode* ReverseList(struct ListNode* pHead ) 
{
    struct ListNode *n1 = NULL , *n2 = pHead;
    
    while(NULL != n2)
    {
        struct ListNode* n3 = n2->next;
        n2->next = n1;
        n1 = n2;
        n2 = n3;
    }
    return n1;
}
//单链表逆序//第二种方式
ListNode tmp_head={};
while(NULL!=head)
{
    ListNode* node=head;
    head=head->next;
    
    node->next=tmp_head.next;
    tmp_head.next=node;
}
return tmp_head.next;

3、JZ25-合并两个排序的链表

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
​
/**
 * 
 * @param pHead1 ListNode类 
 * @param pHead2 ListNode类 
 * @return ListNode类
 */
struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) 
{
    struct ListNode temp;
    struct ListNode* tail = &temp;
    
    while(NULL!=pHead1 && NULL!=pHead2)
    {
        if(pHead1->val < pHead2->val)
        {
            tail->next = pHead1;
            pHead1 = pHead1->next;
        }
        else
        {
            tail->next = pHead2;
            pHead2 = pHead2->next;
        }
        tail = tail->next;
    }
    
    tail->next = NULL==pHead1 ? pHead2 : pHead1;
    return temp.next;
}

4、JZ5-求两个链表的第一个公共结点

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
​
/**
 * 
 * @param pHead1 ListNode类 
 * @param pHead2 ListNode类 
 * @return ListNode类
 */
int lengthList(struct ListNode* pHead)
{
    int len = 0;
    while(NULL != pHead)
    {
        pHead = pHead->next;
        len++;
    }
    return len;
}
​
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) 
{
    int len1 = lengthList(pHead1);
    int len2 = lengthList(pHead2);
    int n = abs(len1-len2);
    
    while(n--)
    {
        if(len1 > len2)
            pHead1 = pHead1->next;
        else
            pHead2 = pHead2->next;
    }
    
    while(NULL!=pHead1 && NULL!=pHead2)
    {
        if(pHead1 == pHead2)
            return pHead1;
        pHead1 = pHead1->next;
        pHead2 = pHead2->next;
    }
    return NULL;
}

5、JZ23-链表中环的入口结点

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) 
{   
    struct ListNode* node = pHead->next;
    while(NULL != node)
    {
        struct ListNode* in = pHead;
        do{
            if(in == node->next)
                return in;
            in = in->next;
        }while(in != node);
        node = node->next;
    }
    return NULL;
}

6、JZ22-链表中倒数第K个结点

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) 
{
    struct ListNode* n1 = pHead;
    for(int i=0; i<k; i++)
    {
        if(NULL == n1)
            return NULL;
        n1 = n1->next;
    }
    
    struct ListNode* n2 = pHead;
    while(NULL!=n1 && NULL!=n2)
    {
        n1 = n1->next;
        n2 = n2->next;
    }
    
    return n2;
}

7、JZ35-复杂链表的复制

/**
 * struct RandomListNode {
 *  int label;
 *  struct RandomListNode *next;
 *  struct RandomListNode *random;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead RandomListNode类 
 * @return RandomListNode类
 */
#include <stdio.h>
#include <stdlib.h>
​
struct RandomListNode* Clone(struct RandomListNode* pHead) 
{
    if(NULL == pHead)
        return NULL;
​
    struct RandomListNode *node = pHead, *copy = NULL;
    
    while(NULL != node)
    {
        copy = malloc(sizeof(struct RandomListNode));
        copy->label = node->label;
        copy->next = node->next;
        node->next = copy;
        node = copy->next;
    }
​
    struct RandomListNode* head = pHead->next;
​
    node = pHead;
    while(NULL != node)
    {
        copy = node->next;
        if(node->random)
            copy->random = node->random->next;
        else
            copy->random = NULL;
        node = copy->next;
    }
​
    node = pHead;
    while(NULL != node->next)
    {
        copy = node->next;
        node->next = copy->next;
        node = copy;
    }
​
    return head;
}

8、JZ76-删除链表中重复的结点

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
​
struct ListNode* delete_value_list(struct ListNode* pHead,int val)
{
    struct ListNode tmp = {0,pHead};
    struct ListNode* prev = &tmp;
    
    while(NULL != prev->next)
    {
        if(val == prev->next->val)
        {
            struct ListNode* node = prev->next;
            prev->next = node->next;
            free(node);
        }
        else 
            prev = prev->next;
    }
    return tmp.next;
}
​
struct ListNode* deleteDuplication(struct ListNode* pHead ) 
{
    char flags[1001] = {};
​
    for(struct ListNode* n=pHead; n!=NULL; n=n->next)
    {
        flags[n->val]++;
    }
​
    for(int i=0; i<1001; i++)
    {
        if(flags[i] > 1)
        {
            pHead = delete_value_list(pHead, i);
        }
    }
​
    return pHead;
}

9、JZ18-删除链表的结点

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param val int整型 
 * @return ListNode类
 */
struct ListNode* deleteNode(struct ListNode* head, int val ) 
{
    struct ListNode* prev = head;
    while(NULL != prev->next)
    {
        if(prev->next->val == val)
        {
            struct ListNode* tmp = prev->next;
            prev->next = tmp->next;
            free(tmp);
        }
        prev = prev->next;
    }
​
    if(head->val == val)
    {
        struct ListNode* tmp = head;
        head = head->next;
        free(tmp);
    }
​
    return head;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值