LeetCode刷题---链表

一、反转链表

在这里插入图片描述

1.分析

给定单链表头结点,反转链表之后返回新的头结点。
思路一:翻转指针
在这里插入图片描述
原本1号指针指向下一个节点2的,但是将1号指针翻转之后指向空,一直翻转直到5指向空翻转为5指向4.
所以我们就需要3个变量,一个节点存放指向其他节点的信息,另一个节点是被指向的节点,还需要一个节点来存放下一个节点的信息
思路2:头插法
将已知链表存放在一个新的链表中,将已知链表的每一个节点头插进新的链表中,需要三个变量:一个变量存放新的链表的节点信息,一个变量存放下一个节点的信息,一个变量来存放当前位置的信息

2.翻转指针

struct ListNode* reverseList(struct ListNode* head) {
   
    if (head == NULL)
    {
   
        return NULL;
    }
    struct ListNode* n1 = NULL;//被指向的节点
    struct ListNode* n2 = head;//已知节点
    struct ListNode* n3 = n2->next;//存下一个节点的位置
    while (n2 != NULL)
    {
   
        n2->next = n1;
        n1 = n2;
        n2 = n3;
        if (n3)
        {
   
            n3 = n3->next;
        }
    }
    return n1;
}

3.头插法

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

二、链表的中间结点

在这里插入图片描述

1.分析

给定链表头结点,找出链表中间节点。
思路1:求长度,找中间值
定义一个变量len来表示长度,先遍历一遍链表,求出链表长度,然后直接就可以得出中间节点的位置
思路2:快慢指针
定义两个指针,一个slow一个fast,fast走两步,slow走一步,当fast到达最后一个节点或者fast出了链表之后,slow指针刚好到达中间节点,图示:
在这里插入图片描述
在这里插入图片描述

1.求长度,找中点

struct ListNode* middleNode(struct ListNode* head) {
   
    int len = 0;
    struct ListNode* p1 = head;
    while (p1)
    {
   
        len++;
        p1 = p1->next;
    }
    for (int i = 0;i < len / 2;i++)
    {
   
        head = head->next;
    }
    return head;
}

2.快慢指针

struct ListNode* middleNode(struct ListNode* head) {
   
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast && fast->next)
    {
   
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

三、合并两个有序链表

在这里插入图片描述

1.分析

思路1:尾插法
由上图可知可以创建一个新的链表,然后依次把两个链表中小的数尾插进新的链表,准备两个节点,一个节点遍历新的链表,一个节点始终指向新链表的头结点,用两个链表依次比较来填充新的链表
思路2:带哨兵位的头结点
利用带哨兵位的头结点,就排除了第一个指针为空的情况,就可以直接判断两个链表的val的大小。

2.尾插法

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;
    while (list1 != NULL && list2 != NULL)
    {
   
        if (list1->val < list2->val)
        {
   
            if (tail == NULL)
            {
   
                head = tail = list1;
            }
            else
            {
   
                tail->next = list1;
                tail = tail->next;
            }
            list1 = list1->next;
        }
        else
        {
   
            if (tail == NULL)
            {
   
                head = tail = list2;
            }
            else
            {
   
                tail->next = list2;
                tail = tail->next;
            }
            list2 = list2->next;
        }
    }
    if (list1 != NULL)
    {
   
        tail->next = list1;
    }
    if (list2 != NULL)
    {
   
        tail->next = list2;
    }
    return head;
}

注:可以提前准备头结点,省去两个判断是否为空的if语句
算法优化:

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;
    if (list1->val < list2->val)
    {
   
        head = tail = list1;
        list1 = list1->next;
    }
    else
    {
   
        head = tail = list2;
        list2 = list2->next;
    }
    while (list1 != NULL && list2 != NULL)
    {
   
        if (list1->val < list2->val)
        {
   
            tail->next = list1;
            tail = tail->next;
            list1 = list1->next;
        }
        else
        {
   
            tail->next = list2;
            tail = tail->next;
            list2 = list2->next;
        }
    }
    if (list1 != NULL)
    {
   
        tail->next = list1;
    }
    if (list2 != NULL)
    {
   
        tail->next = list2;
    }
    return head;
}

3.带哨兵位的头节点

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 != NULL && list2 != NULL)
    {
   
        if (list1->val < list2->val)
        {
   
            tail->next = list1;
            tail = tail->next;
            list1 = list1->next;
        }
        else
        {
   
            tail->next = list2;
            tail = tail->next;
            list2 = list2->next;
        }
    }
    if (list1 != NULL)
    {
   
        tail->next = list1;
    }
    if (list2 != NULL)
    {
   
        tail->next = list2;
    }
    return head->next;
}

四、环形链表

在这里插入图片描述

1.分析

思路:通过快慢指针,创建两个指针,一个fast指针,一个slow指针,slow指针一次走一步,fast指针一次走两步,因为fast指针走的快,所有有两种情况。
第一种情况:
在这里插入图片描述
第二种情况:
在这里插入图片描述
第二种情况就是环形链表,因为fast走的快所以fast先进入环形区域,所以fast在环形区域中已知旋转,当slow进入环形区域中时solw和fast最终会相遇,所以结束标志就是fast==slow如果是非环形链表的话直接就出循环了。

2.快慢指针

bool hasCycle(struct ListNode* head) {
   
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
   
        fast = fast->next->next;
        slow = slow->next;
        if (slow == fast)
        {
   
            return true;
        }
    }
    return false;
}

相关推荐

  1. LeetCode笔记之

    2024-01-12 07:44:02       24 阅读
  2. leetcode算法——

    2024-01-12 07:44:02       27 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-12 07:44:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-12 07:44:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-12 07:44:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-12 07:44:02       20 阅读

热门阅读

  1. 使用Sqoop将Hive数据导出到TiDB

    2024-01-12 07:44:02       33 阅读
  2. k8s存储卷和数据卷下

    2024-01-12 07:44:02       30 阅读
  3. 力扣_数组27—最大矩形

    2024-01-12 07:44:02       38 阅读
  4. debian 12 zabbix 6.0LTS部署

    2024-01-12 07:44:02       36 阅读
  5. 力扣(leetcode)第551题学生出勤记录I(Python)

    2024-01-12 07:44:02       31 阅读
  6. 微服务概述之微服务架构

    2024-01-12 07:44:02       40 阅读
  7. 力扣48. 旋转图像

    2024-01-12 07:44:02       28 阅读
  8. 如何在 Ubuntu 20.04 上安装 Node.js

    2024-01-12 07:44:02       36 阅读
  9. 汽车销售领域相关专业术语

    2024-01-12 07:44:02       44 阅读
  10. Github

    Github

    2024-01-12 07:44:02      33 阅读