Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

String Transformation Algorithms: Reversal, Rotation, and Space Manipulation Techniques

Tech May 16 1
  1. In-Place String Reversal

The problem requires reversing a character array without allocating additional memory, achieving O(1) space complexity. While most languages provide built-in reversal functions, implementing the algorithm manually demonstrates fundamental pointer manipulation skills.

The optimal approach employs a two-pointer technique. Place one pointer at the beginning and another at the end of the array, then progressively swap elements while moving the pointers toward the center.

void reverseString(std::vector<char>& chars) {
    int start = 0;
    int end = chars.size() - 1;
    
    while (start < end) {
        // Manual swap without using library function
        char temp = chars[start];
        chars[start] = chars[end];
        chars[end] = temp;
        
        start++;
        end--;
    }
}

Alternative swap implementations include bitwise XOR operations or std::exchange, though the three-line manual swap offers the best clarity.

  1. Selective Segment Reversal

This variation adds complexity by requiring reversal of only the first k characters in every 2k segment. The key insight involves jumping through the string in 2k increments rather than processing each character sequentially.

std::string reverseSegments(std::string str, int k) {
    size_t pos = 0;
    
    while (pos < str.length()) {
        // Check if we have at least k characters remaining
        if (pos + k <= str.length()) {
            // Reverse first k characters in current segment
            size_t left = pos;
            size_t right = pos + k - 1;
            while (left < right) {
                std::swap(str[left++], str[right--]);
            }
        } else {
            // Reverse all remaining characters
            size_t left = pos;
            size_t right = str.length() - 1;
            while (left < right) {
                std::swap(str[left++], str[right--]);
            }
        }
        pos += 2 * k;
    }
    
    return str;
}

The algorithm efficiently processes the string by skipping fully processed segments, avoiding unnecessary boundary checks within each iteration.

  1. Space Replacement with Percent Encoding

Trensform each space character into "%20" without using extra storage. The solution involves pre-calculating the final length and performing backward population to prevent repeated shifting.

std::string encodeSpaces(std::string& text) {
    size_t spaceCount = 0;
    size_t originalLen = text.length();
    
    // Count spaces to determine expanded size
    for (char c : text) {
        if (c == ' ') spaceCount++;
    }
    
    // Resize string to accommodate "%20" for each space
    text.resize(originalLen + spaceCount * 2);
    
    size_t writePos = text.length() - 1;
    size_t readPos = originalLen - 1;
    
    // Backward writing prevents O(n²) shifting
    while (readPos < writePos) {
        if (text[readPos] == ' ') {
            text[writePos--] = '0';
            text[writePos--] = '2';
            text[writePos--] = '%';
        } else {
            text[writePos--] = text[readPos];
        }
        readPos--;
    }
    
    return text;
}

This technique ensures each character moves at most once, achieving O(n) time complexity with constant extra space.

  1. Word Order Reversal

Reverse the order of words while maintaining their original characters and normalizing spacing. The strategy involves three phases: space normalization, complete string reversal, and individual word correction.

void trimAndNormalize(std::string& s) {
    size_t writeIdx = 0;
    bool firstWord = true;
    
    for (size_t readIdx = 0; readIdx < s.length(); ++readIdx) {
        if (s[readIdx] != ' ') {
            // Add single space before subsequent words
            if (!firstWord) {
                s[writeIdx++] = ' ';
            }
            
            // Copy entire word
            while (readIdx < s.length() && s[readIdx] != ' ') {
                s[writeIdx++] = s[readIdx++];
            }
            
            firstWord = false;
        }
    }
    
    s.resize(writeIdx);
}

void reverseRange(std::string& s, size_t left, size_t right) {
    while (left < right) {
        std::swap(s[left++], s[right--]);
    }
}

std::string reverseWordOrder(std::string s) {
    // Phase 1: Remove extra spaces
    trimAndNormalize(s);
    
    // Phase 2: Reverse entire string
    reverseRange(s, 0, s.length() - 1);
    
    // Phase 3: Reverse each word individually
    size_t wordStart = 0;
    for (size_t i = 0; i <= s.length(); ++i) {
        if (i == s.length() || s[i] == ' ') {
            reverseRange(s, wordStart, i - 1);
            wordStart = i + 1;
        }
    }
    
    return s;
}

The normalization step uses a single pass with read/write pointers, eliminating O(n²) erase operations.

  1. Left Rotation via Reversals

Rotate a string left by n positions using only in-place operations. The clever solution applies targeted reversals: first on the prefix, then the suffix, and finally the entire string.

void reverseSubstring(std::string& s, size_t begin, size_t finish) {
    while (begin < finish) {
        std::swap(s[begin++], s[finish--]);
    }
}

std::string leftRotate(std::string s, size_t n) {
    if (s.empty() || n >= s.length()) return s;
    
    // Three-step reversal process
    reverseSubstring(s, 0, n - 1);          // Reverse prefix
    reverseSubstring(s, n, s.length() - 1); // Reverse suffix
    reverseSubstring(s, 0, s.length() - 1); // Reverse entire string
    
    return s;
}

This approach achieves the rotation in O(n) time with O(1) auxiliary space, demonstrating how composition of simple operations can solve complex problems efficiently.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.