与链表有关的算法题

文章目录

  • [0. 注意](#0. 注意)
  • [1. 排队顺序(链表的打印)](#1. 排队顺序(链表的打印))
  • [2. 排队顺序(单链表)](#2. 排队顺序(单链表))
  • [3. 队列安排(双向链表)](#3. 队列安排(双向链表))
  • [4. 约瑟夫问题(循环链表)](#4. 约瑟夫问题(循环链表))

0. 注意

new 和 delete 是非常耗时的操作,

在算法比赛中,一般不会使用 new 和 delete 去模拟实现一个链表。

而 STL 里面的 list 的底层就是动态实现的双向循环链表,增删会涉及 new 和 delete,效率不高,竞赛中一般不会使用,而是以静态实现的方式。

关于链表的静态实现 可以参考我写的博客 点击转跳

1. 排队顺序(链表的打印)

https://www.luogu.com.cn/problem/B3630#ide

本题相当于告诉了我们每一个点的后继,使用静态链表的存储方式能够很好的还原这个队列。数组中 [1,n] 的下标可以当做数据域,根据题意修改指针域即可。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int n,h,i;
const int N=1e6+10;

int main()
{
    cin>>n;
    int ne[N];
    for(i=1;i<=n;i++)
    {
        cin>>ne[i];
    }
    cin>>h;
    for(i=h; i;i=ne[i])
    {
        cout<< i <<" ";
    }
    return 0;
}

2. 排队顺序(单链表)

https://www.luogu.com.cn/problem/B3631

链表模板题,直接实现⼀个单链表即可!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int h, id;
const int N=1e6+10;
int e[N],ne[N],mp[N],q,op,x,y;


int main()
{
    id++;
    e[id]=1;
    ne[h]=1;
    mp[1]=id;
    cin>>q;
    for(int i=0;i<q;i++)
    {
        cin>>op>>x;
        if(op==1)
        {
            cin>>y;
            id++;
            e[id]=y;
            ne[id]=ne[mp[x]];
            ne[mp[x]]=id;
            mp[y]=id;
        }
        if(op==2)
        {     
            cout<<e[ne[mp[x]]]<<endl;
        }
        if(op==3)
        {
            if(ne[mp[x]])
            {
               // mp[e[ne[mp[x]]]]=0;
                ne[mp[x]]=ne[ne[mp[x]]];
            }
        }
    }
    return 0;
}

3. 队列安排(双向链表)

https://www.luogu.com.cn/problem/P1160

频繁的在某⼀个位置之前和之后插⼊元素,因此可以⽤双向循环的链表来模拟。

循环双链表的静态实现可以参考我的博客 点击转跳

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

const int N =1e5+10;

int h,id,k,p,M,x;

int ne[N],mp[N],pre[N];

int main()
{
    int num;
    ne[0]=1;
    pre[1]=0;
    mp[1]=1;
    id++;
    cin>>num;
    for(int i=2;i<=num ;i++)
    {
        cin>>k>>p;
        id++;
        mp[i]=id;
        if(p==1)
        {
           ne[id]=ne[k];
           pre[id]=mp[k];
           pre[ne[mp[k]]]=id;
           ne[mp[k]]=id; 
            
        }
        else
        {
           ne[id]=mp[k];
           pre[id]=pre[mp[k]];
           ne[pre[mp[k]]]=id;
           pre[mp[k]]=id ;
        }
    }
    
    cin>>M;
    while(M--)
    {
        cin>>x;
        if(mp[x])
        {

            ne[pre[mp[x]]]=ne[mp[x]];
            pre[ne[mp[x]]]=pre[mp[x]];
            mp[x]=0;
        }
    }

    for(int j = ne[h];j;j=ne[j])
    {
        cout<<j<<" ";
    }
    return 0;
}

4. 约瑟夫问题(循环链表)

https://www.luogu.com.cn/problem/P1996

使⽤循环链表模拟即可! 但是这里面有一些小细节 我们删除元素的时候 每走m-1次就删除后面的元素 (比如给的测试样例是每走3次删一个元素,我们每数2次就删除它后面的元素),这是因为单链表删除有个关键的步骤是 ne[删除元素的前一个元素的位置]=ne[ne[删除前一个元素的位置]]如果我们直接删除当前元素,就很难找到当前元素的前一个位置!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N =110;
int n,m;
int h,id;
int ne[N];

int main()
{
    cin>>n>>m;
    //创建循环链表
    for(int i=1;i<n;i++)
    {
        ne[i]=i+1;
    }
    ne[n]=1;

    //用t指针进程模拟
    int t=n;//从1开始报数,那么t初始位置就该在最后
    while(n--)
    {
        for(int i=1;i<m;i++)
        {
            t=ne[t];
        }
        cout<<ne[t]<<" ";
        ne[t]=ne[ne[t]];
    }
    return 0;
}
相关推荐
Trouvaille ~20 小时前
零基础入门 LangChain 与 LangGraph(一):理解大模型、提示词、Embedding 和接入方式
算法·langchain·大模型·embedding·rag·langgraph·llm应用
xiaoye-duck20 小时前
《算法题讲解指南:动态规划算法--简单多状态dp问题》--17.买卖股票的最佳时机III,18.买卖股票的最佳时机IV
c++·算法·动态规划
老四啊laosi20 小时前
[双指针] 5. 有效三角形的个数
算法·leetcode·有效三角形的个数
少许极端20 小时前
算法奇妙屋(三十九)-贪心算法学习之路 6
java·学习·算法·贪心算法
编程之升级打怪20 小时前
有难度的关键算法
算法
wangchunting20 小时前
数据结构-图
数据结构·算法
tyler_download20 小时前
揉扁搓圆transformer架构:模型参数的初始化算法.
深度学习·算法·transformer
尽兴-20 小时前
机器人控制系统(RCS)核心算法深度解析:从路径规划到任务调度
算法·机器人·wms·mes·路径规划算法·冲突解决算法·任务调度算法
最贪吃的虎20 小时前
我的第一个 RAG 程序:从 0 到 1,用 PDF 搭一个最小可运行的知识库问答系统
人工智能·python·算法·机器学习·aigc·embedding·llama
421!20 小时前
C语言学习笔记——10(结构体)
c语言·开发语言·笔记·stm32·学习·算法