【数据结构】链表--OJ

目录

[1 移除链表元素](#1 移除链表元素)

[2 链表的中间节点](#2 链表的中间节点)

[3 合并两个有序链表](#3 合并两个有序链表)

[4 反转链表](#4 反转链表)

[5 回文链表](#5 回文链表)

[6 链表中第K个节点](#6 链表中第K个节点)

[7 链表分割](#7 链表分割)

[8 相交链表](#8 相交链表)

[9 环形链表](#9 环形链表)

[10 随机链表的复制](#10 随机链表的复制)


1 移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode* tail = head;
    struct ListNode* prev = head;
    while (tail)
    {
        if (tail->val == val)
        {
            if (tail == head)
            {
                head = tail->next;
                free(tail);
                tail = head;
            }
            else
            {
                struct ListNode* next = tail->next;
                prev->next = next;
                free(tail);
                tail = next;
            }

        }
        else
        {
            prev = tail;
            tail = tail->next;
        }
    }


    return head;

}

2 链表的中间节点

876. 链表的中间结点 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* middleNode(struct ListNode* head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;

}

3 合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    if (list1 == NULL)
    {
        return list2;
    }
    if (list2 == NULL)
    {
        return list1;
    }
    struct ListNode* head = NULL, * tail = NULL;
    //带哨兵位
    head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    //将大的不断尾插到新链表中
    while (list1 && list2)
    {
        if (list1->val < list2->val)
        {
            tail->next = list1;
            list1 = list1->next;
            tail = tail->next;
        }
        else
        {
            tail->next = list2;
            list2 = list2->next;
            tail = tail->next;
        }
    }
    if (list1)
    {
        tail->next = list1;
    }
    if (list2)
    {
        tail->next = list2;
    }
    struct ListNode* newhead = head->next;
    free(head);
    head = newhead;
    return head;
}

4 反转链表

206. 反转链表 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* newhead = NULL;
    struct ListNode* cur = head;
    while(cur)
    {
        struct ListNode* next = cur->next;
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    return newhead;

}

5 回文链表

LCR 027. 回文链表 - 力扣(LeetCode)

cpp 复制代码
//找中间节点
struct ListNode* middlenode(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}


//将中间节点后面的链表进行逆序
struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* newhead = NULL;
    struct ListNode* tail = head;
    while (tail)
    {
        struct ListNode* next = tail->next;
        tail->next = newhead;
        newhead = tail;
        tail = next;
    }
    return newhead;
}

bool isPalindrome(struct ListNode* head) {
    struct ListNode* newhead = middlenode(head);
    struct ListNode* node = reverseList(newhead);

    //两个链表进行比较
    while (head && node)
    {
        if (head->val != node->val)
        {
            return false;
        }

        head = head->next;
        node = node->next;

    }
    return true;
}

6 链表中第K个节点

链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

cpp 复制代码
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k) {
    // write code here
    struct ListNode* slow = pListHead;
    struct ListNode* fast = pListHead;
    while (k)
    {
        if (fast == NULL)
        {
            return NULL;
        }
        fast = fast->next;
        k--;
    }

    while (fast)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

7 链表分割

面试题 02.04. 分割链表 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* partition(struct ListNode* head, int x) {
    if (head == NULL)
    {
        return NULL;
    }
    struct ListNode* ihead, * itail, * ghead, * gtail;

    ihead = itail = (struct ListNode*)malloc(sizeof(struct ListNode));
    ghead = gtail = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* cur = head;
    itail->next = NULL;
    gtail->next = NULL;
    while (cur)
    {
        if (cur->val < x)
        {
            itail->next = cur;
            itail = itail->next;
        }
        else
        {
            gtail->next = cur;
            gtail = gtail->next;
        }
        cur = cur->next;
    }

    itail->next = ghead->next;
    gtail->next = NULL;
    struct ListNode* newhead = ihead->next;
    free(ihead);
    free(ghead);
    head = newhead;
    return head;

}

创建两个带头链表 小于x的不断尾插的到链表1 大于x的不断尾插到链表2

8 相交链表

160. 相交链表 - 力扣(LeetCode)

cpp 复制代码
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
    struct ListNode* curA = headA;
    struct ListNode* curB = headB;
    int lenA = 0, lenB = 0;
    while (curA)
    {
        curA = curA->next;
        lenA++;
    }
    while (curB)
    {
        curB = curB->next;
        lenB++;
    }

    if (curA != curB)//如果两个链表都为空 就会进来 虽然两个指针都指向空指针 但是不是同一个指针
    {
        return NULL;
    }
    int k = abs(lenA - lenB);
    if (lenA < lenB)
    {
        while (k--)
        {
            headB = headB->next;
        }
    }
    else
    {
        while (k--)
        {
            headA = headA->next;
        }
    }

    while (headA != headB)
    {
        headA = headA->next;
        headB = headB->next;
    }
    return headA;

}

9 环形链表

141. 环形链表 - 力扣(LeetCode)

cpp 复制代码
bool hasCycle(struct ListNode* head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            struct ListNode* meet = slow;
            while (meet != head)
            {
                meet = meet->next;
                head = head->next;
            }
            if (meet == head)
            {
                return true;
            }
        }
    }
    return false;
}

还有一种方法:

cpp 复制代码
bool GetSameNode(struct ListNode* headA, struct ListNode* headB)
{
    struct ListNode* tailA = headA;
    struct ListNode* tailB = headB;
    int lenA = 1, lenB = 1;
    while (tailA)
    {
        tailA = tailA->next;
        lenA++;
    }
    while (tailB)
    {
        tailB = tailB->next;
        lenB++;
    }
    if (tailA != tailB)
    {
        return NULL;
    }
    int k = abs(lenA - lenB);
    if (lenA < lenB)
    {
        while (k--)
        {
            headB = headB->next;
        }
    }
    else
    {
        while (k--)
        {
            headA = headA->next;
        }
    }
    while (headA != headB)
    {
        headA = headA->next;
        headB = headB->next;
    }
    return headA == headB;
}

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)
        {
            struct ListNode* meet = slow->next;
            slow->next = NULL;
            return GetSameNode(meet, head);

        }

    }
    return false;
}

10 随机链表的复制

138. 随机链表的复制 - 力扣(LeetCode)

cpp 复制代码
struct Node* copyRandomList(struct Node* head) {
    //复制节点
    struct Node* cur = head;
    while (cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        struct Node* next = cur->next;
        copy->val = cur->val;
        cur->next = copy;
        copy->next = next;
        cur = next;
    }

    //复制random
    cur = head;
    while (cur)
    {
        struct Node* copy = cur->next;
        if (cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = copy->next;
    }

    //尾插
    cur = head;
    struct Node* copyhead = NULL, * copytail = NULL;
    while (cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;
        if (copytail == NULL)
        {
            copyhead = copytail = copy;
        }
        else
        {
            copytail->next = copy;
            copytail = copytail->next;
        }

        //恢复原链表
        cur->next = next;
        //继续走
        cur = next;
    }
    return copyhead;

}

大家可以在力扣上刷一刷这些题目, 非常的实用和干货, 继续加油!

相关推荐
黑听人2 小时前
【力扣 简单 C】141. 环形链表
c语言·开发语言·数据结构·算法·leetcode
谷雨不太卷2 小时前
AVL树的实现
数据结构·c++·算法
大熊猫侯佩3 小时前
Swift 初学者交心:在 Array 和 Set 之间我们该如何抉择?
数据结构·性能优化·swift
BAGAE3 小时前
使用 Flutter 在 Windows 平台开发 Android 应用
android·大数据·数据结构·windows·python·flutter
liujing102329295 小时前
Day13_C语言基础&项目实战
c语言·开发语言
UP_Continue5 小时前
排序--计数排序
数据结构·算法
sunny-ll10 小时前
【C++】详解vector二维数组的全部操作(超细图例解析!!!)
c语言·开发语言·c++·算法·面试
西装没钱买11 小时前
C语言多进程TCP服务器与客户端
服务器·c语言·tcp/ip·进程
嵌入式@秋刀鱼11 小时前
《第四章-筋骨淬炼》 C++修炼生涯笔记(基础篇)数组与函数
开发语言·数据结构·c++·笔记·算法·链表·visual studio code
嵌入式@秋刀鱼12 小时前
《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
c语言·开发语言·数据结构·c++·笔记·算法·visual studio code