LeetCode //C - 332. Reconstruct Itinerary

332. Reconstruct Itinerary

You are given a list of airline tickets where ticketsi = fromi, toi represent the departure and the arrival airports of one flight. Reconstruct the itinerary in order and return it.

All of the tickets belong to a man who departs from "JFK", thus, the itinerary must begin with "JFK". If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string.

  • For example, the itinerary "JFK", "LGA" has a smaller lexical order than "JFK", "LGB".

You may assume all tickets form at least one valid itinerary. You must use all the tickets once and only once.

Example 1:

Input: tickets = \["MUC","LHR","JFK","MUC","SFO","SJC","LHR","SFO"]
Output: "JFK","MUC","LHR","SFO","SJC"

Example 2:

Input: tickets = \["JFK","SFO","JFK","ATL","SFO","ATL","ATL","JFK","ATL","SFO"]
Output: "JFK","ATL","JFK","SFO","ATL","SFO"
Explanation: Another possible reconstruction is "JFK","SFO","ATL","JFK","ATL","SFO" but it is larger in lexical order.

Constraints:
  • 1 <= tickets.length <= 300
  • ticketsi.length == 2
  • f r o m i . l e n g t h = = 3 from_i.length == 3 fromi.length==3
  • t o i . l e n g t h = = 3 to_i.length == 3 toi.length==3
  • f r o m i a n d t o i c o n s i s t o f u p p e r c a s e E n g l i s h l e t t e r s . from_i and toi consist of uppercase English letters. fromiandtoiconsistofuppercaseEnglishletters.
  • f r o m i ! = t o i from_i != to_i fromi!=toi

From: LeetCode

Link: 332. Reconstruct Itinerary


Solution:

Ideas:
  • Deferred Memory Freeing: The nodes (Node*) in the adjacency list are no longer freed immediately within the DFS loop. Instead, they're freed only after the DFS traversal is complete, preventing use-after-free errors.
  • DFS Stack Handling: The stack is used to manage the DFS iteration, and nodes are correctly removed from the adjacency list as they are processed. The itinerary is built in reverse order and then freed once fully constructed.
Code:
c 复制代码
#define MAX_TICKETS 300
#define MAX_AIRPORTS 26 * 26 * 26 // Assuming three-letter airport codes
#define AIRPORT_CODE_LEN 4

// Node structure for adjacency list
typedef struct Node {
    char airport[AIRPORT_CODE_LEN];
    struct Node* next;
} Node;

// Function to insert an edge into the adjacency list, maintaining lexicographical order
void insertEdge(Node* adjList[], char* from, char* to) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    strcpy(newNode->airport, to);
    newNode->next = NULL;

    int index = (from[0] - 'A') * 26 * 26 + (from[1] - 'A') * 26 + (from[2] - 'A');

    if (adjList[index] == NULL || strcmp(adjList[index]->airport, to) > 0) {
        newNode->next = adjList[index];
        adjList[index] = newNode;
    } else {
        Node* current = adjList[index];
        while (current->next != NULL && strcmp(current->next->airport, to) < 0) {
            current = current->next;
        }
        newNode->next = current->next;
        current->next = newNode;
    }
}

// Iterative DFS using a stack to build the itinerary
void dfs(char* airport, Node* adjList[], char** itinerary, int* index) {
    char* stack[MAX_TICKETS + 1];
    int stackSize = 0;

    stack[stackSize++] = airport;

    while (stackSize > 0) {
        char* currentAirport = stack[stackSize - 1];
        int idx = (currentAirport[0] - 'A') * 26 * 26 + (currentAirport[1] - 'A') * 26 + (currentAirport[2] - 'A');

        if (adjList[idx] != NULL) {
            Node* nextNode = adjList[idx];
            stack[stackSize++] = nextNode->airport;
            adjList[idx] = nextNode->next;
            // Do not free nextNode here; defer the free operation until the end
        } else {
            itinerary[(*index)--] = stack[--stackSize];
        }
    }
}

// Function to find the itinerary from the list of tickets
char** findItinerary(char*** tickets, int ticketsSize, int* ticketsColSize, int* returnSize) {
    Node* adjList[MAX_AIRPORTS] = {NULL};

    // Populate the adjacency list with the tickets
    for (int i = 0; i < ticketsSize; i++) {
        insertEdge(adjList, tickets[i][0], tickets[i][1]);
    }

    char** itinerary = (char**)malloc((ticketsSize + 1) * sizeof(char*));
    int index = ticketsSize;
    dfs("JFK", adjList, itinerary, &index);

    // Freeing nodes after DFS traversal is complete
    for (int i = 0; i < MAX_AIRPORTS; i++) {
        Node* current = adjList[i];
        while (current) {
            Node* next = current->next;
            free(current->airport);
            free(current);
            current = next;
        }
    }

    *returnSize = ticketsSize + 1;
    return itinerary;
}
相关推荐
微尘hjx7 小时前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
小向是个Der7 小时前
嵌入式进阶——MCU上电后的动作
c语言·单片机·mcu·学习·链接脚本
bkspiderx10 小时前
基于Socket的广播通信及C语言实现详解
c语言·开发语言·socket·广播·socket的广播通信
小蒋观天下11 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
WBluuue12 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂12 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode
澳鹏Appen13 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
benjormin14 小时前
Java数据结构 二叉搜索树
数据结构·算法
人工智能培训14 小时前
知识图谱:结构化表达实体与关系的知识组织技术
大数据·人工智能·算法·重构·生活·知识图谱