<p>Given a string array <code>words</code>, return <em>an array of all characters that show up in all strings within the </em><code>words</code><em> (including duplicates)</em>. You may return the answer in <strong>any order</strong>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> words = ["bella","label","roller"]
<strong>Output:</strong> ["e","l","l"]
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> words = ["cool","lock","cook"]
<strong>Output:</strong> ["c","o"]
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= words.length &lt;= 100</code></li>
	<li><code>1 &lt;= words[i].length &lt;= 100</code></li>
	<li><code>words[i]</code> consists of lowercase English letters.</li>
</ul>

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        // We need to build a lookup table from the smallest word
        size_t sWI = 0;

        {
            size_t minSize = std::numeric_limits<size_t>::max();
            for(int i = 0; i < words.size(); ++i) {
                const auto& w = words[i];
                if(minSize > w.size()) {
                    sWI = i;
                    minSize = w.size();
                }
            }
        }

        std::map<char,int> charLookup;
        for(const auto& c : words[sWI]) {
            charLookup[c] += 1;
        }

        // Loop through everything other than sWI and compare . . .
        for(int i = 0; i < words.size(); ++i) {
            if(i == sWI) continue;

            // Let's try not to copy the unordered_map?
            auto& word = words[i];
            std::ranges::sort(word);

            int charIndex = 0;
            std::set<char> deletedChars;
            for(auto& [k,v] : charLookup) {
                int charCount = 0;
                for(int i = charIndex; i < word.size(); ++i) {
                    if(word[i] > k) {
                        break;
                    }
                    if(word[i] == k) {
                        ++charCount;
                        charIndex = i;
                    }
                }
                if(charCount == 0) {
                    deletedChars.insert(k);
                } else {
                    v = std::min(charCount, v);
                }
            }

            for(const auto& c : deletedChars) {
                // std::cout << "Deleted char: " << c << "\n";
                charLookup.erase(c);
            }
        }

        // Finally!
        std::vector<string> ans;
        for(auto& [k,v] : charLookup) {
            for(int i = 0; i < v; ++i) {
                ans.push_back(std::string{k});
            }
        }

        return ans;
    }
};
12700