3838. Weighted Word Mapping
題目 / Problem
中文
給你一個字串陣列 words,每個字串是由小寫英文字母組成的單字。
另外給你一個長度為 26 的整數陣列 weights,其中 weights[i] 代表第 i 個小寫字母的權重(weights[0] 是 'a' 的權重,weights[1] 是 'b' 的權重,依此類推)。
一個單字的「權重」定義為它所有字元權重的總和。
對每個單字,先把它的權重對 26 取餘數(modulo 26),再用反向字母順序把這個餘數對應到一個小寫字母:0 -> 'z'、1 -> 'y'、…、25 -> 'a'。
把所有單字依序對應到的字元串接起來,回傳這個字串。
English
You are given an array of strings words, each made of lowercase English letters.
You are also given an integer array weights of length 26, where weights[i] is the weight of the i-th lowercase letter (weights[0] for 'a', weights[1] for 'b', and so on).
The weight of a word is the sum of the weights of its characters.
For each word, take its weight modulo 26, then map that result to a lowercase letter using reverse alphabetical order: 0 -> 'z', 1 -> 'y', …, 25 -> 'a'.
Concatenate the mapped characters for all words in order and return the resulting string.
Constraints / 限制
- 1 <= words.length <= 100
- 1 <= words[i].length <= 10
- weights.length == 26
- 1 <= weights[i] <= 100
- words[i] 只含小寫英文字母 / consists of lowercase letters.
Worked example / 範例
words = ["abcd","def","xyz"], weights = [5,3,12,14,1,...]
- "abcd" → 5+3+12+14 = 34,34 % 26 = 8 → 'r'
- "def" → 14+1+2 = 17,17 % 26 = 17 → 'i'
- "xyz" → 7+7+2 = 16,16 % 26 = 16 → 'j'
Output: "rij"
名詞解釋 / Glossary
- 權重總和 / weight sum:把單字裡每個字元對應的權重加起來得到的數字。例如
"ab"的權重 =weights['a']+weights['b']。It is just an accumulated total. - 取餘數 / modulo (
%):%運算子回傳除法的餘數。例如34 % 26 = 8,因為34 = 26 × 1 + 8。Here it folds any large sum into the range0..25. - 字元算術 / character arithmetic:在 C/C++ 中字元其實是小整數(ASCII 碼)。
c - 'a'會把'a'變成0、'b'變成1…,剛好就是這個字母在weights裡的索引(index)。'z' - value則反過來,把一個數字轉回字母。 - 索引 / index:陣列中某個元素的位置編號,從
0開始。weights[c - 'a']就是用字母換算出來的索引去查它的權重。 - 指標 / pointer (C):在 C 裡
char *是一個指向字元的位址。字串就是一串字元,以'\0'(結尾標記)收尾。words[i]是第i個字串。 - 動態配置記憶體 / dynamic allocation (
malloc):C 不能回傳「自動長大」的字串,所以我們用malloc向系統要一塊指定大小的記憶體來存答案,呼叫者用完後負責free。
思路
最直接的想法就是照題目敘述一步一步模擬,因為資料量很小(最多 100 個單字,每個最多 10 個字母),完全不需要任何優化技巧。對每一個單字,我們從 0 開始累加,把單字裡每個字元 c 用 weights[c - 'a'] 查到權重後加進總和。c - 'a' 之所以正確,是因為字元在記憶體裡就是連續的整數編碼,'a' 減掉自己是 0、'b' 減 'a' 是 1,剛好對上 weights 的索引。累加完後對 26 取餘數,把總和「摺疊」進 0..25 的範圍。最後關鍵是反向對應:題目要 0 -> 'z'、25 -> 'a',注意到 'z' 的編碼比 'a' 大 25,所以 'z' - value 正好能把 0 變 'z'、把 25 變 'a'。把每個單字算出來的字元依序寫進答案字串即可。因為每個字元只被看過一次,這已經是最佳解。
The simplest idea is to simulate the description directly, and since the input is tiny (at most 100 words of at most 10 letters), no clever optimization is needed at all. For each word, start a running sum at 0 and, for every character c, add weights[c - 'a']. The expression c - 'a' works because characters are just small integer codes laid out consecutively: 'a' - 'a' is 0, 'b' - 'a' is 1, and so on — exactly the indices into weights. After summing, take the result modulo 26 to fold it into the range 0..25. The crucial final step is the reverse mapping: the problem wants 0 -> 'z' and 25 -> 'a', and since 'z' sits 25 codes above 'a', the expression 'z' - value turns 0 into 'z' and 25 into 'a' automatically. Write each word's mapped character into the answer in order. Each character is touched exactly once, so this is already optimal.
逐步走查 / Walkthrough
Input: words = ["abcd","def","xyz"], weights[0..] = a=5, b=3, c=12, d=14, e=1, f=2, ..., x=7, y=7, z=2
| Word / 單字 | 逐字累加 / per-char sum | sum | sum % 26 |
'z' - value |
char |
|---|---|---|---|---|---|
"abcd" |
5(a)+3(b)+12(c)+14(d) |
34 | 34%26 = 8 |
'z'-8 |
'r' |
"def" |
14(d)+1(e)+2(f) |
17 | 17%26 = 17 |
'z'-17 |
'i' |
"xyz" |
7(x)+7(y)+2(z) |
16 | 16%26 = 16 |
'z'-16 |
'j' |
- 結果字串逐步成長 / result grows:
"r"→"ri"→"rij" - 最後補上字串結尾標記
'\0'/ append the terminating'\0'. - Final output:
"rij"✅
Solution — C
// 演算法 / Algorithm:
// 對每個單字累加字元權重,sum % 26 得到 0..25,再用 'z'-value 反向對應成字母。
// For each word, sum its letter weights, take % 26, then map via 'z'-value (reverse order).
// 結果字串長度 = 單字數量,需動態配置記憶體回傳 / result length = number of words; malloc it.
char* mapWords(char** words, int wordsSize, int* weights, int weightsSize) {
// 配置 wordsSize+1 個位元組:每個單字一個字元,加上結尾的 '