LeetCode 791 自定義字串排序
阿新 • • 發佈:2021-10-06
思路一
根據字串S
構建對映表,對映表用一個長度為26的陣列表示。下標為i
的內容表示字元'a' + i
在S
中出現的位置。比如S = "cba"
,則對映表如下所示。
g_orderMap[0] = 2;
g_orderMap[1] = 1;
g_orderMap[2] = 0;
...
隨後將字串T
中所有在S
中出現的字元移動到T
的前面,不在S
中出現的字元移動到T
的後面。比如T = "defgabc"
,則移動後為T = "abcgfed"
。注意這只是其中一種移動方法,題目對不在S
中出現的字元的相對順序沒有做要求。所以T
中所有不在S
中出現的字元的順序可以不用理會。
最後呼叫qsort
對T
的前半部分按照S
static int g_orderMap[26]; static void BuildOrderMap(const char *s) { int index = 0; memset(g_orderMap, -1, sizeof(int) * 26); while (*s != '\0') { g_orderMap[*s - 'a'] = index; ++index; ++s; } } // 將在order串中出現的字元移到字串前;未出現的移到字串後 static void DivideStr(char *result, int *endPos) { int len = strlen(result); int left = 0; int right = len - 1; char *temp = NULL; int tempLen = sizeof(char) * len; temp = (char *)malloc(tempLen + 1); if (temp == NULL) { return; } memset(temp, 0, tempLen + 1); for (int i = 0; i < len; ++i) { if (g_orderMap[result[i] - 'a'] > -1) { temp[left++] = result[i]; } else { temp[right--] = result[i]; } } *endPos = left; memcpy(result, temp, tempLen + 1); free(temp); } static int cmp(const void *a, const void *b) { const char *pa = (char *)a; const char *pb = (char *)b; int idxA = (int)(*pa - 'a'); int idxB = (int)(*pb - 'a'); return g_orderMap[idxA] - g_orderMap[idxB]; } char *customSortString(char *s, char *t){ char *result = NULL; int len = strlen(t); int endPos = 0; result = (char *)malloc(len + 1); if (result == NULL) { return NULL; } memset(result, 0, len + 1); memcpy(result, t, len); BuildOrderMap(s); DivideStr(result, &endPos); qsort(result, endPos, sizeof(char), cmp); return result; }
思路二
看了一下題解,發現題解的思路更加巧妙。先統計T
串中各個字元出現的次數,然後遍歷S
串,根據S
串中字元的順序逐個新增字元到結果字串中。
char *customSortString(char *S, char *T) { int idx = 0; int count[26]; int len = strlen(T); char *result = NULL; result = (char *)malloc(len + 1); if (result == NULL) { return NULL; } memset(result, 0, len + 1); memset(count, 0, sizeof(int) * 26); for (int i = 0; i < len; ++i) { count[T[i] - 'a']++; } while (*S != '\0') { while (count[*S - 'a'] > 0) { result[idx++] = *S; count[*S - 'a']--; } S++; } // 將不在S串中出現的字元新增到result的末尾 for (int i = 0; i < 26; ++i) { while (count[i] > 0) { result[idx++] = (char)('a' + i); count[i]--; } } return result; }