IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构】牛客网链表 -> 正文阅读

[数据结构与算法]【数据结构】牛客网链表

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


目录

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

二、牛牛的链表删除

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


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

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

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

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

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;
}

二、牛牛的链表删除

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

#include<stdio.h>
#include<stdlib.h>
//创建节点
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;i<n;i++){
        node=(Linklist*)malloc(sizeof(Linklist));
        tail->next=node;
         tail=node;
      }
    tail->next=NULL;
    return head;
}

//输入函数
Linklist* _scanf(Linklist* head,int n){
    Linklist* p=head;
    for(int i=0;i<n;i++){
        p=p->next;
       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个结点

此题思路快慢指针,先用快指针走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;i<k;i++)
    {
        if(fast==NULL)
            return NULL;
        fast=fast->next;
    }
    while(fast!=NULL)
    {
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

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

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:43:26  更:2022-09-13 11:43:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:18:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码