LeetCode 热题 100_K 个一组翻转链表(31_25_困难_C++)(四指针法) ...

打印 上一主题 下一主题

主题 785|帖子 785|积分 2355

题目描述:

给你链表的头节点 head ,每 k 个节点一组举行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或即是链表的长度。假如节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是必要实际举行节点交换。
输入输出样例:

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
提示:
链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
题解:

解题思绪:

思绪一(四指针法):

1、通过题目分析,在每次翻转前必要举行个数的判断,若满意再将k个结点翻转,将翻转后的答案举行连接。
我们发现我们在举行翻转的时候必要保存k个结点的首和尾(kHead和kTail),并且还必要保存kHead之前的一个结点(ansTail)和kTail之后的一个结点(next_kHead),方便将翻转后的链表举行连接和剩余结点的处理,因此我们必要四个指针(kHead、kTail、ansTail、next_kHead)。
具体实现思绪请看下图:

代码实现

代码实现(思绪一(四指针法)):

  1. //判断剩余长度是否>=k,不够则返回nullptr,够则返回k个长度链表的尾结点
  2. ListNode *judgeLen_k(ListNode *kHead,int k){
  3.         while(k-1){
  4.                 if(kHead==nullptr){
  5.                         return nullptr;
  6.                 }
  7.                 kHead=kHead->next;
  8.                 --k;
  9.         }
  10.         return kHead;
  11. }
  12. //翻转固定个数的链表,返回翻转后的头结点
  13. ListNode *reverseList_k(ListNode *kHead,int k){
  14.         ListNode *pre=nullptr,*r=kHead,*tmp=kHead;
  15.         while(k){
  16.                 r=r->next;
  17.                 tmp->next=pre;
  18.                 pre=tmp;
  19.                 tmp=r;
  20.                 --k;
  21.         }
  22.         return pre;
  23. }
  24. //K 个一组翻转链表
  25. ListNode* reverseKGroup(ListNode* head, int k) {
  26.         ListNode *dummyHead=new ListNode(0);
  27.         //存储答案的尾结点
  28.         ListNode *ansTail=dummyHead;
  29.         //交换前,k个结点的头
  30.         ListNode *kHead=head;
  31.         //交换前,k个结点的末尾,不够k个则为nullptr
  32.         ListNode *kTail=judgeLen_k(kHead,k);
  33.         //保存下一个区间的头
  34.         ListNode *next_kHead=nullptr;
  35.         while(kTail!=nullptr){
  36.                 //保存下一个区间的头
  37.                 next_kHead=kTail->next;
  38.                 //翻转k个结点
  39.                 reverseList_k(kHead,k);
  40.                
  41.                 //将k个结点翻转后的链表,连接到答案列表
  42.                 ansTail->next=kTail;
  43.                 kHead->next=next_kHead;
  44.                
  45.                 //更新答案链表的尾结点
  46.                 ansTail=kHead;
  47.                 //更新交换前,k个结点的头
  48.                 kHead=next_kHead;
  49.                 //判断之后的结点是否够k个
  50.                 kTail=judgeLen_k(next_kHead,k);
  51.                
  52.                  
  53.         }
  54.         ListNode *ansHead=dummyHead->next;
  55.         delete dummyHead;
  56.         return ansHead;         
  57. }
复制代码
代码调试
  1. #include<iostream>#include<vector>using namespace std;struct ListNode{        int val;        ListNode *next;        ListNode():val(0),next(nullptr){}         ListNode(int x):val(x),next(nullptr){}        ListNode(int x,ListNode *next): val(x),next(next){}}; //尾插法创建单链表ListNode *createList(vector<int> arr){        ListNode *head=nullptr,*tail=nullptr;        for(const auto &val:arr){                if(head==nullptr){                        head=tail=new ListNode(val);                }else{                        tail->next=new ListNode(val);                        tail=tail->next;                }        }        return head;} //判断剩余长度是否>=k,不够则返回nullptr,够则返回k个长度链表的尾结点
  2. ListNode *judgeLen_k(ListNode *kHead,int k){
  3.         while(k-1){
  4.                 if(kHead==nullptr){
  5.                         return nullptr;
  6.                 }
  7.                 kHead=kHead->next;
  8.                 --k;
  9.         }
  10.         return kHead;
  11. }
  12. //翻转固定个数的链表,返回翻转后的头结点
  13. ListNode *reverseList_k(ListNode *kHead,int k){
  14.         ListNode *pre=nullptr,*r=kHead,*tmp=kHead;
  15.         while(k){
  16.                 r=r->next;
  17.                 tmp->next=pre;
  18.                 pre=tmp;
  19.                 tmp=r;
  20.                 --k;
  21.         }
  22.         return pre;
  23. }
  24. //K 个一组翻转链表
  25. ListNode* reverseKGroup(ListNode* head, int k) {
  26.         ListNode *dummyHead=new ListNode(0);
  27.         //存储答案的尾结点
  28.         ListNode *ansTail=dummyHead;
  29.         //交换前,k个结点的头
  30.         ListNode *kHead=head;
  31.         //交换前,k个结点的末尾,不够k个则为nullptr
  32.         ListNode *kTail=judgeLen_k(kHead,k);
  33.         //保存下一个区间的头
  34.         ListNode *next_kHead=nullptr;
  35.         while(kTail!=nullptr){
  36.                 //保存下一个区间的头
  37.                 next_kHead=kTail->next;
  38.                 //翻转k个结点
  39.                 reverseList_k(kHead,k);
  40.                
  41.                 //将k个结点翻转后的链表,连接到答案列表
  42.                 ansTail->next=kTail;
  43.                 kHead->next=next_kHead;
  44.                
  45.                 //更新答案链表的尾结点
  46.                 ansTail=kHead;
  47.                 //更新交换前,k个结点的头
  48.                 kHead=next_kHead;
  49.                 //判断之后的结点是否够k个
  50.                 kTail=judgeLen_k(next_kHead,k);
  51.                
  52.                  
  53.         }
  54.         ListNode *ansHead=dummyHead->next;
  55.         delete dummyHead;
  56.         return ansHead;         
  57. }
  58. int main(){        vector<int> a={1,2,3,4,5};        int k=2;        ListNode *head=createList(a);        ListNode *test=reverseKGroup(head,k);         while(test!=nullptr){                cout<<test->val<<"->";                test=test->next;        }        cout<<"null";         return 0;}
复制代码
反转链表(23_206_简单_C++)(单链表_迭代_递归):有关反转链表的知识请点击此链接
LeetCode 热题 100_K 个一组翻转链表(31_25)原题链接
接待大家和我沟通交换(✿◠‿◠)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表