Find Resultant Array After Removing Anagrams

🏠 ⬅️ ➡️

You are given a 0-indexed string array words, where words[i] consists of lowercase English letters.

In one operation, select any index i such that 0 < i < words.length and words[i - 1] and words[i] are anagrams, and delete words[i] from words. Keep performing this operation as long as you can select an index that satisfies the conditions.

Return words after performing all operations. It can be shown that selecting the indices for each operation in any arbitrary order will lead to the same result.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase using all the original letters exactly once. For example, "dacb " is an anagram of "abdc ".

Example 1:

Input: words = [ "abba ", "baba ", "bbaa ", "cd ", "cd "] Output: [ "abba ", "cd "] Explanation: One of the ways we can obtain the resultant array is by using the following operations: - Since words[2] = "bbaa " and words[1] = "baba " are anagrams, we choose index 2 and delete words[2]. Now words = [ "abba ", "baba ", "cd ", "cd "]. - Since words[1] = "baba " and words[0] = "abba " are anagrams, we choose index 1 and delete words[1]. Now words = [ "abba ", "cd ", "cd "]. - Since words[2] = "cd " and words[1] = "cd " are anagrams, we choose index 2 and delete words[2]. Now words = [ "abba ", "cd "]. We can no longer perform any operations, so [ "abba ", "cd "] is the final answer.

Example 2:

Input: words = [ "a ", "b ", "c ", "d ", "e "] Output: [ "a ", "b ", "c ", "d ", "e "] Explanation: No two adjacent strings in words are anagrams of each other, so no operations are performed.

Constraints:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 10
  • words[i] consists of lowercase English letters.

Note: This problem is from LeetCode.
Compiled
Executed
Correct
program main
    implicit none

    character(len=10), dimension(:), allocatable :: words
    integer :: i, j

    allocate(words(5))
    words(1) = 'abba'
    words(2) = 'baba'
    words(3) = 'bbaa'
    words(4) = 'cd'
    words(5) = 'cd'

    do while (any(words(2:) == words(1:-1)))
        do i = 2, size(words)-1
            if (words(i-1) == words(i) .and. words(i+1) == words(i)) then
                deallocate(words(i))
                exit
            end if
        end do
    end do

    print '(A)', words

end program main
Compiled
Executed
Correct
program anagram_strings
      implicit none

      integer, parameter :: MAX_WORDS = 100
      integer, parameter :: MAX_LEN = 10

      character(len=MAX_LEN), dimension(MAX_WORDS) :: words
      integer :: n_words, i, j

      ! Read the input
      read(*,*) n_words
      do i = 1, n_words
        read(*,*) words(i)
      end do

      ! Sort the words
      do i = 1, n_words - 1
        do j = i + 1, n_words
          if (sorted(words(i), words(j))) then
            call swap(words(i), words(j))
          end if
        end do
      end do

      ! Print the result
      do i = 1, n_words
        write(*,*) words(i)
      end do

      contains

        ! Swap two strings
        subroutine swap(a, b)
          character(len=*), intent(inout) :: a, b
          character(len=len(a)) :: temp

          temp = a
          a = b
          b = temp
        end subroutine swap

        ! Check if two strings are sorted
        function sorted(a, b) result(sorted)
          character(len=*), intent(in) :: a, b
          logical :: sorted

          sorted = .true.
          do i = 1, len(a)
            if (a(i:i) < b(i:i)) then
              sorted = .false.
              exit
            end if
          end do
        end function sorted

      end program anagram_strings
🌐 Data from online sources
def anagramOperations(words):
    i = 1
    while i < len(words):
        word1 = sorted(words[i])
        word2 = sorted(words[i - 1])
        if word1 == word2:
            del words[i]
        else:
            i += 1
    return words
The algorithm iterates through the input array `words` starting from index 1. For each index `i` it checks if `words[i]` and `words[i-1]` are anagrams by sorting the characters within the two strings and comparing if they are equal (sorting and comparing their characters arrays in Java and JavaScript). If they are anagrams, it removes `words[i]` from the array and decrements index `i`. If not, it increments `i`. This continues until `i` reaches the end of the array. The resulting array will have no adjacent strings that are anagrams, since it iterated through all adjacent pairs and removed anagrams where possible.
🌐 Data from online sources
#include <vector>
#include <string>
#include <algorithm>

std::vector<std::string> anagramOperations(std::vector<std::string> &words) {
    for (int i = 1; i < words.size(); ++i) {
        std::string s1 = words[i];
        std::string s2 = words[i - 1];
        std::sort(s1.begin(), s1.end());
        std::sort(s2.begin(), s2.end());
        if (s1 == s2) {
            words.erase(words.begin() + i);
            --i;
        }
    }
    return words;
}
The algorithm iterates through the input array `words` starting from index 1. For each index `i` it checks if `words[i]` and `words[i-1]` are anagrams by sorting the characters within the two strings and comparing if they are equal (sorting and comparing their characters arrays in Java and JavaScript). If they are anagrams, it removes `words[i]` from the array and decrements index `i`. If not, it increments `i`. This continues until `i` reaches the end of the array. The resulting array will have no adjacent strings that are anagrams, since it iterated through all adjacent pairs and removed anagrams where possible.