Skip to content

Commit 77d6e98

Browse files
committed
优化0332重新安排行程 C 版本
遍历所有ticket查找机场为O(n), 修改为使用hash表查找.
1 parent 6b77db5 commit 77d6e98

File tree

1 file changed

+84
-46
lines changed

1 file changed

+84
-46
lines changed

problems/0332.重新安排行程.md

Lines changed: 84 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -652,62 +652,100 @@ function findItinerary(tickets: string[][]): string[] {
652652
### C
653653

654654
```C
655-
char **result;
656-
bool *used;
657-
int g_found;
658-
659-
int cmp(const void *str1, const void *str2)
660-
{
661-
const char **tmp1 = *(char**)str1;
662-
const char **tmp2 = *(char**)str2;
663-
int ret = strcmp(tmp1[0], tmp2[0]);
664-
if (ret == 0) {
665-
return strcmp(tmp1[1], tmp2[1]);
655+
typedef struct {
656+
char *name; /* key */
657+
int cnt; /* 记录到达机场是否飞过了 */
658+
UT_hash_handle hh; /* makes this structure hashable */
659+
} to_airport_t;
660+
661+
typedef struct {
662+
char *name; /* key */
663+
to_airport_t *to_airports;
664+
UT_hash_handle hh; /* makes this structure hashable */
665+
} from_airport_t;
666+
667+
void to_airport_destroy(to_airport_t *airports) {
668+
to_airport_t *airport, *tmp;
669+
HASH_ITER(hh, airports, airport, tmp) {
670+
HASH_DEL(airports, airport);
671+
free(airport);
666672
}
667-
return ret;
668673
}
669674

670-
void backtracting(char *** tickets, int ticketsSize, int* returnSize, char *start, char **result, bool *used)
671-
{
672-
if (*returnSize == ticketsSize + 1) {
673-
g_found = 1;
674-
return;
675+
void from_airport_destroy(from_airport_t *airports) {
676+
from_airport_t *airport, *tmp;
677+
HASH_ITER(hh, airports, airport, tmp) {
678+
to_airport_destroy(airport->to_airports);
679+
HASH_DEL(airports, airport);
680+
free(airport);
681+
}
682+
}
683+
684+
int name_sort(to_airport_t *a, to_airport_t *b) {
685+
return strcmp(a->name, b->name);
686+
}
687+
688+
bool backtracking(from_airport_t *airports, int target_path_len, char **path,
689+
int path_len) {
690+
if (path_len == target_path_len) return true;
691+
692+
from_airport_t *from_airport = NULL;
693+
HASH_FIND_STR(airports, path[path_len - 1], from_airport);
694+
if (!from_airport) return false;
695+
696+
for (to_airport_t *to_airport = from_airport->to_airports;
697+
to_airport != NULL; to_airport = to_airport->hh.next) {
698+
if (to_airport->cnt == 0) continue;
699+
to_airport->cnt--;
700+
path[path_len] = to_airport->name;
701+
if (backtracking(airports, target_path_len, path, path_len + 1))
702+
return true;
703+
to_airport->cnt++;
675704
}
705+
return false;
706+
}
707+
708+
char **findItinerary(char ***tickets, int ticketsSize, int *ticketsColSize,
709+
int *returnSize) {
710+
from_airport_t *airports = NULL;
711+
712+
// 记录映射关系
676713
for (int i = 0; i < ticketsSize; i++) {
677-
if ((used[i] == false) && (strcmp(start, tickets[i][0]) == 0)) {
678-
result[*returnSize] = (char*)malloc(sizeof(char) * 4);
679-
memcpy(result[*returnSize], tickets[i][1], sizeof(char) * 4);
680-
(*returnSize)++;
681-
used[i] = true;
682-
/*if ((*returnSize) == ticketsSize + 1) {
683-
return;
684-
}*/
685-
backtracting(tickets, ticketsSize, returnSize, tickets[i][1], result, used);
686-
if (g_found) {
687-
return;
688-
}
689-
(*returnSize)--;
690-
used[i] = false;
714+
from_airport_t *from_airport = NULL;
715+
to_airport_t *to_airport = NULL;
716+
HASH_FIND_STR(airports, tickets[i][0], from_airport);
717+
if (!from_airport) {
718+
from_airport = malloc(sizeof(from_airport_t));
719+
from_airport->name = tickets[i][0];
720+
from_airport->to_airports = NULL;
721+
HASH_ADD_KEYPTR(hh, airports, from_airport->name,
722+
strlen(from_airport->name), from_airport);
723+
}
724+
HASH_FIND_STR(from_airport->to_airports, tickets[i][1], to_airport);
725+
if (!to_airport) {
726+
to_airport = malloc(sizeof(to_airport_t));
727+
to_airport->name = tickets[i][1];
728+
to_airport->cnt = 0;
729+
HASH_ADD_KEYPTR(hh, from_airport->to_airports, to_airport->name,
730+
strlen(to_airport->name), to_airport);
691731
}
732+
to_airport->cnt++;
692733
}
693-
return;
694-
}
695734

696-
char ** findItinerary(char *** tickets, int ticketsSize, int* ticketsColSize, int* returnSize){
697-
if (tickets == NULL || ticketsSize <= 0) {
698-
return NULL;
735+
// 机场排序
736+
for (from_airport *from_airport = airports; from_airport != NULL;
737+
from_airport = from_airport->hh.next) {
738+
HASH_SRT(hh, from_airport->to_airports, name_sort);
699739
}
700-
result = malloc(sizeof(char*) * (ticketsSize + 1));
701-
used = malloc(sizeof(bool) * ticketsSize);
702-
memset(used, false, sizeof(bool) * ticketsSize);
703-
result[0] = malloc(sizeof(char) * 4);
704-
memcpy(result[0], "JFK", sizeof(char) * 4);
705-
g_found = 0;
706-
*returnSize = 1;
707-
qsort(tickets, ticketsSize, sizeof(tickets[0]), cmp);
708-
backtracting(tickets, ticketsSize, returnSize, "JFK", result, used);
740+
741+
char **path = malloc(sizeof(char *) * (ticketsSize + 1));
742+
path[0] = "JFK"; // 起始机场
743+
backtracking(airports, ticketsSize + 1, path, 1);
744+
745+
from_airport_destroy(airports);
746+
709747
*returnSize = ticketsSize + 1;
710-
return result;
748+
return path;
711749
}
712750
```
713751

0 commit comments

Comments
 (0)