BackmediumStringsInfosys

Galactic Transmission Correction Solution

Problem Statement

Given a transmission string S and a corrupted subsequence C (|C| ≤ |S|) consisting of characters that appear in S, determine the smallest number of adjacent‑swap operations required to reorder C so that its characters appear in the same relative order as they do in S. In one operation you may swap C[i] and C[i+1] for any valid i. It is guaranteed that C can be formed by selecting |C| characters from S in left‑to‑right order (i.e., each character of C matches a distinct occurrence in S). Return the minimum number of swaps as an integer.

Example 1
Input
S = "ABCDAB", C = "BACA"
Output
1

Explanation: Map each character of C to its earliest unused occurrence in S → positions [1,0,2,4]. The target order is [0,1,2,4]; one inversion (1,0) means one adjacent swap.

Example 2
Input
S = "GATACAG", C = "AGACA"
Output
1

Explanation: Corresponding indices are [1,0,3,4,5]; sorting gives [0,1,3,4,5]. Only the pair (1,0) is inverted, so one swap suffices.

Example 3
Input
S = "XYZXYZXYZ", C = "ZZYXXY"
Output
7

Explanation: Indices obtained: [2,5,0,1,4,3]. Counting inversions yields 7, which is the minimal number of adjacent swaps needed.

Constraints

  • 1 <= |S| <= 2*10^5
  • 1 <= |C| <= |S|
  • S and C contain only uppercase English letters
  • C is a subsequence of S (each character matches a distinct occurrence)
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Galactic Transmission Correction — Problem Statement & Solution Guide

StringsMediumMixed
TimeO(n log n)
|
SpaceO(n)

Problem Description

Given a transmission string S and a corrupted subsequence C (|C| ≤ |S|) consisting of characters that appear in S, determine the smallest number of adjacent‑swap operations required to reorder C so that its characters appear in the same relative order as they do in S. In one operation you may swap C[i] and C[i+1] for any valid i. It is guaranteed that C can be formed by selecting |C| characters from S in left‑to‑right order (i.e., each character of C matches a distinct occurrence in S). Return the minimum number of swaps as an integer.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Galactic Transmission Correction"

medium

WHY DOES IT MATTER?

This pattern is essential because it bridges the gap between sequence alignment and inversion counting, a fundamental concept in combinatorics and algorithm design. It appears in problems involving sorting, permutation analysis, and sequence transformation, making it a versatile tool for tackling a wide range of medium to hard problems.

OPTIMIZATION CHALLENGE

The key insight is to decouple the mapping of characters to positions from the inversion counting. By using a greedy mapping and then applying an O(n log n) inversion counter, you avoid the O(n^2) complexity of naive approaches. The Fenwick Tree is particularly effective because it allows efficient point updates and prefix sum queries.

REAL-WORLD CONNECTION

In distributed systems, this pattern is analogous to reordering a list of tasks or messages to match a desired execution order. For example, in a message queue system, you might need to reorder messages to ensure they are processed in a specific sequence, and the minimum number of swaps helps optimize the reordering process.

In interviews, clearly articulate the two-step process: mapping and inversion counting. Emphasize why the greedy mapping is correct and how the inversion count relates to adjacent swaps. Be prepared to explain the Fenwick Tree or Merge Sort approach in detail, as interviewers often probe the implementation details.

COMPLEXITY AT A GLANCE

⏱ Time:O(n log n)
💾 Space:O(n)

Core Theory — Why This Approach?

The problem reduces to counting the minimum number of adjacent swaps required to transform a sequence C into a sequence that is a subsequence of S, preserving the relative order of characters in S. This is fundamentally a problem of mapping the positions of characters in C to their corresponding positions in S and then counting the inversions in the resulting index sequence. If we map each character in C to the earliest available occurrence in S (greedily), we obtain a sequence of indices. The number of adjacent swaps needed to sort this index sequence in increasing order is exactly the number of inversions in the sequence. This is because each adjacent swap reduces the inversion count by exactly one, and the sorted sequence has zero inversions.

Naive approaches that simulate the swaps or use O(n^2) inversion counting (like nested loops) fail on large inputs where |S| and |C| can be up to 10^5 or 10^6. The optimal paradigm involves two key steps: first, efficiently mapping characters in C to positions in S using a greedy pointer or precomputed position lists, and second, counting inversions in O(n log n) time using a Fenwick Tree (Binary Indexed Tree) or a Merge Sort-based inversion counter. The Fenwick Tree approach is particularly efficient because it allows point updates and prefix sum queries in O(log n) time, making the total inversion count O(n log n).

The greedy mapping is critical: for each character in C, we must assign it to the earliest possible position in S that hasn't been used yet. This ensures that the relative order in S is preserved and minimizes the potential for unnecessary inversions. If we were to assign characters to arbitrary positions, we might create extra inversions that don't reflect the true minimum swaps. The correctness of the greedy approach follows from the fact that choosing an earlier position in S for a character in C cannot increase the number of inversions compared to choosing a later position, as it leaves more room for subsequent characters to be placed in increasing order.

Interview Questions on This Problem

Q1At a fintech platform, you're building a transaction reconciliation system where two ledgers have the same set of transactions but in different orders. How would you compute the minimum number of adjacent swaps needed to align one ledger to the other, assuming transactions are unique?

Map each transaction in the second ledger to its index in the first ledger, then count the inversions in the resulting index sequence using a Fenwick Tree or Merge Sort. The inversion count equals the minimum adjacent swaps. This is O(n log n) and handles large ledgers efficiently.

Q2In a high-growth startup's content delivery network, you need to reorder a list of cached assets to match the most popular access pattern. If the current order is C and the target order is a subsequence of the full asset list S, how do you minimize adjacent swaps to transform C into the target order?

Treat the target order as the desired subsequence of S. Map each asset in C to its position in S greedily, then count inversions in the mapped index sequence. The inversion count gives the minimum adjacent swaps. Use a Fenwick Tree for O(n log n) performance.

Q3At a global product company, you're optimizing a search ranking system where documents are reordered based on user feedback. If the current ranking is C and the ideal ranking is a subsequence of all documents S, how do you compute the minimum adjacent swaps to reach the ideal ranking?

Map each document in C to its position in S using a greedy approach (earliest available position), then count inversions in the resulting index sequence. The inversion count is the answer. Use a Merge Sort-based inversion counter or Fenwick Tree for efficiency.

Examples

Example 1

Input

S = "ABCDAB", C = "BACA"

Output

1

Explanation: Map each character of C to its earliest unused occurrence in S → positions [1,0,2,4]. The target order is [0,1,2,4]; one inversion (1,0) means one adjacent swap.

Example 2

Input

S = "GATACAG", C = "AGACA"

Output

1

Explanation: Corresponding indices are [1,0,3,4,5]; sorting gives [0,1,3,4,5]. Only the pair (1,0) is inverted, so one swap suffices.

Example 3

Input

S = "XYZXYZXYZ", C = "ZZYXXY"

Output

7

Explanation: Indices obtained: [2,5,0,1,4,3]. Counting inversions yields 7, which is the minimal number of adjacent swaps needed.

Constraints

  • 1 <= |S| <= 2*10^5
  • 1 <= |C| <= |S|
  • S and C contain only uppercase English letters
  • C is a subsequence of S (each character matches a distinct occurrence)

Optimal Approach & Strategy

Map each character in C to its earliest available position in S greedily, then count the inversions in the resulting index sequence using a Fenwick Tree or Merge Sort. This runs in O(n log n) time and is efficient for large inputs.

Brute Force Approach

Simulate the adjacent swaps by repeatedly finding the next character in C that should be moved and swapping it into place, counting each swap. This is O(n^2) or worse and is too slow for large inputs.

Verified Code Solutions

JavaScript Solution
Time: O(n log n)
function minSwapsToReorder(S, C) {
    const n = S.length;
    const m = C.length;
    
    // Store indices of each character in S
    const charIndices = new Array(26).fill().map(() => []);
    for (let i = 0; i < n; ++i) {
        charIndices[S.charCodeAt(i) - 65].push(i);
    }
    
    // Map each character in C to its corresponding index in S
    const mappedIndices = new Array(m);
    for (let i = 0; i < m; ++i) {
        const charCode = C.charCodeAt(i) - 65;
        mappedIndices[i] = charIndices[charCode].shift();
    }
    
    // Count inversions using Fenwick Tree
    const maxIndex = n;
    const fenwick = new Array(maxIndex + 1).fill(0);
    
    const update = (idx) => {
        while (idx <= maxIndex) {
            fenwick[idx]++;
            idx += idx & (-idx);
        }
    };
    
    const query = (idx) => {
        let sum = 0;
        while (idx > 0) {
            sum += fenwick[idx];
            idx -= idx & (-idx);
        }
        return sum;
    };
    
    let inversions = 0;
    for (let i = 0; i < m; ++i) {
        const pos = mappedIndices[i] + 1; // 1-based index
        const countBefore = query(pos - 1);
        inversions += (i - countBefore);
        update(pos);
    }
    
    return inversions;
}

// Driver code
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    terminal: false
});

let lines = [];
rl.on('line', line => lines.push(line));
rl.on('close', () => {
    const [S, C] = lines[0].split(' ');
    console.log(minSwapsToReorder(S, C));
});

Asked in Top Tech Interviews

Infosys

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.