题解 | #链表中的节点每k个一组翻转#

链表中的节点每k个一组翻转

http://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e

使用上一题翻转区间内链表的思路

  • 排除各类特殊情况:链表空,链表只有一个,一组节点数大于链表内节点总数
  • 之后
  • 第一组翻转需要特殊处理,因为它没有前结点
  • 之后的所有组都按照:找反转头,反转头的前结点,反转尾,翻转尾的后节点,再按照部分翻转,之后链接翻转部分和原来部分即可
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param k int整型 
 * @return ListNode类
 */

 
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
    // write code here
    //遍历获得链表节点个数
    int list_count=0;
    struct ListNode* count_head=head;
    while(count_head){
        count_head=count_head->next;
        list_count++;
    }
    //如果空链表,或者链表只有一个元素,或者反转一组链表节点个数小于k,直接返回链表头
    if(head==NULL || head->next ==NULL || list_count<k){
        return head;
    }
    struct ListNode* node=head;
    struct ListNode* org_head=head;
    struct ListNode* org_head_pre=NULL;
    int count=1;
    while(count<=list_count){
        if(count==k){
            struct ListNode* org_tail=node;
            struct ListNode* org_tail_next=node->next;
            //原地反转法将需要反转的部分链表反转
            struct ListNode* pre=org_tail_next;
            struct ListNode* cur=org_head;
            struct ListNode* next=cur->next;
            while(cur!=org_tail_next){
                cur->next=pre;
                pre=cur;
                cur=next;
                next=next->next;
            }
            head=pre;//保存一下整个链表的头结点
        } 
        if(count%k==0 && count>k){
            //遍历寻找此次反转的头
            int count_m=1;
            struct ListNode* org_head=head;
            while(count_m<count-k+1){
                org_head=org_head->next;
                count_m++;
            }
            //寻找此次反转头的前一个
            struct ListNode* org_head_pre=head;
            int count_m2=1;
            while(count_m2<count-k){
                org_head_pre=org_head_pre->next;
                count_m2++;
            }
            //找到反转的尾
            int count_n=1;
            struct ListNode* org_tail=head;
            while(count_n<count){
                org_tail=org_tail->next;
                count_n++;
            }
            //找到反转尾的下一个节点
            int count_n2=1;
            struct ListNode* org_tail_next=head;
            while(count_n2<=count){
                org_tail_next=org_tail_next->next;
                count_n2++;
            }
            //原地反转法将需要反转的部分链表反转
            struct ListNode* pre=org_tail_next;
            struct ListNode* cur=org_head;
            struct ListNode* next=cur->next;
            while(cur!=org_tail_next){
                cur->next=pre;
                pre=cur;
                cur=next;
                next=next->next;
            }
            org_head_pre->next=pre; //链接翻转部分和原来的部分
        }
        node=node->next;
        count++;
    }
    return head;
}
全部评论

相关推荐

神哥了不得:你简历字体有点不太协调呀,下面的字实在太小了呀,而且项目也不太行,建议换几个高质量的项目,面试会多很多
点赞 评论 收藏
分享
02-08 20:56
已编辑
南京工业大学 Java
在等offer的比尔很洒脱:我也是在实习,项目先不说,感觉有点点小熟悉,但是我有点疑问,这第一个实习,公司真的让实习生去部署搭建和引入mq之类的吗,是不是有点过于信任了,我实习过的两个公司都是人家正式早搭好了,根本摸不到部署搭建的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务