Start learning free

LESSON 229 OF 343 · TWO POINTERS

Rotate Array by One to the Right in C++: In Place, O(n)

Practice O(n) Read the full explanation

Given an array of integers nums, rotate it in-place by one position to its right.

Do not allocate extra space for another array. You must do this by modifying directly the input array with O(1) auxiliary space.


Example 1:

Input: nums = [1, 2, 3, 4, 5]
Output: [5, 1, 2, 3, 4]

Example 2:

Input: nums = [4, -2, 13, 1]
Output: [1, 4, -2, 13]

Note:

Your algorithm should run in O(n) time and use O(1) auxiliary space.


STEP 1 OF 4
    Ctrl + Enter to check

    C++ · TWO POINTERS

    Rotate Array 1 in C++, explained

    Problem overview

    The function rotate receives a vector of integers, nums, and moves every element one position to the right. The last element wraps around to the front. The change must happen in the vector itself, with no second array, so the extra space is O(1).

    For [1, 2, 3, 4, 5] the result is [5, 1, 2, 3, 4]. For [4, -2, 13, 1] it is [1, 4, -2, 13]. The function returns nothing: the caller sees the change because nums is passed by reference.

    Approach: save the last element, shift the rest

    Every element except the last moves one slot right, and the last one goes to index 0. Writing nums[i] = nums[i - 1] for each i does the shifting, but it overwrites the old nums[i]. That value must not be lost before it is used.

    The last element is the only one that would be destroyed without ever being copied elsewhere, because the first write, to index n - 1, overwrites it. So the plan is:

    1. save the last element in a variable;
    2. shift the others right, starting from the right end;
    3. put the saved value at index 0.

    The direction of the shift matters. Going right to left, each step reads nums[i - 1], which no earlier step has touched yet. Going left to right would copy nums[0] into nums[1], then copy that same value into nums[2], and fill the vector with copies of the first element.

    Step by step

    1. Record the size and the last value. Store nums.size() in an int named n, and copy nums[n - 1] into last.
    2. Loop from the right. Let i start at n - 1 and run while i > 0, decreasing each time. The loop stops before index 0, which has no left neighbour to copy from.
    3. Shift. Assign nums[i] = nums[i - 1]. Each element moves one slot right, and the value read has not been overwritten yet.
    4. Wrap around. After the loop, index 0 still holds its old value, which has already been copied to index 1. Assign last to nums[0].

    The solution in C++

    class Solution {
    public:
        void rotate(vector<int>& nums) {
            int n = nums.size();
            int last = nums[n - 1];
            for (int i = n - 1; i > 0; i--) {
                nums[i] = nums[i - 1];
            }
            nums[0] = last;
        }
    };
    

    Tracing [1, 2, 3, 4, 5]: last is 5. The loop produces [1, 2, 3, 4, 4], then [1, 2, 3, 3, 4], then [1, 2, 2, 3, 4], then [1, 1, 2, 3, 4]. Finally nums[0] = 5 gives [5, 1, 2, 3, 4].

    The C++ details worth knowing:

    • Reference parameter. vector<int>& nums is the caller's vector, not a copy. Without the &, the function would rotate a copy and the caller would see no change.
    • Signed index. The size is stored in an int, so n - 1 and the loop condition i > 0 behave normally. With an unsigned variable such as size_t i, a loop like for (i = n - 1; i >= 0; i--) would never end, because an unsigned value can't go below 0.
    • The standard library has this. rotate(nums.begin(), nums.end() - 1, nums.end()) from <algorithm> performs the same rotation. Writing the loop by hand is the point of this lesson.

    Complexity

    Time: O(n). The loop runs n - 1 times, and each iteration is one assignment.

    Space: O(1). The code uses two integers, n and last, and the loop counter, whatever the size of the vector.

    Edge cases and common mistakes

    • One element. For [7], the loop doesn't run and nums[0] = last writes the same value back. The vector stays [7].
    • Two elements. [1, 2] becomes [2, 1].
    • An empty vector. nums[n - 1] would be nums[-1], which is undefined behaviour. The lesson's tests don't use an empty vector, but code that may receive one should start with if (nums.empty()) return;.
    • Shifting left to right. Every element ends up equal to the first one, because each assignment copies a value that was just overwritten.
    • Forgetting to save the last element. The first assignment, to nums[n - 1], destroys it, and there is nothing left to put at index 0.
    • Writing i >= 0. The loop would then evaluate nums[-1] on its last pass, which is undefined behaviour.

    Testing

    • [1, 2, 3, 4, 5] becomes [5, 1, 2, 3, 4].
    • [4, -2, 13, 1] becomes [1, 4, -2, 13].
    • [7] stays [7].
    • [1, 2] becomes [2, 1].
    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free