抛弃旧有链表思维解决PAT-A1074

不同于真正的链表,算法笔记上提出了一种静态链表来模拟实际链表,对于解题速度、准确性都有很大帮助。然而受限于原来链表思维,在解决有关链表的题目时虽然使用了静态链表,但解决问题的方式与使用实际链表时并无区别,这样导致解题准确度、速度依然很慢。这篇文章记录自己实现思路与题解思路的区别,以加深自己对静态链表的掌握。

旧思路

  1. 开一个数组作为静态链表,读入数据,初始化链表

  2. 从头结点开始遍历链表,记录有效节点数量

  3. 用一个双层循环,外层循环模拟按照k划分的每一组,内存循环用于实现链表逆置

    链表逆置的主要思想为:用一个指针指向尾结点(原序列的头结点),遍历后面的每个节点,每一个都插入到当前头节点前面,每插入一个节点就更新当前头节点。

此思路的问题在于需要维护大量变量,过程繁琐,容易出错。

新思路

  1. 开一个数组作为静态链表,读入数据,初始化链表
  2. 从头结点开始遍历链表,记录有效节点数量,并且为每一个节点的属性order(用于表示节点在链表中的位置)赋值。无效节点的该属性为INF
  3. order为排序依据,对整个数组排序,有效节点都位于数组左侧
  4. 按照k划分组,组内反转
  5. 输出节点信息

代码

#include <iostream>
#include <cstdio>
#include <algorithm>

typedef long long LL;
#define INF 1 << 30
LL LLINF = ~(1ll << 63);
using namespace std;

const int maxn = 1000000;

struct Node
{
    int address;
    int data;
    int next;
    int ord;
    Node(): ord(INF) {}
}nodes[maxn];
bool cmp(Node n1, Node n2)
{
    return n1.ord < n2.ord;
}
bool cmp2(Node n1, Node n2)
{
    return n1.ord > n2.ord;
}
int main()
{
    int head, n ,k;
    scanf("%d%d%d", &head, &n, &k);

    int pos;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &pos);
        nodes[pos].address = pos;
        scanf("%d%d", &nodes[pos].data, &nodes[pos].next);
    }

    //找到有效节点个数,为ord属性赋值
    int cnt = 0;
    int p = head;
    while (p != -1)
    {
        nodes[p].ord = cnt++;
        p = nodes[p].next;
    }
    sort(nodes, nodes + maxn, cmp);

    //为每一个部分反转
    for (int i = 0; i + k <= cnt; i+=k)
    {
        sort(nodes+i, nodes+i+k, cmp2);
    }
    //输出
    for (int i = 0; i < cnt; i++)
    {
        printf("%05d %d ", nodes[i].address, nodes[i].data);
        if (i != cnt - 1) printf("%05d\n", nodes[i+1].address);
        else printf("-1\n");
    }
    
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值