Left Rotate an Array by K Places
Problem and examples
Given an array arr of integers and an integer k, your task is to rotate the array to the left by k positions.
In a left rotation, each element of the array is shifted to the left by one index, and the first elements are moved to the end in order.
The goal is to perform this rotation efficiently using an optimal in-place algorithm with O(n) time and O(1) extra space.
| Input Array | k | Rotated Array | Description |
|---|---|---|---|
| [10, 20, 30, 40, 50] | 2 | [30, 40, 50, 10, 20] | Shift first 2 elements to the endVisualization |
| [10, 20, 30, 40] | 0 | [10, 20, 30, 40] | No rotation since k = 0Visualization |
| [7, 8, 9] | 3 | [7, 8, 9] | k equals array length, so array remains unchangedVisualization |
| [4, 5, 6] | 5 | [6, 4, 5] | k > n, so we use k % n = 2 → rotate by 2 positionsVisualization |
| [1] | 3 | [1] | Single element remains unchanged regardless of kVisualization |
| [] | 4 | [] | Empty array remains unchangedVisualization |
Explore Left Rotate Array by K Places
Load an example or enter your own input. Use the player controls to follow each change.
Understanding the Problem
We are given an array and asked to rotate it to the left by k positions. Rotating left means moving the first k elements to the end of the array, while keeping the rest of the elements in order.
For example, given arr = [1, 2, 3, 4, 5, 6, 7] and k = 3, rotating it to the left would give [4, 5, 6, 7, 1, 2, 3].
We will solve this problem step-by-step using an optimal method that is easy to understand and very efficient.
Step-by-Step Approach with Explanation
Step 1: Normalize k
If k is larger than the array size, rotating more than necessary is redundant. So, we first compute k = k % n, where n is the length of the array.
For example, rotating a 7-element array by 10 is the same as rotating it by 10 % 7 = 3 steps.
Step 2: Reverse the First k Elements
We reverse the first k elements. These are the ones that will eventually move to the end of the array after the full rotation.
In our example, reverse [1, 2, 3] → [3, 2, 1].
Step 3: Reverse the Remaining n - k Elements
Next, reverse the part of the array that will stay at the beginning after rotation — the last n - k elements.
In our example, reverse [4, 5, 6, 7] → [7, 6, 5, 4].
Step 4: Reverse the Entire Array
Now, reverse the whole array to finalize the rotation.
After combining the previous two steps: [3, 2, 1, 7, 6, 5, 4] → final reverse → [4, 5, 6, 7, 1, 2, 3].
Edge Cases and How We Handle Them
Case 1: k = 0
No rotation is needed. The array remains unchanged.
Case 2: k is a multiple of array length
If k % n == 0, the rotation brings us back to the original array. So we return it as-is.
Case 3: k > n
Normalize k using k % n to prevent over-rotating.
Case 4: Empty Array
If the array is empty, there's nothing to rotate. We simply return an empty array.
Case 5: Single-Element Array
Rotating a single-element array any number of times still results in the same array.
- Given an array
arrof sizenand a valuek. - Normalize
kusingk = k % nto handle overflow. - Reverse the first
kelements. - Reverse the remaining
n - kelements. - Reverse the entire array to get the final rotated form.
Worked example
We will left rotate the array by 3 places using the reversal algorithm.
Step 1: Reverse the first 3 elements.
Step 2: Reverse the remaining 4 elements.
Step 3: Reverse the entire array.
Final Rotated Array:
Implementation and efficiency
C implementation
#include <stdio.h>
void reverse(int arr[], int start, int end) {
while (start < end) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void leftRotate(int arr[], int n, int k) {
k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 2;
leftRotate(arr, n, k);
printf("Rotated Array: ");
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
return 0;
}C++ implementation
#include <iostream>
#include <vector>
using namespace std;
void reverse(vector<int>& arr, int start, int end) {
while (start < end) {
swap(arr[start], arr[end]);
start++;
end--;
}
}
void leftRotate(vector<int>& arr, int k) {
int n = arr.size();
k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
}
int main() {
vector<int> arr = {1, 2, 3, 4, 5, 6, 7};
int k = 2;
leftRotate(arr, k);
cout << "Rotated Array: ";
for (int num : arr) cout << num << " ";
return 0;
}Python implementation
def reverse(arr, start, end):
while start < end:
arr[start], arr[end] = arr[end], arr[start]
start += 1
end -= 1
def left_rotate(arr, k):
n = len(arr)
k = k % n
reverse(arr, 0, k - 1)
reverse(arr, k, n - 1)
reverse(arr, 0, n - 1)
return arr
# Sample Input
arr = [1, 2, 3, 4, 5, 6, 7]
k = 2
print("Rotated Array:", left_rotate(arr, k))Java implementation
public class RotateArray {
static void reverse(int[] arr, int start, int end) {
while (start < end) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
static void leftRotate(int[] arr, int k) {
int n = arr.length;
k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
int k = 2;
leftRotate(arr, k);
System.out.print("Rotated Array: ");
for (int num : arr) System.out.print(num + " ");
}
}JavaScript implementation
function reverse(arr, start, end) {
while (start < end) {
[arr[start], arr[end]] = [arr[end], arr[start]];
start++;
end--;
}
}
function leftRotate(arr, k) {
const n = arr.length;
k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
return arr;
}
const arr = [1, 2, 3, 4, 5, 6, 7];
const k = 2;
console.log("Rotated Array:", leftRotate(arr, k));Go implementation
package main
import (
"fmt"
)
func reverse(arr []int, start, end int) {
for start < end {
arr[start], arr[end] = arr[end], arr[start]
start++
end--
}
}
func leftRotate(arr []int, k int) []int {
n := len(arr)
k = k % n
reverse(arr, 0, k-1)
reverse(arr, k, n-1)
reverse(arr, 0, n-1)
return arr
}
func main() {
arr := []int{1, 2, 3, 4, 5, 6, 7}
k := 2
rotated := leftRotate(arr, k)
fmt.Print("Rotated Array: ")
for _, num := range rotated {
fmt.Print(num, " ")
}
}Rust implementation
fn reverse(arr: &mut [i32], start: usize, end: usize) {
let mut i = start;
let mut j = end;
while i < j {
arr.swap(i, j);
i += 1;
if j == 0 { break; }
j -= 1;
}
}
fn left_rotate(arr: &mut [i32], k: usize) {
let n = arr.len();
let k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
}
fn main() {
let mut arr = vec![1, 2, 3, 4, 5, 6, 7];
let k = 2;
left_rotate(&mut arr, k);
print!("Rotated Array: ");
for num in arr.iter() {
print!("{} ", num);
}
}Kotlin implementation
fun reverse(arr: IntArray, start: Int, end: Int) {
var s = start
var e = end
while (s < e) {
val temp = arr[s]
arr[s] = arr[e]
arr[e] = temp
s++
e--
}
}
fun leftRotate(arr: IntArray, k: Int): IntArray {
val n = arr.size
val rot = k % n
reverse(arr, 0, rot - 1)
reverse(arr, rot, n - 1)
reverse(arr, 0, n - 1)
return arr
}
fun main() {
val arr = intArrayOf(1, 2, 3, 4, 5, 6, 7)
val k = 2
leftRotate(arr, k)
print("Rotated Array: ")
arr.forEach { print("$it ") }
}Swift implementation
func reverse(_ arr: inout [Int], _ start: Int, _ end: Int) {
var s = start
var e = end
while s < e {
arr.swapAt(s, e)
s += 1
e -= 1
}
}
func leftRotate(_ arr: inout [Int], _ k: Int) {
let n = arr.count
let rot = k % n
reverse(&arr, 0, rot - 1)
reverse(&arr, rot, n - 1)
reverse(&arr, 0, n - 1)
}
var arr = [1, 2, 3, 4, 5, 6, 7]
let k = 2
leftRotate(&arr, k)
print("Rotated Array:", arr)TypeScript implementation
function reverse(arr: number[], start: number, end: number): void {
while (start < end) {
[arr[start], arr[end]] = [arr[end], arr[start]];
start++;
end--;
}
}
function leftRotate(arr: number[], k: number): number[] {
const n = arr.length;
k = k % n;
reverse(arr, 0, k - 1);
reverse(arr, k, n - 1);
reverse(arr, 0, n - 1);
return arr;
}
const arr: number[] = [1, 2, 3, 4, 5, 6, 7];
const k: number = 2;
console.log("Rotated Array:", leftRotate(arr, k));Time complexity
| Case | Time | Explanation |
|---|---|---|
| best case | O(n) | In all cases, the reversal algorithm performs three full reversals of parts of the array, resulting in linear time complexity. |
| average case | O(n) | Regardless of the value of k, the algorithm always reverses the same number of elements in total, leading to consistent linear time. |
| worst case | O(n) | Even in the worst case (e.g., k = n - 1), the three-reversal strategy still results in traversing each element once, so the complexity is linear. |
Space complexity
O(1)
The algorithm operates in-place and uses only a constant number of temporary variables to perform reversals. No additional data structures are needed.