1 minute read

위상 정렬 연습용으로 찾은 문제 210. Course Schedule II.

typedef struct pr {
    int subjectCode;
    struct pr *next;
} COURSELIST;

typedef struct st {
    int NumPrerequisites;
    COURSELIST* after;
} COURSES;

COURSES *courses;
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize){
    int classTaken = 0;
    int *ret = calloc(numCourses, sizeof(int));
    courses = calloc(numCourses, sizeof(COURSES));
    for(int idx=0; idx<prerequisitesSize; idx++){
        int courseIdx = prerequisites[idx][0]; 
        int preIdx = prerequisites[idx][1];

        courses[courseIdx].NumPrerequisites += 1; //선수강과목 갯수 더해주고
        
        COURSELIST *newNext = calloc(1, sizeof(COURSELIST));  // 선수강과목의 '들으면 수강 할 수 있는 강의 리스트'에 추가해줌
        newNext->subjectCode = courseIdx;
        newNext->next = courses[preIdx].after;
        courses[preIdx].after = newNext;
    }
    int *preZeroIdxQueue = calloc(numCourses, sizeof(int));
    int pushPtr = 0;
    int popPtr = 0;
    for(int idx=0; idx < numCourses; idx++) {  // 선수강과목이 없는 과목들을 먼저 큐에 넣음
        if(courses[idx].NumPrerequisites == 0)
        {
            preZeroIdxQueue[pushPtr++] = idx;
        }
    }
    
    while(pushPtr > popPtr) {
        int courseIdx = preZeroIdxQueue[popPtr++];  // courseIdx를 수강했다.
        ret[classTaken++] = courseIdx;  // 큐에서 하나씩 빼서 정답에 담기
        COURSELIST *courList = courses[courseIdx].after;
        while(courList != 0){  // '들으면 수강할 수 있는 과목 리스트'를 돌면서
            int subJectIdx = courList->subjectCode;
            courses[subJectIdx].NumPrerequisites--;  // 선수강 과목 갯수를 -1 해줌 (하나 들었으니까)
            if(courses[subJectIdx].NumPrerequisites == 0) {  //선수강과목이 없어진 과목이 있다면
                preZeroIdxQueue[pushPtr++] = subJectIdx;  // 큐에 넣어준다
            }
            courList = courList->next;
        }
        
    }
    free(courses);
    free(preZeroIdxQueue);
    
    if(classTaken != numCourses) {
        *returnSize = 0;
    } else {
        *returnSize = classTaken;
    }
    
    return ret;
}
/*
0->1
0->2
1->3
2->3

0 : no pre -> 0 should have idx of 1, 2
1 : 0
2 : 0
3 : 1, 2

0
0 : -1
1 : no pre
2 : no pre
3 : 1, 2

1, 2
0: -1
1 : -1
2: -1
3 : 0

3

3
[[1,0],[1,2],[0,1]]
0->1
2->1
1->0
*/

위상 정렬도 queue를 사용해서 풀다보니 보통 자료구조 지원하는 언어 코드가 많았다. 생각해보니 linked list 순회해가며 free 해줬어야 하는데 안해도 통과되었다… 너그러운 리트코드…