Подход
Два прохода: частоты, затем первый с count === 1.
function firstUniqueChar(s) {
const freq = new Map();
for (const ch of s) freq.set(ch, (freq.get(ch) || 0) + 1);
for (const ch of s) {
if (freq.get(ch) === 1) return ch;
}
return null;
}
firstUniqueChar('swiss');
Детали
for…of по строке учитывает code points лучше, чем индекс по UTF-16 surrogates в простых случаях; для полной Unicode-сегментации нужен Intl.Segmenter.
Итог
Map/объект частот + второй проход — O(n) по времени.