diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index ab144f43..d1fd46f6 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -652,62 +652,100 @@ function findItinerary(tickets: string[][]): string[] { ### C ```C -char **result; -bool *used; -int g_found; +typedef struct { + char *name; /* key */ + int cnt; /* 记录到达机场是否飞过了 */ + UT_hash_handle hh; /* makes this structure hashable */ +} to_airport_t; -int cmp(const void *str1, const void *str2) -{ - const char **tmp1 = *(char**)str1; - const char **tmp2 = *(char**)str2; - int ret = strcmp(tmp1[0], tmp2[0]); - if (ret == 0) { - return strcmp(tmp1[1], tmp2[1]); +typedef struct { + char *name; /* key */ + to_airport_t *to_airports; + UT_hash_handle hh; /* makes this structure hashable */ +} from_airport_t; + +void to_airport_destroy(to_airport_t *airports) { + to_airport_t *airport, *tmp; + HASH_ITER(hh, airports, airport, tmp) { + HASH_DEL(airports, airport); + free(airport); } - return ret; } -void backtracting(char *** tickets, int ticketsSize, int* returnSize, char *start, char **result, bool *used) -{ - if (*returnSize == ticketsSize + 1) { - g_found = 1; - return; +void from_airport_destroy(from_airport_t *airports) { + from_airport_t *airport, *tmp; + HASH_ITER(hh, airports, airport, tmp) { + to_airport_destroy(airport->to_airports); + HASH_DEL(airports, airport); + free(airport); } +} + +int name_sort(to_airport_t *a, to_airport_t *b) { + return strcmp(a->name, b->name); +} + +bool backtracking(from_airport_t *airports, int target_path_len, char **path, + int path_len) { + if (path_len == target_path_len) return true; + + from_airport_t *from_airport = NULL; + HASH_FIND_STR(airports, path[path_len - 1], from_airport); + if (!from_airport) return false; + + for (to_airport_t *to_airport = from_airport->to_airports; + to_airport != NULL; to_airport = to_airport->hh.next) { + if (to_airport->cnt == 0) continue; + to_airport->cnt--; + path[path_len] = to_airport->name; + if (backtracking(airports, target_path_len, path, path_len + 1)) + return true; + to_airport->cnt++; + } + return false; +} + +char **findItinerary(char ***tickets, int ticketsSize, int *ticketsColSize, + int *returnSize) { + from_airport_t *airports = NULL; + + // 记录映射关系 for (int i = 0; i < ticketsSize; i++) { - if ((used[i] == false) && (strcmp(start, tickets[i][0]) == 0)) { - result[*returnSize] = (char*)malloc(sizeof(char) * 4); - memcpy(result[*returnSize], tickets[i][1], sizeof(char) * 4); - (*returnSize)++; - used[i] = true; - /*if ((*returnSize) == ticketsSize + 1) { - return; - }*/ - backtracting(tickets, ticketsSize, returnSize, tickets[i][1], result, used); - if (g_found) { - return; - } - (*returnSize)--; - used[i] = false; + from_airport_t *from_airport = NULL; + to_airport_t *to_airport = NULL; + HASH_FIND_STR(airports, tickets[i][0], from_airport); + if (!from_airport) { + from_airport = malloc(sizeof(from_airport_t)); + from_airport->name = tickets[i][0]; + from_airport->to_airports = NULL; + HASH_ADD_KEYPTR(hh, airports, from_airport->name, + strlen(from_airport->name), from_airport); } + HASH_FIND_STR(from_airport->to_airports, tickets[i][1], to_airport); + if (!to_airport) { + to_airport = malloc(sizeof(to_airport_t)); + to_airport->name = tickets[i][1]; + to_airport->cnt = 0; + HASH_ADD_KEYPTR(hh, from_airport->to_airports, to_airport->name, + strlen(to_airport->name), to_airport); + } + to_airport->cnt++; } - return; -} -char ** findItinerary(char *** tickets, int ticketsSize, int* ticketsColSize, int* returnSize){ - if (tickets == NULL || ticketsSize <= 0) { - return NULL; + // 机场排序 + for (from_airport *from_airport = airports; from_airport != NULL; + from_airport = from_airport->hh.next) { + HASH_SRT(hh, from_airport->to_airports, name_sort); } - result = malloc(sizeof(char*) * (ticketsSize + 1)); - used = malloc(sizeof(bool) * ticketsSize); - memset(used, false, sizeof(bool) * ticketsSize); - result[0] = malloc(sizeof(char) * 4); - memcpy(result[0], "JFK", sizeof(char) * 4); - g_found = 0; - *returnSize = 1; - qsort(tickets, ticketsSize, sizeof(tickets[0]), cmp); - backtracting(tickets, ticketsSize, returnSize, "JFK", result, used); + + char **path = malloc(sizeof(char *) * (ticketsSize + 1)); + path[0] = "JFK"; // 起始机场 + backtracking(airports, ticketsSize + 1, path, 1); + + from_airport_destroy(airports); + *returnSize = ticketsSize + 1; - return result; + return path; } ```