LeetCode //C - 332. Reconstruct Itinerary

332. Reconstruct Itinerary

You are given a list of airline tickets where tickets[i] = [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
  • tickets[i].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;
}
相关推荐
一匹电信狗21 分钟前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
鱼跃鹰飞1 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
梵刹古音2 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
筵陌2 小时前
算法:模拟
算法
梵刹古音2 小时前
【C语言】 结构化编程与选择结构
c语言·开发语言·嵌入式
We་ct3 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia13 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo3 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
爱编码的小八嘎3 小时前
C语言对话-22.想睡觉,偶然
c语言
民乐团扒谱机3 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳