链表OJ题练习2

这篇博客主要介绍了三种链表操作:使用双指针法删除链表的倒数第N个节点,合并已排序的K个链表,以及如何旋转链表。提供了详细的思路分析和代码实现,包括快慢指针法和构建环形链表等技巧。这些方法对于理解和解决链表问题非常有帮助。
摘要由CSDN通过智能技术生成

链表的倒数第N个节点(双指针)

链接删除链表的倒数第 N 个结点

问题描述

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?

方法1分析:

  1. 我们可以在遍历链表的同时将所有节点依次入栈。
  2. 根据栈「先进后出」的原则,我们弹出栈的第 n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点
    (需要自己建栈,这里不再赘述)

方法2分析:

  1. 先让快指针走n步,再快慢指针同时走,同时记录慢指针的前一个节点
  2. 直到快指针为NULL时 让记录的慢指针的前一个节点指向慢指针的后一个节点

代码如下:

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
   if(head->next==NULL)
   {
       return NULL;
  }
  struct ListNode* newhead=(struct ListNode* )malloc(sizeof(struct ListNode));
   newhead->next=head;
   struct ListNode* prev=newhead;
   struct ListNode* fast=head;
   struct ListNode* slow=prev->next;
   while(n--)
   {
       fast=fast->next;
   }
   while(1)
   {
       if(fast==NULL)
       {
           prev->next=slow->next;
           break;
       }
       slow=slow->next;
       prev=prev->next;
       fast=fast->next;
   }
   return newhead->next;
}

合并 K个升序链表

链接删除链表的倒数第 N 个结点

问题描述

给你一个链表数组,每个链表都已经按升序排列
请你将所有链表合并到一个升序链表中,返回合并后的链表。

思路一:(暴力法)

  1. 将链表数组中的每个链表中的节点值存到一个新建的数组中,然后对数组排序,再建一个新链表进行存储

思路二:(小根堆

思路三:(分而治之
代码如下

在这里插入代码片

旋转链表

链接删除链表的倒数第 N 个结点

问题描述:

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

思路一:双指针
思路二:环形链表

  1. 先循环得出链表的长度,同时顺便让尾的next指向head构成环形
  2. 由head开始两两交换,一个循环进行n次,共(k%n)个循环
    代码如下:
struct ListNode* rotateRight(struct ListNode* head, int k){
   if(head==NULL)
   {
       return NULL;
   }
   struct ListNode* cac=head;
   //struct ListNode* cur=head;
   int n=0;
   while(1)
   {
       if(cac->next==NULL)
       {
           n++;
           break;
       }
       cac=cac->next;
       n++;
   }
   printf("%d\n",n);
   if(0==k%n)
       return head;
   cac->next=head;//构造环形链表
   int times=k%n+1;
   while(--times)
   {
       struct ListNode* cur=head;
       int tmp=cur->val;
       for(int i=0;i<=n;i++)
       {
           struct ListNode* next=cur->next;
           int tem=next->val;
           next->val=tmp;
           tmp=tem;
           cur=next;
       }
   } 
   struct ListNode* cur2=head;
   while(--n)
   {
       cur2=cur2->next;
   }
   cur2->next=NULL;
   return head;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值