Find Anagram Mappings

Updated on 27 May, 2025
Find Anagram Mappings header image

Problem Statement

In this problem, two integer arrays nums1 and nums2 are given. Here, nums2 is designated as an anagram of nums1, which implies that nums2 contains the same elements as nums1 but potentially in a different order. The task involves creating a 'mapping' array where for each index i in nums1, mapping[i] will represent the index j in nums2 where the ith element of nums1 is located. Given the nature of anagrams and the possibility of duplicate elements, multiple valid mapping arrays might exist, and any valid mapping is an acceptable solution.

Examples

Example 1

Input:

nums1 = [12,28,46,32,50], nums2 = [50,12,32,46,28]

Output:

[1,4,3,2,0]

Explanation:

As mapping[0] = 1 because the 0th element of nums1 appears at nums2[1], and mapping[1] = 4 because the 1st element of nums1 appears at nums2[4], and so on.

Example 2

Input:

nums1 = [84,46], nums2 = [84,46]

Output:

[0,1]

Constraints

  • 1 <= nums1.length <= 100
  • nums2.length == nums1.length
  • 0 <= nums1[i], nums2[i] <= 105
  • nums2 is an anagram of nums1.

Approach and Intuition

  1. Given the constraints and definitions:

    • Each element in nums1 has a corresponding match in nums2 due to the anagram condition.
    • The task essentially is a search problem where for every element in nums1, we need to find its corresponding index in nums2.
  2. To construct the solution:

    • Create a dictionary to track the indices of elements from nums2. If an element appears multiple times, store all its indices.
    • Iterate through each element in nums1 and for each element:
      • Retrieve and pop the first available index from the list of indices in the dictionary. This ensures each index is used only once, which is crucial when handling duplicates.
  3. Consider an implementation that is efficient given the problem's constraints:

    • Utilize a dictionary to achieve an amortized lookup time of O(1) for index retrieval.
    • Maintaining lists of indices for each element allows handling duplicates effectively by popping an index each time it's matched with an element in nums1.

This approach optimizes searching and mapping process by effectively using a dictionary, accommodating conditions like varying order of elements and duplicates neatly within the provided constraints.

Solutions

  • C++
  • Java
cpp
class Solution {
public:
    const int shiftBits = 7;
    const int maskLastBits = (1 << shiftBits) - 1;
    
    vector<int> findAnagramMappings(vector<int>& A, vector<int>& B) {
        for (int idx = 0; idx < A.size(); idx++) {
            A[idx] = (A[idx] << shiftBits) + idx;
            B[idx] = (B[idx] << shiftBits) + idx;
        }
        
        sort(A.begin(), A.end());
        sort(B.begin(), B.end());
        
        vector<int> result(A.size());
        for (int idx = 0; idx < A.size(); idx++) {
            result[A[idx] & maskLastBits] = (B[idx] & maskLastBits);
        }

        return result;
    }
};

The code provides a solution for finding anagram mappings between two vectors, A and B, where each vector contains integer elements. The mapping is determined by the position of elements from A in B. Each element in the result vector corresponds to the index of the element in B that is an anagram of the element in A at the same index.

  • The code defines two constants, shiftBits and maskLastBits, to manipulate indices and values during sorting for correlation.
  • Each element in both A and B is re-encoded by shifting the element's value left by seven bits and then adding the original index. This encoding allows the sorting of vectors based on the original values while preserving the index information.
  • After re-encoding, both vectors A and B are sorted.
  • A result vector of the same size as A and B is prepared. The code then decodes the sorted lists using bitwise AND with maskLastBits to extract the original indices. The index from B (decoded) is placed at the index from A (decoded) in the result vector.

This method efficiently maps the indices of vector A to the corresponding indices in vector B where similar elements exist, leveraging bit manipulation and sorting.

java
class Solution {
  final int shiftAmount = 7;
  final int mask = (1 << shiftAmount) - 1;

  public int[] getAnagramMappings(int[] array1, int[] array2) {
    // Embed the index with the element
    for (int i = 0; i < array1.length; i++) {
      array1[i] = (array1[i] << shiftAmount) + i;
      array2[i] = (array2[i] << shiftAmount) + i;
    }

    // Sort arrays to align the original elements
    Arrays.sort(array1);
    Arrays.sort(array2);

    // Result array for storing mappings
    int[] resultMappings = new int[array1.length];
    for (int i = 0; i < array1.length; i++) {
      // Extract original indices and map them
      resultMappings[array1[i] & mask] = (array2[i] & mask);
    }

    return resultMappings;
  }
}

This solution in Java outlines a method to find anagram mappings between two integer arrays. The goal is to identify the indices of elements in array1 that correspond to the elements in array2 where both arrays are anagrams of each other. To achieve this, the logic involves manipulating and sorting data to align the arrays based on the values of the elements while also tracking their original positions. Follow these steps to understand the implementation:

  1. The method getAnagramMappings takes two integer arrays array1 and array2 as parameters.

  2. First, the code combines each element in the arrays with its respective index. This combination makes sorting the arrays based on the elements' values easier without losing the index information. Here, bitwise left shift and addition are used to embed the index with the element.

  3. Next, both arrays are sorted. This sorting is based on the newly computed values from the previous step, which ensures that the actual values of the elements dictate the order post-sort.

  4. A result array resultMappings is initialized to store the final mappings of indices. It is of the same length as input arrays.

  5. Finally, the code iterates through the sorted arrays. Using bitwise AND operation with a mask, it extracts the original indices from the encoded values and maps them accordingly to reconstruct the index mapping between the two arrays.

This method effectively finds and records index mappings between two arrays that are anagrams of each other, relying on encoding indices and elements together, sorting, and then decoding them to achieve the correct mapping.

Comments

No comments yet.