Skip to main content
4 of 4
added 75 characters in body
G. Sliepen
  • 69.3k
  • 3
  • 75
  • 180

As already mentioned, you can do this in a one-pass algorithm. You only need to keep track of whether you have seen a character before, and what the position of its first occurence is. Here is a possible implementation:

#include <algorithm>
#include <array>
#include <climits>
#include <cstdint>
#include <string>

std::size_t FirstOccurrenceOfUniqueChar(const std::string& s) {
    std::array<bool, 1 << CHAR_BIT> seen{};
    std::array<std::size_t, 1 << CHAR_BIT> pos;
    pos.fill(s.npos);

    for (std::size_t i = 0; i < s.size(); ++i) {
        auto ch = static_cast<unsigned char>(s[i]);
        pos[ch] = seen[ch] ? s.npos : i;
        seen[ch] = true;
    }

    return *std::min_element(pos.begin(), pos.end());
}

Note that in the above code, only two std::arrays are used; since there are only a fixed number of characters, you can use a fixed-size container instead of the slower std::list and std::unordered_map.

Also note that this version returns a std::size_t; this is necessary to support strings longer than an int can represent. Also, std::string::npos is used to indicate that there is no unique character. It's the largest possible value of std::size_t, which is very convenient here.

Also, if you cast std::string::npos to an int, it will become -1.

G. Sliepen
  • 69.3k
  • 3
  • 75
  • 180