25. k个一组翻转链表

103 篇文章 0 订阅
99 篇文章 0 订阅

给出一个链表,每 个节点一组进行翻转,并返回翻转后的链表。

是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

示例 :

给定这个链表:1->2->3->4->5

当 = 2 时,应当返回: 2->1->4->3->5

当 = 3 时,应当返回: 3->2->1->4->5

说明 :

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

思路:我的思路就是将链表分开成组,压入vector中,按照实际情况判断是否需要翻转。当小组中的节点数小于k值时不用翻转。最后一并输入,上一组最后一个结点连接下一组的头结点。

注意保存返回的头结点。

(我的代码效率实在太低,有些汗颜,需要多多学习!)

另外两个注意的:

在cuts[m+1]这个语句中,会报错,free() invalid pointer。因为存在越界访问的行为,需要注意

对于链表翻转的算法还需加强理解和练习。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
       //实验:将链表切断;--可以切断的
        vector<ListNode*> cuts;
        ListNode* p=head;
        ListNode* r=head;
        int cnt=0;
        int sum=0;
        while(p!=NULL){
            p=p->next;
            sum++;
        }
        if(sum==k)
            return ReverseList( head) ;
        p=head;
        int i=0;//判断分组;
        int j=0;//判断最后一个组是否需要翻转
        int l=0;//统计分组数;
        while(p!=NULL){//分组,压入vector中;
            cnt+=i;
            i=0;
            for(i;i<k;i++){
               // cout<<"1"<<endl;
                cout<<p->val<<endl;
                r=p;
                if((sum-cnt)<k){
                    break;
                }
                p=p->next;
            }
            if((sum-cnt)>k){
                j=1;//不需要翻转
                r->next=NULL;
            }
            cuts.push_back(head);
            ++l;//统计分组数
            head=p;
            if((sum-cnt)<k){
                    break;
                }
            //cout<<"2"<<endl;
        }

        for(auto &t:cuts){//判断该组是不是需要翻转;
            int sum=0;
            ListNode *p=t;
            while(p!=NULL){
              p=p->next;
              sum++;
           }
            if(sum==k)
              t= ReverseList(t);
        }
        //将各组连接;
       // cout<<l<<endl;
        int m=0;
        for(auto &t:cuts){
            if(m==0)
                head=t;
            p=t;
            while(p->next!=NULL){
                p=p->next;
            }
            if(m+1<l)
                p->next=cuts[m+1];
            else
                break;
            ++m;
        }
        return head;
    }
private:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *root=pHead; 
        ListNode *pre=NULL;  
        ListNode *next=NULL;
        if(pHead==NULL) return NULL; 
    while(root->next){  
        next=root->next;   
        root->next=pre;      
        pre=root;       
        root=next;     
    }    
        root->next=pre; 
        return root; 
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值