【数据结构】牛客网链表

【数据结构】牛客网链表_第1张图片

推荐一款模拟面试、刷题神器 、从基础到大厂面试题:点击跳转刷题网站进行注册学习


目录

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

二、牛牛的链表删除

三、链表中倒数最后k个结点


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

【数据结构】牛客网链表_第2张图片

排除各类特殊情况:链表空,链表只有一个,一组节点数大于链表内节点总数之后

第一组翻转需要特殊处理,因为它没有前结点

之后的所有组都按照:找反转头,反转头的前结点,反转尾,翻转尾的后节点,再按照部分翻转,之后链接翻转部分和原来部分即可

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_countnext;
            //原地反转法将需要反转的部分链表反转
            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_mnext;
                count_m++;
            }
            //寻找此次反转头的前一个
            struct ListNode* org_head_pre=head;
            int count_m2=1;
            while(count_m2next;
                count_m2++;
            }
            //找到反转的尾
            int count_n=1;
            struct ListNode* org_tail=head;
            while(count_nnext;
                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;
}

二、牛牛的链表删除

【数据结构】牛客网链表_第3张图片

在这个问题里面,要注意删除函数判断的应该是(p->next)!=NULL;如果是p!=NULL,当位于最后一个数字的时候p->next->data出现不存在的问题,编译器会报错数组越界

#include
#include
//创建节点
typedef struct node{
    int data;
    struct node* next;
}Linklist;

//创建n个节点的单链表
Linklist* _create(int n){
    Linklist* head,*node,*tail;
    head=(Linklist*)malloc(sizeof(Linklist));
    tail=head;
     for(int i=0;inext=node;
         tail=node;
      }
    tail->next=NULL;
    return head;
}

//输入函数
Linklist* _scanf(Linklist* head,int n){
    Linklist* p=head;
    for(int i=0;inext;
       if(p!=NULL){
        scanf("%d",&p->data);
      }
    }
    return head;
}

//删除节点
Linklist* _delete(Linklist* head,int num){
    Linklist* p=head,*t;
    //找到num的上一个节点
     while((p->next)!=NULL){
        //删除节点
        if(p->next->data==num){
            t=p->next;
            p->next=t->next;
            free(t);
        }
        p=p->next;
      }
       return head;  
  }

int main(){
    int n,num;
    scanf("%d %d",&n,&num);
    Linklist* t=_delete(_scanf(_create(n),n),num);
  while(t!=NULL){
      t=t->next;
      if(t!=NULL){
            printf("%d ",t->data);
      }
    
  }
    return 0;
}

三、链表中倒数最后k个结点

【数据结构】牛客网链表_第4张图片

此题思路快慢指针,先用快指针走k步,如果k的大小没有超过链表大小,则快慢指针同时移动,这样两者始终保持k距离,当快指向空时,返回慢指针即为倒数的k个结点

struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
   if(pHead==NULL)
       return NULL;
    struct ListNode*fast=pHead,*slow=pHead;
    for(int i=0;inext;
    }
    while(fast!=NULL)
    {
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

【数据结构】牛客网链表_第5张图片

推荐一款模拟面试、刷题神器 、从基础到大厂面试题:点击跳转刷题网站进行注册学习

你可能感兴趣的:(数据结构与算法,链表,数据结构)