String Rotation and Reversal Techniques

String Rotation and Reversal Techniques

Problem: Move first m characters to the end

Brute Force Rotation

Move one character to the end, repeat m times. Time complexity O(mn), space O(1).

Three-Step Reversal

Time complexity O(N), space O(1). Split into two parts, reverse each part, then reverse the whole string.

void reverse(string &s, int from, int to) {
    while(from < to) swap(s[from++], s[to--]);
}

void ReverseStr(string &s, int m) {
    int n = s.length();
    // m might be greater than n
    m %= s.length();

    reverse(s, 0, m-1);
    reverse(s, m, n-1);
    reverse(s, 0, n-1);
}

151. Reverse Words in a String

The idea works like character reversal but for words. First reverse the entire string, which reverses each word’s order. Then scan for spaces with two pointers and reverse individual words. Finally reverse the last word.

Catch: Remove leading, middle, and trailing spaces. Time complexity: O(N) Space complexity: O(1)

void reverseWords(string &s) {
    //trimming spaces at start
    int i=0;
    while(i<s.length() && s[i]==' '){
        s.erase(s.begin()+i);
    }

    //trimming spaces from the end.
    int j=s.length()-1;
    while(j>=0 && s[j]==' '){
        s.erase(s.begin()+j);
        j--;
    }

	// CC: string contains only spaces
    if (s == "") return;
	// 1. reverse whole str
    reverse(s, 0, s.length()-1);
    
	// 2. reverse word by word (two pointers)
    for(i=j=0;i<s.length()-1;++i) {
        if (s[i] == ' ') {
            reverse(s, j, i-1);
            j = i+1;
			// CC: remove spaces before continue
            while (s[i+1] == ' ') s.erase(s.begin()+i+1);
        }
    }
    reverse(s, j, s.length()-1);
}

void reverse(string &s, int from, int to) {
    while(from < to) swap(s[from++], s[to--]);
}

Key Insight

Efficient string reversal uses three reversals.

796. Rotate String

Given strings a and b. Check if b can be obtained by left-shifting a.

Solution 1: Brute Force Substring Concatenation 0ms

b can be obtained by splitting a at some position and swapping parts.

bool rotateString(string a, string b) {
    if (a.length() != b.length()) return false;
    if (a == b) return true;

    for(int i=0;i<a.size();++i) {
		// reduce unnecessary splits
        if (a[i] != b[0]) continue;
        if (a.substr(i, a.size()-i)
			+a.substr(0, i) == b) return true;
    }

    return false;
}

Solution 2: Pattern Recognition 4ms

b will always appear in the new string made by concatenating two copies of a.

bool rotateString(string A, string B) {
    return A.size() == B.size() && (A + A).find(B) != string::npos;
}

Key Insight

string::npos is just -1 indicating not found.

#two-pointers #strings