PAT甲级1133Splitting A Linked List

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805346776760320

题解

题目要求

给1个有n(不超过1e5)个结点的单向链表和数字k(不超过1e3),链表的值属于[-1e5,1e5]要求将链表改为(或输出):负数结点出现在正数结点之前,值属于[0,k]的结点出现在值大于k的结点之前,其余不变##

注意点

  • PAT中的这种链表适合用数组形式的链表
  • PAT里的链表和LeetCode里的链表(LeetCode里的链表是基于指针的)不太一样,因此操作也要适当调整
  • 不一定要修改链表结构,能按要求输出就可以

思路

用数组表示链表,然后遍历将链表里的结点分成3类(小于0的、0到k的、大于k的)并存入3个数组,然后按顺序遍历3个数组并输出

代码

// Problem: PAT Advanced 1133
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805346776760320
// Tags: Linked List

#include <iostream>
#include <vector>
using namespace std;

struct ListNode{
    int val;
    int next;
};

ListNode list[int(1e5) + 10];
vector<int> parts[3];

int main()
{
    // 获取输入
    int head, n, k; // 头结点地址、结点数量、k
    cin >> head >> n >> k;
    int address;
    for (int i = 0; i < n; i++){
        cin >> address;
        cin >> list[address].val >> list[address].next;
    }

    // 遍历链表将其中的结点分为3个部分
    int p = head;
    while(p != -1){
        int partIndex = 1;  // 默认为第2部分,即结点的值属于[0,k]
        if (list[p].val < 0)
            partIndex = 0;
        else if(list[p].val > k)
            partIndex = 2;
        parts[partIndex].push_back(p);
        p = list[p].next;
    }

    // 将划分好的3部分结点输出
    bool isFirstLine = true;
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < parts[i].size(); j++){
            if (isFirstLine){
                printf("%05d %d", parts[i][j], list[parts[i][j]].val);
                isFirstLine = false;
            }
            else
                printf(" %05d\n%05d %d", parts[i][j], parts[i][j], list[parts[i][j]].val);
        }
    }
    cout << " -1";
    return 0;
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


posted @ 2020-08-07 12:54  臭咸鱼  阅读(90)  评论(0编辑  收藏  举报