每K个元素翻转一次链表,若最后剩余元素不足K个,不进行翻转(美团2014校招试题)

来源:互联网 发布:ubuntu的英语读音 编辑:程序博客网 时间:2024/04/26 12:24

给定一个单链表和一个整数k,要求每隔k个元素翻转链表一次

struct node{

   int key;
   struct node* next;

};

typedef node* List;

实现函数:List kReverse(List  head,int k)

比如:

原始链表为:1—>2—>3—>4—>5—>6

k=2 翻转为:2—>1—>4—>3—>6—>5

k=3 翻转为:3—>2—>1—>6—>5—>4

k=4 翻转为:4—>3—>2—>1—>5—>6

#include <stdio.h>#include <stdlib.h>typedef struct node{    int data;    struct node* next;}node, *List;List kReverse(List head,int k){    List oldHead = NULL;List newHead = NULL;//链表翻转完之后的第一个节点    List previousGroupTail = NULL;int n = 0;int num = 0;int count = 1;int reverseNum;    //链表为空或链表中只有一个元素,则不需要翻转    if (head == NULL || head->next == NULL)    return head;    oldHead = head;     //链表长度while (head != NULL) {  head = head->next;  n++;}reverseNum = n / k;//需要翻转的链表的个数 newHead = head = oldhead;while (head != NULL && num < reverseNum)     {List groupTail = head;//groupTail记录分组内的头结点,即为翻转后分组内的尾节点List prev = NULL;List next = NULL;int i;//翻转具有k个元素的链表分组,每循环一次后,pre指向翻转前分组内最后一个节点,head指向下一个分组的第一个节点for (i = 1; i <= k && head != NULL; i++) {      next = head->next;      head->next = prev;  prev = head;      head = next;}            //newHead指向第一个分组翻转之后的第一个节点    if (count == 1) {        newHead = prev;        count++;         }     if(previousGroupTail != NULL)         {       previousGroupTail->next = prev;        }    previousGroupTail = groupTail;num++;}//处理最后的不组K个的元素节点,此时head指向剩下的元素的第一个节点if (head != NULL){     if (previousGroupTail != NULL){        previousGroupTail->next = head;        }     }     return newHead;}void push(List* head_ref, int new_data){    List new_node = (List) malloc(sizeof(node));             new_node->data  = new_data;    new_node->next = (*head_ref);        (*head_ref) = new_node;}int main(){     List head = NULL; List head1 = NULL;     push(&head, 8);     push(&head, 7);     push(&head, 6);     push(&head, 5);     push(&head, 4);     push(&head, 3);     push(&head, 2);     push(&head, 1); head1 = kReverse(head, 3);  printf("翻转后:"); while (head1 != NULL)  {    printf("%d ",head1->data);head1 = head1->next; }     printf("\n");return 0;}


方法2:

ListNode *reverseKGroup(ListNode *head, int k){    if (head == nullptr || head->next == nullptr || k < 2)    {        return head;    }    ListNode *next_group = head;    for (int i = 0; i < k; ++i)    {        if (next_group)        {            next_group = next_group->next;        }        else        {            return head;        }    }    // next_group is the head of next group    // new_next_group is the new head of next group after reversion    ListNode *new_next_group = reverseKGroup(next_group, k);    ListNode *prev = NULL, *cur = head;    while (cur != next_group)    {        ListNode *next = cur->next;        cur->next = prev ? prev : new_next_group;        prev = cur;        cur = next;    }    return prev; // prev will be the new head of this group}


原创粉丝点击