LeetCode //C - 1203. Sort Items by Groups Respecting Dependencies

1203. Sort Items by Groups Respecting Dependencies

There are n items each belonging to zero or one of m groups where groupi is the group that the i-th item belongs to and it's equal to -1 if the i-th item belongs to no group. The items and the groups are zero indexed. A group can have no item belonging to it.

Return a sorted list of the items such that:

  • The items that belong to the same group are next to each other in the sorted list.
  • There are some relations between these items where beforeItemsi is a list containing all the items that should come before the i-th item in the sorted array (to the left of the i-th item).

Return any solution if there is more than one solution and return an empty list if there is no solution.

Example 1:

Input: n = 8, m = 2, group = -1,-1,1,0,0,1,0,-1, beforeItems = \[,6,5,6,3,6,\[\],\[\],\[\]]

Output: 6,3,4,1,5,2,0,7

Example 2:

Input: n = 8, m = 2, group = -1,-1,1,0,0,1,0,-1, beforeItems = \[,6,5,6,3,\[\],4,\[\]]

Output: \[\]

Explanation: This is the same as example 1 except that 4 needs to be before 6 in the sorted list.

Constraints:
  • 1 < = m < = n < = 3 ∗ 10 4 1 <= m <= n <= 3 * 10^4 1<=m<=n<=3∗104
  • group.length == beforeItems.length == n
  • -1 <= groupi <= m - 1
  • 0 <= beforeItemsi.length <= n - 1
  • 0 <= beforeItemsij <= n - 1
  • i != beforeItemsij
  • beforeItemsi does not contain duplicates elements.

From: LeetCode

Link: 1203. Sort Items by Groups Respecting Dependencies


Solution:

Ideas:

give every -1 item its own group, topologically sort both item-dependencies and group-dependencies, then output items group by group.

Code:
c 复制代码
#include <stdlib.h>
#include <string.h>

static int* topoSort(int nodes, int* head, int* to, int* next, int* indeg, int* returnCount) {
    int* q = (int*)malloc(sizeof(int) * nodes);
    int* order = (int*)malloc(sizeof(int) * nodes);
    int front = 0, back = 0, cnt = 0;

    for (int i = 0; i < nodes; i++) {
        if (indeg[i] == 0) q[back++] = i;
    }

    while (front < back) {
        int u = q[front++];
        order[cnt++] = u;

        for (int e = head[u]; e != -1; e = next[e]) {
            int v = to[e];
            indeg[v]--;
            if (indeg[v] == 0) q[back++] = v;
        }
    }

    free(q);

    if (cnt != nodes) {
        free(order);
        *returnCount = 0;
        return NULL;
    }

    *returnCount = cnt;
    return order;
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortItems(int n, int m, int* group, int groupSize,
               int** beforeItems, int beforeItemsSize,
               int* beforeItemsColSize, int* returnSize) {
    
    *returnSize = 0;

    int totalGroups = m;

    for (int i = 0; i < n; i++) {
        if (group[i] == -1) {
            group[i] = totalGroups++;
        }
    }

    int edgeCount = 0;
    for (int i = 0; i < n; i++) {
        edgeCount += beforeItemsColSize[i];
    }

    int* itemHead = (int*)malloc(sizeof(int) * n);
    int* groupHead = (int*)malloc(sizeof(int) * totalGroups);
    int* itemTo = (int*)malloc(sizeof(int) * edgeCount);
    int* itemNext = (int*)malloc(sizeof(int) * edgeCount);
    int* groupTo = (int*)malloc(sizeof(int) * edgeCount);
    int* groupNext = (int*)malloc(sizeof(int) * edgeCount);
    int* itemIndeg = (int*)calloc(n, sizeof(int));
    int* groupIndeg = (int*)calloc(totalGroups, sizeof(int));

    for (int i = 0; i < n; i++) itemHead[i] = -1;
    for (int i = 0; i < totalGroups; i++) groupHead[i] = -1;

    int itemEdges = 0, groupEdges = 0;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < beforeItemsColSize[i]; j++) {
            int pre = beforeItems[i][j];

            itemTo[itemEdges] = i;
            itemNext[itemEdges] = itemHead[pre];
            itemHead[pre] = itemEdges++;
            itemIndeg[i]++;

            if (group[pre] != group[i]) {
                groupTo[groupEdges] = group[i];
                groupNext[groupEdges] = groupHead[group[pre]];
                groupHead[group[pre]] = groupEdges++;
                groupIndeg[group[i]]++;
            }
        }
    }

    int itemCount = 0, groupCount = 0;
    int* itemOrder = topoSort(n, itemHead, itemTo, itemNext, itemIndeg, &itemCount);
    int* groupOrder = topoSort(totalGroups, groupHead, groupTo, groupNext, groupIndeg, &groupCount);

    if (!itemOrder || !groupOrder) {
        free(itemOrder);
        free(groupOrder);
        free(itemHead);
        free(groupHead);
        free(itemTo);
        free(itemNext);
        free(groupTo);
        free(groupNext);
        free(itemIndeg);
        free(groupIndeg);
        return (int*)malloc(0);
    }

    int* count = (int*)calloc(totalGroups + 1, sizeof(int));

    for (int i = 0; i < n; i++) {
        count[group[i] + 1]++;
    }

    for (int i = 1; i <= totalGroups; i++) {
        count[i] += count[i - 1];
    }

    int* pos = (int*)malloc(sizeof(int) * totalGroups);
    for (int i = 0; i < totalGroups; i++) {
        pos[i] = count[i];
    }

    int* bucket = (int*)malloc(sizeof(int) * n);

    for (int i = 0; i < n; i++) {
        int item = itemOrder[i];
        int g = group[item];
        bucket[pos[g]++] = item;
    }

    int* ans = (int*)malloc(sizeof(int) * n);
    int idx = 0;

    for (int i = 0; i < totalGroups; i++) {
        int g = groupOrder[i];
        for (int j = count[g]; j < count[g + 1]; j++) {
            ans[idx++] = bucket[j];
        }
    }

    *returnSize = n;

    free(itemOrder);
    free(groupOrder);
    free(itemHead);
    free(groupHead);
    free(itemTo);
    free(itemNext);
    free(groupTo);
    free(groupNext);
    free(itemIndeg);
    free(groupIndeg);
    free(count);
    free(pos);
    free(bucket);

    return ans;
}
相关推荐
水饺编程36 分钟前
第2章:Linux 基础,切换到超级用户
linux·c语言·汇编
y1su1 小时前
Leetcode 字符串模板
java·数据结构·算法·leetcode·职场和发展·动态规划
residual_fan2 小时前
船用柴油机动态机动工况故障诊断:控制感知仿射网络(CAAN)的技术实现
人工智能·算法·数据挖掘·数据分析
其实防守也摸鱼2 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
蓝悦无人机2 小时前
《Planning algorithms》读书笔记——第8章 反馈运动规划
算法·读书笔记·反馈运动规划
RaaS1003 小时前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构
CV爱数码3 小时前
CT 重建从零开始(五):ASTRA Toolbox 上手——几何、投影器与算法
图像处理·算法·计算机视觉·ct
TunerT_TQ3 小时前
超立方体Ramsey(openai/math 家族171)H11攻坚日志|D60–D69:Star分组重数、二幂坐标群、奇偶入射语义与Site‑Level候选计数形式化闭环
算法
Rabitebla3 小时前
【系统性学习笔记】Linux 权限篇(二):文件属性、权限修改与目录权限的底层逻辑
linux·c++·笔记·学习·算法
远离UE44 小时前
半拉格朗日学习笔记 动力学 实时渲染
人工智能·算法