Find Resultant Array After Removing Anagrams

easy array hash table string sorting

Problem

You are given a string array words. In one operation you may pick an index i (with 0 < i < words.length) where words[i−1] and words[i] are anagrams, and delete words[i]. Repeat while any such index exists, then return the remaining words. Two strings are anagrams when they use exactly the same letters with the same counts. The result is the same regardless of the order operations are applied.

Inputwords = ["abba","baba","bbaa","cd","cd"]
Output["abba","cd"]
"abba", "baba", "bbaa" are all anagrams, so only the first survives; the two "cd"s collapse to one.

def removeAnagrams(words):
    result = []                       # words that survive
    for w in words:
        sig = "".join(sorted(w))      # signature = letters sorted
        # drop w if it is an anagram of the last kept word
        if result and "".join(sorted(result[-1])) == sig:
            continue
        result.append(w)              # keep this word
    return result
function removeAnagrams(words) {
  const sig = (w) => w.split("").sort().join(""); // sorted letters
  const result = [];                  // words that survive
  for (const w of words) {
    // drop w if it is an anagram of the last kept word
    if (result.length && sig(result[result.length - 1]) === sig(w)) {
      continue;
    }
    result.push(w);                   // keep this word
  }
  return result;
}
List<String> removeAnagrams(String[] words) {
    List<String> result = new ArrayList<>();   // survivors
    for (String w : words) {
        // drop w if it is an anagram of the last kept word
        if (!result.isEmpty() &&
            sig(result.get(result.size() - 1)).equals(sig(w))) {
            continue;
        }
        result.add(w);                          // keep this word
    }
    return result;
}

String sig(String w) {                          // sorted letters
    char[] c = w.toCharArray();
    Arrays.sort(c);
    return new String(c);
}
vector<string> removeAnagrams(vector<string>& words) {
    auto sig = [](string w) { sort(w.begin(), w.end()); return w; };
    vector<string> result;                       // survivors
    for (const string& w : words) {
        // drop w if it is an anagram of the last kept word
        if (!result.empty() && sig(result.back()) == sig(w)) {
            continue;
        }
        result.push_back(w);                     // keep this word
    }
    return result;
}
Time: O(n · L log L) Space: O(L)