LeetCode 3925 - Concatenate Array With Reverse

The problem asks us to construct a new array by concatenating an input array with its reversed version. Given an integer array nums of length n, we must return a new array ans of length 2 n. The first n elements of ans are exactly the same as nums, preserving order.

LeetCode Problem 3925

Difficulty: 🟢 Easy
Topics: Array, Simulation

Solution

Problem Understanding

The problem asks us to construct a new array by concatenating an input array with its reversed version. Given an integer array nums of length n, we must return a new array ans of length 2 * n.

The first n elements of ans are exactly the same as nums, preserving order. The next n elements are the elements of nums in reverse order, meaning the last element of nums becomes the first element of the second half of ans, the second-to-last element becomes the second, and so on.

The input constraints are 1 <= nums.length <= 100 and 1 <= nums[i] <= 100. These constraints indicate the input size is small, so even simple linear solutions are efficient.

Important edge cases include an array of length 1, arrays with all identical elements, and arrays with length 2 where reversal produces a noticeable change. The problem guarantees that the input array is non-empty and contains valid positive integers.

Approaches

The brute-force approach constructs the result in two distinct steps. First, it copies all elements of nums into a new array. Second, it iterates through nums in reverse order and appends each element. This approach is simple and correct because it follows the problem definition exactly, but it involves two passes and repeated append operations.

The optimal approach is based on the insight that every index in the output array can be computed directly. By preallocating an array of size 2n, we can fill both the forward and reversed portions in a single loop. This reduces overhead, simplifies the code, and maintains linear time complexity.

Approach Time Complexity Space Complexity Notes
Brute Force O(n) O(n) Copy original array then append reversed array in two passes
Optimal O(n) O(n) Preallocate array and fill both halves in a single loop using index mapping

Algorithm Walkthrough

  1. Determine the length n of nums because the output array size is 2 * n and the reverse index depends on n.
  2. Allocate an array ans of size 2 * n to hold the result. Preallocation ensures efficient constant-time writes and avoids dynamic resizing.
  3. Iterate through the range 0 to n - 1. Each index i corresponds to two positions in ans: i for the forward portion and i + n for the reversed portion.
  4. Assign ans[i] = nums[i] to copy the original array into the first half.
  5. Assign ans[i + n] = nums[n - 1 - i] to fill the second half with elements in reverse order.
  6. Continue until all elements are processed. The array ans now contains the original array followed by its reverse.
  7. Return ans.

Why it works: Every output index has a unique mapping to the input array. The first half directly preserves the order, and the second half deterministically reverses it. Since each index is written exactly once, the algorithm guarantees correctness.

Python Solution

class Solution:
    def concatWithReverse(self, nums: list[int]) -> list[int]:
        n = len(nums)
        ans = [0] * (2 * n)
        for i in range(n):
            ans[i] = nums[i]
            ans[i + n] = nums[n - 1 - i]
        return ans

The Python implementation begins by computing n and allocating the result array. The loop iterates through each index, filling both halves simultaneously. The first assignment preserves the original array, while the second computes the reversed index. The algorithm completes in a single pass with clear, direct index mapping.

Go Solution

func concatWithReverse(nums []int) []int {
    n := len(nums)
    ans := make([]int, 2*n)
    for i := 0; i < n; i++ {
        ans[i] = nums[i]
        ans[i+n] = nums[n-1-i]
    }
    return ans
}

In Go, we preallocate the slice using make to avoid resizing during the loop. The loop mirrors the Python logic, filling both halves directly. No special handling is required for nil slices because the problem guarantees at least one element.

Worked Examples

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

n = 3, initialize ans = [0, 0, 0, 0, 0, 0]

i ans after forward ans after reverse
0 [1, 0, 0, 0, 0, 0] [1, 0, 0, 3, 0, 0]
1 [1, 2, 0, 3, 0, 0] [1, 2, 0, 3, 2, 0]
2 [1, 2, 3, 3, 2, 0] [1, 2, 3, 3, 2, 1]

Example 2: nums = [1]

n = 1, initialize ans = [0, 0]

i ans after forward ans after reverse
0 [1, 0] [1, 1]

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each element is processed exactly once in a single loop
Space O(n) Output array of size 2n dominates memory usage

The time complexity is linear because each element requires only constant work. The space complexity is linear because we allocate a new array of size 2n.

Test Cases

# Provided examples
assert Solution().concatWithReverse([1, 2, 3]) == [1, 2, 3, 3, 2, 1]  # general case
assert Solution().concatWithReverse([1]) == [1, 1]  # single element

# Additional edge cases
assert Solution().concatWithReverse([5, 5, 5]) == [5, 5, 5, 5, 5, 5]  # all elements identical
assert Solution().concatWithReverse([1, 2]) == [1, 2, 2, 1]  # smallest non-trivial reversal
assert Solution().concatWithReverse([9, 8, 7, 6]) == [9, 8, 7, 6, 6, 7, 8, 9]  # larger array
Test Why
[1,2,3] validates standard behavior
[1] minimal size edge case
[5,5,5] ensures correctness with duplicates
[1,2] checks correct reversal for smallest non-trivial array
[9,8,7,6] verifies proper handling of larger arrays

Edge Cases

One edge case is when nums has length 1. In this situation, the reversed array is identical to the original, and the output should simply duplicate the element. The implementation handles this automatically because both halves are assigned using direct indices.

Another edge case is when all elements in nums are the same. Reversal does not visibly change the array, but the algorithm still correctly maps indices using n - 1 - i. This prevents any mistakes related to mistaken assumptions about distinct values.

A final edge case is a minimal array of length 2. This is the smallest array where reversal produces a change. Using n - 1 - i ensures that the two elements are swapped in the reversed portion, and the algorithm writes each index exactly once, avoiding overwrites.