Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions problems/3838-weighted-word-mapping/analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 3838. Weighted Word Mapping

[LeetCode Link](https://leetcode.com/problems/weighted-word-mapping/)

Difficulty: Easy
Topics: Array, String, Simulation
Acceptance Rate: 88.1%

## Hints

### Hint 1

This is a pure simulation problem — there is no clever trick or hidden data
structure. Read the rules carefully and translate each rule directly into code.
Think about what information you need for a single word before worrying about
the whole array.

### Hint 2

For one word you need its *weight*: the sum of `weights[i]` for each character,
where `i` is the position of the character in the alphabet. Recall that for a
lowercase byte `c`, the index is `c - 'a'`. Once you have the weight, the
problem tells you to reduce it with `weight % 26`.

### Hint 3

The only part that trips people up is the *reverse alphabetical* mapping:
`0 -> 'z'`, `1 -> 'y'`, ..., `25 -> 'a'`. Notice that the index and the letter
move in opposite directions, and they always sum to 25 (`'z'` is index 25 from
`'a'`). So the mapped letter is simply `'z' - r`, or equivalently
`'a' + (25 - r)`. Build the answer one byte at a time and you are done.

## Approach

We process each word independently and build the result string character by
character.

1. **Compute the weight of a word.** Walk over its characters. For each
character `c`, its alphabet index is `c - 'a'`, so add `weights[c-'a']` to a
running sum. The constraints (word length ≤ 10, weight ≤ 100) mean this sum
easily fits in an `int`.

2. **Reduce modulo 26.** Let `r = weight % 26`. This gives a value in the range
`[0, 25]`.

3. **Map to a letter in reverse order.** The rule is `0 -> 'z'`, `1 -> 'y'`,
..., `25 -> 'a'`. Because index `r` and the target letter sum to the value of
`'z'` (index 25 above `'a'`), the mapped byte is `'z' - r`. For example
`r = 8` gives `'z' - 8 = 'r'`, matching the first example.

4. **Concatenate.** Append each mapped byte to a `[]byte` (or
`strings.Builder`) in word order, then convert to a string at the end.

Using a byte slice that we append to and convert once avoids repeated string
allocations, keeping the work proportional to the total number of characters.

Worked example for `words = ["abcd"]` with the third example's weights
`[7,5,3,4,...]`: weight = `7 + 5 + 3 + 4 = 19`, `19 % 26 = 19`, and
`'z' - 19 = 'g'`, so the answer is `"g"`. ✔

## Complexity Analysis

Time Complexity: O(N · L) where N is the number of words and L is the maximum
word length — we touch every character of every word exactly once. (Given the
constraints this is at most 100 · 10 = 1000 operations.)
Space Complexity: O(N) for the output string of one character per word, ignoring
the input. The per-word computation uses O(1) extra space.

## Edge Cases

- **Single-character words.** Words like `"a"` or `"c"` are valid; the weight is
just `weights[c-'a']`. Example 2 covers this.
- **Single word in the array.** With `words.length == 1` the output is a single
character (Example 3). Make sure the loop and the builder handle a length-one
result.
- **Weight divisible by 26 (`r == 0`).** This maps to `'z'`, the start of the
reverse alphabet. It is easy to accidentally produce a wrong byte here, so it
is worth a dedicated test.
- **Maximum-weight words.** The largest single word weight is 10 · 100 = 1000,
which is well within `int` range — no overflow concern, but good to confirm
the modulo arithmetic is correct for large sums.
81 changes: 81 additions & 0 deletions problems/3838-weighted-word-mapping/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
number: "3838"
frontend_id: "3838"
title: "Weighted Word Mapping"
slug: "weighted-word-mapping"
difficulty: "Easy"
topics:
- "Array"
- "String"
- "Simulation"
acceptance_rate: 8810.3
is_premium: false
created_at: "2026-06-13T04:58:37.349563+00:00"
fetched_at: "2026-06-13T04:58:37.349563+00:00"
link: "https://leetcode.com/problems/weighted-word-mapping/"
date: "2026-06-13"
---

# 3838. Weighted Word Mapping

You are given an array of strings `words`, where each string represents a word containing lowercase English letters.

You are also given an integer array `weights` of length 26, where `weights[i]` represents the weight of the `ith` lowercase English letter.

The **weight** of a word is defined as the **sum** of the weights of its characters.

For each word, take its weight modulo 26 and map the result to a lowercase English letter using reverse alphabetical order (`0 -> 'z', 1 -> 'y', ..., 25 -> 'a'`).

Return a string formed by concatenating the mapped characters for all words in order.



**Example 1:**

**Input:** words = ["abcd","def","xyz"], weights = [5,3,12,14,1,2,3,2,10,6,6,9,7,8,7,10,8,9,6,9,9,8,3,7,7,2]

**Output:** "rij"

**Explanation:**

* The weight of `"abcd"` is `5 + 3 + 12 + 14 = 34`. The result modulo 26 is `34 % 26 = 8`, which maps to `'r'`.
* The weight of `"def"` is `14 + 1 + 2 = 17`. The result modulo 26 is `17 % 26 = 17`, which maps to `'i'`.
* The weight of `"xyz"` is `7 + 7 + 2 = 16`. The result modulo 26 is `16 % 26 = 16`, which maps to `'j'`.



Thus, the string formed by concatenating the mapped characters is `"rij"`.

**Example 2:**

**Input:** words = ["a","b","c"], weights = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

**Output:** "yyy"

**Explanation:**

Each word has weight 1. The result modulo 26 is `1 % 26 = 1`, which maps to `'y'`.

Thus, the string formed by concatenating the mapped characters is `"yyy"`.

**Example 3:**

**Input:** words = ["abcd"], weights = [7,5,3,4,3,5,4,9,4,2,2,7,10,2,5,10,6,1,2,2,4,1,3,4,4,5]

**Output:** "g"

**Explanation:​​​​​​​**

The weight of `"abcd"` is `7 + 5 + 3 + 4 = 19`. The result modulo 26 is `19 % 26 = 19`, which maps to `'g'`.

Thus, the string formed by concatenating the mapped characters is `"g"`.



**Constraints:**

* `1 <= words.length <= 100`
* `1 <= words[i].length <= 10`
* `weights.length == 26`
* `1 <= weights[i] <= 100`
* `words[i]` consists of lowercase English letters.
21 changes: 21 additions & 0 deletions problems/3838-weighted-word-mapping/solution_daily_20260613.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

// 3838. Weighted Word Mapping
//
// Pure simulation. For each word we sum the weights of its characters
// (weights[c-'a']), reduce the sum modulo 26, then map the result r to a
// lowercase letter in reverse alphabetical order (0 -> 'z', ..., 25 -> 'a').
// Since index r and its target letter sum to the value of 'z', the mapped byte
// is simply 'z' - r. Results are appended to a byte slice and converted once.
func weightedWordMapping(words []string, weights []int) string {
result := make([]byte, 0, len(words))
for _, word := range words {
weight := 0
for i := 0; i < len(word); i++ {
weight += weights[word[i]-'a']
}
r := weight % 26
result = append(result, byte('z'-r))
}
return string(result)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import "testing"

func TestWeightedWordMapping(t *testing.T) {
tests := []struct {
name string
words []string
weights []int
expected string
}{
{
name: "example 1: multiple multi-char words",
words: []string{"abcd", "def", "xyz"},
weights: []int{5, 3, 12, 14, 1, 2, 3, 2, 10, 6, 6, 9, 7, 8, 7, 10, 8, 9, 6, 9, 9, 8, 3, 7, 7, 2},
expected: "rij",
},
{
name: "example 2: single-char words, all weights 1",
words: []string{"a", "b", "c"},
weights: []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
expected: "yyy",
},
{
name: "example 3: single word",
words: []string{"abcd"},
weights: []int{7, 5, 3, 4, 3, 5, 4, 9, 4, 2, 2, 7, 10, 2, 5, 10, 6, 1, 2, 2, 4, 1, 3, 4, 4, 5},
expected: "g",
},
{
name: "edge case: weight divisible by 26 maps to 'z'",
words: []string{"a"},
weights: []int{26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// weight = 26, 26 % 26 = 0 -> 'z'
expected: "z",
},
{
name: "edge case: max-length word with max weights",
words: []string{"aaaaaaaaaa"},
weights: []int{100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// weight = 10 * 100 = 1000, 1000 % 26 = 12 -> 'z' - 12 = 'n'
expected: "n",
},
{
name: "edge case: word using last letter of alphabet",
words: []string{"z"},
weights: []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25},
// weight = 25, 25 % 26 = 25 -> 'z' - 25 = 'a'
expected: "a",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := weightedWordMapping(tt.words, tt.weights)
if result != tt.expected {
t.Errorf("weightedWordMapping(%v, ...) = %q, want %q", tt.words, result, tt.expected)
}
})
}
}