链表的经典算法OJ题

前言

hello,大家好呀,我是Humble,本篇博客要分享的内容是关于链表的一些力扣OJ题

OK,废话不多说,我们直接开始吧~

 

链表的经典算法OJ题_第1张图片

题目一

 

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

 

题目描述:

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node

val == val 的节点,并返回 新的头节点

链表的经典算法OJ题_第2张图片

 

链表的经典算法OJ题_第3张图片

 

思路一:遍历原链表,遇到val就执行删除 val 节点的操作

这是一种很容易想到的思路,BUT,执行删除操作修改指针的指向有点麻烦,有没有其他办法?

 

接下来我们看一下思路二:

定义新链表,遍历原链表找不为val的节点,尾插在新链表上

 

代码如下:

struct ListNode* removeElements(struct ListNode* head, int val)
 {
    struct ListNode* newHead = NULL;
    struct ListNode* newTail = NULL;

    struct ListNode* pcur = head;//pur用来遍历链表

    while(pcur)
    {
       if (pcur->val!=val)
             {
                 if (newHead == NULL)//链表为空
                    newHead =  newTail = pcur;

                 else 
                 {
                    newTail->next = pcur;
                    newTail = newTail->next;
                 }
             }
       pcur = pcur->next;

    }

    if (newTail)   newTail->next = NULL; //循环结束后让尾节点指向空指针

    return newHead;

}

运行结果:
 

链表的经典算法OJ题_第4张图片

 

 

题目二

 

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

 

题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表

链表的经典算法OJ题_第5张图片

 

链表的经典算法OJ题_第6张图片

 

这里有一个点值得注意,链表的指针是只能指向后面的,不能反过来,这也是它的一个特性

 

思路:创建三个指针n1,n2,n3分别记录前驱节点,当前节点,后继节点,改变原链表指针指向

代码如下:

struct ListNode* reverseList(struct ListNode* head) 
{
    if (head == NULL) //如果是空链表,直接返回
        return head;
    
   struct ListNode* n1, *n2, *n3;
   n1 = NULL;
   n2 = head;
   n3 = head->next;
   
   while (n2)
   {
      n2->next = n1;
      n1 = n2;
      n2 = n3;
      if (n3) n3 = n3->next;

   }

  return n1;
}

运行结果如下:
链表的经典算法OJ题_第7张图片

 

 

题目三

 

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

 

题目描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

链表的经典算法OJ题_第8张图片

链表的经典算法OJ题_第9张图片

 

对于这道题,我们很直接的会想到要创建一个新链表

而且,如果有看过我的上一篇关于顺序表的算法OJ题博客的小伙伴可能会发现,

本题与那里的题目二——合并两个有序数组有点相像

 

下面是这道题的代码:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
   
     if (list1 == NULL)  return list2;
     if (list2 == NULL)  return list1;
     
     struct ListNode* l1 = list1;
     struct ListNode* l2 = list2;

     struct ListNode* newHead,*newTail; 
     newHead = newTail = (struct ListNode*)malloc(sizeof(struct ListNode));
  
     while (l1 && l2)
     {
         if (l1->val < l2->val)
           { 
              newTail->next = l1;
              newTail = newTail->next;
              l1 = l1->next;
            }
        
         else
          {
            newTail->next = l2;
            newTail = newTail->next;
            l2 = l2->next;
          }
     }

     if (l1)  newTail->next = l1;
     if (l2)  newTail->next = l2;
    
     struct ListNode* ret = newHead->next;
     free(newHead);
     return ret;
}


运行结果:

链表的经典算法OJ题_第10张图片

 

 

 

 

题目四

 

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

 

题目描述:

给你单链表的头结点 head ,请你找出并返回链表的中间结点

如果有两个中间结点,则返回第二个中间结点

链表的经典算法OJ题_第11张图片

 

链表的经典算法OJ题_第12张图片

 

链表的经典算法OJ题_第13张图片

 

对于这道题,Humble的思路是快慢指针

定义两个变量slow和fast

slow每走一步,fast走两步

 

代码如下:

struct ListNode* middleNode(struct ListNode* head)
 {
    struct ListNode* slow,*fast;
    slow = fast =head;

    while(fast && fast->next) //两个条件顺序不能换!
    {
          slow = slow->next;//slow走一步
          fast = fast->next->next;//fast走两步

    }

   return slow;
}

 

运行结果如下:
链表的经典算法OJ题_第14张图片

 

 

题目五

 

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

 

题目描述:

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前

链表的经典算法OJ题_第15张图片

 

链表的经典算法OJ题_第16张图片

 

对于这道题,Humble的思路是:定义两个链表,分别放 小于 x 的 与 大于或等于 x 的

通过遍历原链表分别放进对应的新链表中,最后两个链表按顺序首尾相连

 

代码如下:

struct ListNode* partition(struct ListNode* head, int x)
{
if (head ==NULL) //空链表直接返回
     return head;

struct ListNode*greaterHead,*greaterTail;
struct ListNode*lessHead,*lessTail;

greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));

struct ListNode* pcur = head;
while (pcur)
    {  
         if (pcur ->val next = pcur;
             lessTail = lessTail->next;
         }
        else 
        {
         greaterTail->next = pcur;
         greaterTail = greaterTail->next;
        }
      pcur =  pcur->next;
    }
    
greaterTail->next = NULL;//将大链表尾部置为NULL,防止链表循环

lessTail->next = greaterHead->next;

    
    return lessHead->next;
}

运行结果如下:

链表的经典算法OJ题_第17张图片

 

 

 

结语

好了,今天关于链表的五道OJ题的分享就到这里了,如果对大家有帮助就太好啦~

在学习编程的道路上Humble与各位同行,加油吧各位!

最后希望大家点个免费的赞或者关注吧(感谢感谢),也欢迎大家订阅我的专栏

让我们在接下来的时间里一起成长,一起进步吧!

e0d3d2143b284925a6e6d82b6cd73662.png

 

 

你可能感兴趣的:(C语言进阶之数据结构,算法,链表,数据结构,c语言,开发语言)