182 lines
7.7 KiB
YAML
182 lines
7.7 KiB
YAML
title: Concatenation of Array
|
|
slug: concatenation-of-array
|
|
difficulty: easy
|
|
leetcode_id: 1929
|
|
leetcode_url: https://leetcode.com/problems/concatenation-of-array/
|
|
categories:
|
|
- arrays
|
|
patterns:
|
|
- slug: two-pointers
|
|
is_optimal: true
|
|
|
|
function_signature: "def get_concatenation(nums: list[int]) -> list[int]:"
|
|
|
|
test_cases:
|
|
visible:
|
|
- input: { nums: [1, 2, 1] }
|
|
expected: [1, 2, 1, 1, 2, 1]
|
|
- input: { nums: [1, 3, 2, 1] }
|
|
expected: [1, 3, 2, 1, 1, 3, 2, 1]
|
|
hidden:
|
|
- input: { nums: [1] }
|
|
expected: [1, 1]
|
|
- input: { nums: [5, 4, 3, 2, 1] }
|
|
expected: [5, 4, 3, 2, 1, 5, 4, 3, 2, 1]
|
|
- input: { nums: [1, 1, 1] }
|
|
expected: [1, 1, 1, 1, 1, 1]
|
|
- input: { nums: [7] }
|
|
expected: [7, 7]
|
|
- input: { nums: [100, 200] }
|
|
expected: [100, 200, 100, 200]
|
|
|
|
description: |
|
|
Given an integer array `nums` of length `n`, you want to create an array `ans` of length `2n` where `ans[i] == nums[i]` and `ans[i + n] == nums[i]` for `0 <= i < n` (**0-indexed**).
|
|
|
|
Specifically, `ans` is the **concatenation** of two `nums` arrays.
|
|
|
|
Return *the array* `ans`.
|
|
|
|
constraints: |
|
|
- `n == nums.length`
|
|
- `1 <= n <= 1000`
|
|
- `1 <= nums[i] <= 1000`
|
|
|
|
examples:
|
|
- input: "nums = [1,2,1]"
|
|
output: "[1,2,1,1,2,1]"
|
|
explanation: "The array ans is formed as follows: ans = [nums[0],nums[1],nums[2],nums[0],nums[1],nums[2]] = [1,2,1,1,2,1]"
|
|
- input: "nums = [1,3,2,1]"
|
|
output: "[1,3,2,1,1,3,2,1]"
|
|
explanation: "The array ans is formed as follows: ans = [nums[0],nums[1],nums[2],nums[3],nums[0],nums[1],nums[2],nums[3]] = [1,3,2,1,1,3,2,1]"
|
|
|
|
explanation:
|
|
intuition: |
|
|
Imagine you have a deck of cards and you want to create a copy of it placed right after the original. The result is simply the same sequence repeated twice.
|
|
|
|
This problem is fundamentally about **array duplication and concatenation**. The key insight is that we need to produce an output array that contains the original array followed by itself. There's no complex logic involved — we're simply copying elements twice.
|
|
|
|
Think of it like this: if you have a row of numbered boxes, you create an identical row and place it at the end. The first half of your result mirrors the input, and so does the second half.
|
|
|
|
The simplicity of this problem makes it an excellent introduction to basic array manipulation and understanding index relationships.
|
|
|
|
approach: |
|
|
We solve this using a **Direct Concatenation Approach**:
|
|
|
|
**Step 1: Create the result array**
|
|
|
|
- Initialise an empty array `ans` that will hold `2n` elements
|
|
- We can either pre-allocate space or build it dynamically
|
|
|
|
|
|
|
|
**Step 2: Fill the first half**
|
|
|
|
- Copy all elements from `nums` into positions `0` to `n-1` of `ans`
|
|
- This mirrors the original array exactly
|
|
|
|
|
|
|
|
**Step 3: Fill the second half**
|
|
|
|
- Copy all elements from `nums` into positions `n` to `2n-1` of `ans`
|
|
- This creates the duplicate portion
|
|
|
|
|
|
|
|
**Step 4: Return the result**
|
|
|
|
- Return `ans` containing the concatenated array
|
|
|
|
|
|
|
|
In most languages, this can be simplified using built-in concatenation operators or methods. Python allows `nums + nums` or `nums * 2` for direct concatenation.
|
|
|
|
common_pitfalls:
|
|
- title: Off-by-One Errors in Manual Implementation
|
|
description: |
|
|
When manually filling the result array using indices, a common mistake is getting the index calculation wrong for the second half.
|
|
|
|
For the second half, element `nums[i]` should go to `ans[i + n]`, not `ans[i + n - 1]` or `ans[i + n + 1]`.
|
|
|
|
Example with `nums = [1, 2, 3]` (n=3):
|
|
- `nums[0]` goes to `ans[0]` AND `ans[3]`
|
|
- `nums[1]` goes to `ans[1]` AND `ans[4]`
|
|
- `nums[2]` goes to `ans[2]` AND `ans[5]`
|
|
wrong_approach: "Using incorrect index offset for second half"
|
|
correct_approach: "Use ans[i + n] = nums[i] for the second half"
|
|
|
|
- title: Modifying the Original Array
|
|
description: |
|
|
Some approaches might try to extend the original array in-place. While this works, it modifies the input which may not be desired.
|
|
|
|
Creating a new array preserves the original input and is generally cleaner.
|
|
wrong_approach: "Extending nums in-place"
|
|
correct_approach: "Create a new result array"
|
|
|
|
- title: Overcomplicating the Solution
|
|
description: |
|
|
This is intentionally a simple problem. Don't overthink it by using complex data structures or algorithms.
|
|
|
|
A straightforward concatenation using language features is the expected solution. In Python, `nums + nums` or `nums * 2` is perfectly acceptable and idiomatic.
|
|
|
|
key_takeaways:
|
|
- "**Array concatenation basics**: Understanding how to combine arrays is fundamental to many problems"
|
|
- "**Index relationships**: The mapping `ans[i] = ans[i + n] = nums[i]` demonstrates how indices relate across duplicated data"
|
|
- "**Language idioms**: Most languages have built-in ways to concatenate arrays — use them when appropriate"
|
|
- "**Simplicity is valid**: Not every problem requires complex algorithms; recognising simple solutions is a skill"
|
|
|
|
time_complexity: "O(n). We iterate through the input array once (or twice with explicit copying), where `n` is the length of `nums`."
|
|
space_complexity: "O(n). The output array `ans` has length `2n`, which is O(n) additional space. Note: if we count output as required space, it's O(2n) = O(n)."
|
|
|
|
solutions:
|
|
- approach_name: Built-in Concatenation
|
|
is_optimal: true
|
|
code: |
|
|
def get_concatenation(nums: list[int]) -> list[int]:
|
|
# Python allows direct list concatenation with +
|
|
# This creates a new list with nums followed by nums
|
|
return nums + nums
|
|
explanation: |
|
|
**Time Complexity:** O(n) — Creating the concatenated list requires copying all elements twice.
|
|
|
|
**Space Complexity:** O(n) — The result array has `2n` elements.
|
|
|
|
This is the most Pythonic solution. The `+` operator creates a new list containing all elements from both operands. Alternatively, `nums * 2` achieves the same result by repeating the list twice.
|
|
|
|
- approach_name: Manual Index Copying
|
|
is_optimal: false
|
|
code: |
|
|
def get_concatenation(nums: list[int]) -> list[int]:
|
|
n = len(nums)
|
|
# Pre-allocate array of size 2n
|
|
ans = [0] * (2 * n)
|
|
|
|
# Fill both halves in a single pass
|
|
for i in range(n):
|
|
# First half: direct copy
|
|
ans[i] = nums[i]
|
|
# Second half: offset by n
|
|
ans[i + n] = nums[i]
|
|
|
|
return ans
|
|
explanation: |
|
|
**Time Complexity:** O(n) — Single pass through the input array.
|
|
|
|
**Space Complexity:** O(n) — The result array has `2n` elements.
|
|
|
|
This approach explicitly demonstrates the index relationship described in the problem. While more verbose than using built-in concatenation, it clearly shows how `ans[i]` and `ans[i + n]` both receive `nums[i]`. This is useful for understanding the underlying mechanics and translates well to languages without convenient concatenation operators.
|
|
|
|
- approach_name: List Comprehension
|
|
is_optimal: false
|
|
code: |
|
|
def get_concatenation(nums: list[int]) -> list[int]:
|
|
n = len(nums)
|
|
# Use modulo to wrap index back to start
|
|
return [nums[i % n] for i in range(2 * n)]
|
|
explanation: |
|
|
**Time Complexity:** O(n) — Iterates through `2n` indices.
|
|
|
|
**Space Complexity:** O(n) — The result list has `2n` elements.
|
|
|
|
This approach uses modulo arithmetic to cycle through the original array twice. When `i >= n`, the expression `i % n` wraps back to give indices `0, 1, 2, ...` again. While clever, it's less readable than direct concatenation and adds unnecessary computation with the modulo operation.
|