zoukankan      html  css  js  c++  java
  • [Leetcode] Reverse nodes in k group 每k个一组反转链表

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

    If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

    You may not alter the values in the nodes, only nodes itself may be changed.

    Only constant memory is allowed.

    For example,
    Given this linked list:1->2->3->4->5

    For k = 2, you should return:2->1->4->3->5

    For k = 3, you should return:3->2->1->4->5

     题意:以k个结点为一组,进行反转连接,若最后小于k个结点,则保持不变。要求:仅用常数空间,不改变结点的值。

    思路:大致过程是每k个结点一反转,直到剩余结点数小于k。遇到一个问题是:如何判断剩余结点数小于k,即循环的终止条件?这样就需要知道整条链表的总共的结点数count,然后每次反转完一组则用总的count减去k,直到最后剩余结点数小于k,就不用改变。遇到另一个问题,如何反转k个结点,这个和reverse linked list ii类似,大致的想法可以参照。这样就剩下的如何将不同的小组连接起来的问题,因为在reverse linked list ii这题中,只要反转一部分,所以其pre是不动的,这题因为有很多小组,所以pre应该是每k个结点为一小组的最开始结点的前驱,所以要移动,同理的是当前节点cur。因为要改变表头,所以要先new一个nList。使用计数器的思维值得注意。

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode *reverseKGroup(ListNode *head, int k) 
    12     {
    13         ListNode *nList=new ListNode(-1);
    14         nList->next=head;
    15         ListNode *cur=head;
    16         ListNode *pre=nList;
    17 
    18         int num=0;      //组里的结点数
    19         int count=0;    //整链结点数
    20         while(head)
    21         {
    22             head=head->next;
    23             count++;
    24         } 
    25 
    26         while(count>=k)     //整体遍历
    27         {
    28             while(++num<k)  //组内循环
    29             {
    30                 ListNode *temp=cur->next;
    31                 cur->next=temp->next;
    32                 temp->next=pre->next;
    33                 pre->next=temp;
    34             }
    35             count-=num;  //减k也行.
    36             num=0;
    37             pre=cur;    //每组反转以后,pre要移动
    38             cur=cur->next;  //cur要变
    39         }
    40         return nList->next;
    41 
    42     }
    43 };

    还有另一种写法:见Code Gander的博客,其核心思想是,每次取k个结点进行反转,传入反转函数的是这个组的前驱和其最后一个结点,反转函数返回是反转后小组的第一个结点,体会其中的差别。代码如下:

     1 /**   Reverse Nodes in k-Group 
     2  *
     3  * Definition for singly-linked list.
     4  * struct ListNode {
     5  *     int val;
     6  *     ListNode *next;
     7  *     ListNode(int x) : val(x), next(NULL) {}
     8  * };
     9  */                 //经典,很多关于list的题都可用这种方法重写
    10  /* 使用计数器count,若count=k,则反转前k个节点,然后重置count */
    11 class Solution {
    12 public:
    13     ListNode *reverseKGroup(ListNode *head, int k) 
    14     {
    15         if(head==NULL)  return NULL;
    16 
    17         ListNode *preAll=new ListNode(-1);
    18         preAll->next=head;
    19 
    20         ListNode *pre=preAll;
    21         ListNode *cur=head;
    22         int count=0;
    23 
    24         while(cur !=NULL)
    25         {
    26             count++;
    27             ListNode *last=cur->next;
    28             if(count==k)
    29             {
    30                 pre=reverse(pre,last);
    31                 count=0;
    32             }
    33             cur=last;
    34         } 
    35 
    36         return preAll->next;   
    37     }
    38 
    39     //反转前k个节点,这k个点的前驱和最后一点传入
    40     ListNode *reverse(ListNode *pre,ListNode *last)
    41     {
    42         if(pre==NULL||pre->next==NULL)  return pre;
    43 
    44         ListNode *head=pre->next;
    45         ListNode *cur=pre->next->next;
    46 
    47         while(cur !=last)
    48         {
    49             ListNode *temp=cur->next;
    50             cur->next=pre->next;
    51             pre->next=cur;
    52             cur=temp;
    53         }
    54 
    55         head->next=last;
    56         return head;    //巧妙之处是返回前节点
    57     }
    58 };
  • 相关阅读:
    quick-cocos2d-x游戏开发【5】——创建菜单
    cocos2d-x3.0 lua学习(一个)
    hdu 3001 Travelling (TSP问题 )
    朱重组成功,?(行家都知道,几乎回答)
    无人机DLG生产作业流程
    自己定制个人无人机需要的准备工作的内容
    C# 多线程网络爬虫
    [转] c#中 多线程访问winform控件
    C# WinForm中 让控件全屏显示的实现代码
    5.数据绑定和表单标签库
  • 原文地址:https://www.cnblogs.com/love-yh/p/7049308.html
Copyright © 2011-2022 走看看