【数据结构】链表--OJ

目录

1 移除链表元素

2 链表的中间节点

3 合并两个有序链表 

4 反转链表

5 回文链表

6 链表中第K个节点

7 链表分割 

8 相交链表

9 环形链表

10 随机链表的复制


1 移除链表元素

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

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)

 

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)

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)

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)

//找中间节点
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)

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)

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)

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)

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;
}

 

还有一种方法:

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)

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;

}

 

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值