Skip to main content

Concatenation of Array

Description

You are given an integer array nums of length n. Your task is to construct a new array ans of length 2n such that ans[i] == nums[i] and ans[i + n] == nums[i] for every valid index 0 <= i < n.

In simpler terms, you need to create an array that contains all the elements of nums followed by all the elements of nums again — essentially placing two copies of the original array side by side.

Return the resulting array ans.

Examples

Example 1

Input: nums = [1, 2, 1]

Output: [1, 2, 1, 1, 2, 1]

Explanation: The result array ans is formed by placing the original array [1, 2, 1] followed by another copy of itself. The first three elements come from the original array, and the next three elements are an exact repeat: ans[0]=nums[0]=1, ans[1]=nums[1]=2, ans[2]=nums[2]=1, ans[3]=nums[0]=1, ans[4]=nums[1]=2, ans[5]=nums[2]=1.

Example 2

Input: nums = [1, 3, 2, 1]

Output: [1, 3, 2, 1, 1, 3, 2, 1]

Explanation: The result is the original four-element array [1, 3, 2, 1] followed by another copy of those same four elements. The resulting array has length 2 × 4 = 8. Notice that the second half (indices 4 through 7) is identical to the first half (indices 0 through 3).

Example 3

Input: nums = [5]

Output: [5, 5]

Explanation: With a single-element array, concatenating it with itself simply produces [5, 5]. The result has length 2 × 1 = 2.

Constraints

  • n == nums.length
  • 1 ≤ n ≤ 1000
  • 1 ≤ nums[i] ≤ 1000

Editorial

Brute Force

Intuition

The most straightforward way to think about this problem is to build the result array by filling it element by element.

Imagine you have a blank notebook with 2n pages. You go through the original array and write each value onto the notebook once. When you reach the end of the original array, you go back to the beginning and write each value again, filling the remaining pages.

In programming terms, we create a new array of size 2n and use a loop that runs from 0 to 2n - 1. For each position i, we figure out which element from the original array belongs there by using the modulo operation: nums[i % n]. The modulo operator naturally "wraps around" when i reaches n, so positions 0 through n-1 get nums[0] through nums[n-1], and positions n through 2n-1 get nums[0] through nums[n-1] again.

Step-by-Step Explanation

Let's trace through with nums = [1, 2, 1] (n = 3):

Step 1: Create an empty result array ans of size 2n = 6.

  • ans = [_, _, _, _, _, _]

Step 2: i = 0. Compute i % n = 0 % 3 = 0. Set ans[0] = nums[0] = 1.

  • ans = [1, _, _, _, _, _]

Step 3: i = 1. Compute i % n = 1 % 3 = 1. Set ans[1] = nums[1] = 2.

  • ans = [1, 2, _, _, _, _]

Step 4: i = 2. Compute i % n = 2 % 3 = 2. Set ans[2] = nums[2] = 1.

  • ans = [1, 2, 1, _, _, _]

Step 5: i = 3. Compute i % n = 3 % 3 = 0. The modulo wraps back to index 0! Set ans[3] = nums[0] = 1.

  • ans = [1, 2, 1, 1, _, _]

Step 6: i = 4. Compute i % n = 4 % 3 = 1. Set ans[4] = nums[1] = 2.

  • ans = [1, 2, 1, 1, 2, _]

Step 7: i = 5. Compute i % n = 5 % 3 = 2. Set ans[5] = nums[2] = 1.

  • ans = [1, 2, 1, 1, 2, 1]

Result: ans = [1, 2, 1, 1, 2, 1]

Building the Concatenated Array Element by Element — Watch how we fill the result array position by position, using the modulo operator to wrap around and re-read from the source array.

Algorithm

  1. Let n = length of nums
  2. Create a new array ans of size 2n
  3. For each index i from 0 to 2n - 1:
    • Set ans[i] = nums[i % n]
  4. Return ans

Code

class Solution {
public:
    vector<int> getConcatenation(vector<int>& nums) {
        int n = nums.size();
        vector<int> ans(2 * n);
        for (int i = 0; i < 2 * n; i++) {
            ans[i] = nums[i % n];
        }
        return ans;
    }
};
class Solution:
    def getConcatenation(self, nums: list[int]) -> list[int]:
        n = len(nums)
        ans = [0] * (2 * n)
        for i in range(2 * n):
            ans[i] = nums[i % n]
        return ans
class Solution {
    public int[] getConcatenation(int[] nums) {
        int n = nums.length;
        int[] ans = new int[2 * n];
        for (int i = 0; i < 2 * n; i++) {
            ans[i] = nums[i % n];
        }
        return ans;
    }
}

Complexity Analysis

Time Complexity: O(n)

We iterate through 2n positions, performing a constant-time modulo operation and array assignment at each step. Since 2n is linear in n, the overall time complexity is O(n).

Space Complexity: O(n)

We allocate a new array of size 2n to hold the result. This is the required output, so the space usage is O(n). Beyond the output array, we only use a constant number of variables (n, i).

Why This Approach Is Not Efficient

The modulo-based approach works correctly and runs in O(n) time, which is already asymptotically optimal — we cannot do better than O(n) because we must write all 2n elements of the output.

However, the modulo operation at each iteration introduces an unnecessary computation. For every single index i, we compute i % n to determine which source element to copy. While modulo is a constant-time operation, it adds overhead compared to simply copying two blocks of the array directly.

The key insight is that we already know the structure of the result: the first n elements are an exact copy of nums, and the next n elements are another exact copy. We do not need modulo arithmetic to figure out where each element goes — we can just copy nums twice in sequence. Most languages provide built-in ways to concatenate or extend arrays that are both simpler and potentially faster due to optimized memory operations.

Optimal Approach - Direct Concatenation

Intuition

Since the problem literally asks us to concatenate the array with itself, the most natural and efficient approach is to do exactly that — copy the entire array once, then copy it again right after.

Think of it like photocopying a document: instead of photocopying each page individually and figuring out which page goes where, you simply put the entire document through the copier twice and stack the copies together.

In most programming languages, there are built-in operations for array concatenation that handle memory allocation and copying in a single, optimized step:

  • In Python, nums + nums creates a new list with both copies
  • In C++, we can use insert to append the array to itself
  • In Java, we use System.arraycopy for efficient block-level copying

This avoids per-element modulo calculations and leverages the language's optimized memory copying routines.

Step-by-Step Explanation

Let's trace through with nums = [1, 2, 1] (n = 3):

Step 1: Start with the source array nums = [1, 2, 1]. Allocate a result array of size 2n = 6.

  • ans = [_, _, _, _, _, _]

Step 2: Copy the entire first block — all of nums — into positions 0 through n-1 of ans.

  • Copy nums[0..2] → ans[0..2]
  • ans = [1, 2, 1, _, _, _]

Step 3: Copy the entire second block — all of nums again — into positions n through 2n-1 of ans.

  • Copy nums[0..2] → ans[3..5]
  • ans = [1, 2, 1, 1, 2, 1]

Result: ans = [1, 2, 1, 1, 2, 1]. Done in just two bulk copy operations.

Direct Concatenation — Two Block Copies — Watch how we copy the source array as two complete blocks into the result, without any per-element arithmetic.

Algorithm

  1. Let n = length of nums
  2. Create a new array ans of size 2n
  3. Copy nums[0..n-1] into ans[0..n-1] (first block)
  4. Copy nums[0..n-1] into ans[n..2n-1] (second block)
  5. Return ans

Alternatively, in languages with built-in concatenation:

  1. Return nums concatenated with nums

Code

class Solution {
public:
    vector<int> getConcatenation(vector<int>& nums) {
        int n = nums.size();
        vector<int> ans(nums);
        ans.insert(ans.end(), nums.begin(), nums.end());
        return ans;
    }
};
class Solution:
    def getConcatenation(self, nums: list[int]) -> list[int]:
        return nums + nums
class Solution {
    public int[] getConcatenation(int[] nums) {
        int n = nums.length;
        int[] ans = new int[2 * n];
        System.arraycopy(nums, 0, ans, 0, n);
        System.arraycopy(nums, 0, ans, n, n);
        return ans;
    }
}

Complexity Analysis

Time Complexity: O(n)

We copy n elements twice, for a total of 2n copy operations. Each copy is O(1), so the overall time is O(n). This is the same asymptotic complexity as the brute force, but in practice it is faster because bulk memory copy operations (like memcpy, System.arraycopy, or Python's list concatenation) are heavily optimized at the hardware level and avoid per-element modulo computation.

Space Complexity: O(n)

The output array has 2n elements, which is O(n). No additional auxiliary data structures are used beyond the required output.