🚀 I’m kick-starting a new LeetCode Solutions Series, where I’ll break down coding problems step by step, explaining the logic and best approaches! Stay tuned for more solutions. Now, let’s dive into our first problem!
Problem Statement
You are given two integer arrays nums1
and nums2
, sorted in non-decreasing order, and two integers m
and n
, representing the number of elements in nums1
and nums2
respectively.
Merge nums1
and nums2
into a single array sorted in non-decreasing order.
The final sorted array should not be returned by the function, but instead be stored inside the array nums1
. To accommodate this, nums1
has a length of m + n
, where the first m
elements denote the elements that should be merged, and the last n
elements are set to 0
and should be ignored. nums2
has a length of n
.
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
Input: nums1 = [0], m = 0, nums2 = [1], n = 1
Output: [1]
Approach: Two Pointers from the End
Idea
Instead of merging from the beginning, we can merge from the end of nums1
to efficiently place the largest elements in the correct position. This avoids the need for extra space.
Algorithm
- Use three pointers:
p1
at the last non-zero element innums1
(m - 1
)p2
at the last element innums2
(n - 1
)p
at the last index ofnums1
(m + n - 1
)
- Compare elements from
nums1
andnums2
, placing the larger one at indexp
. - Move the pointers accordingly.
- If any elements remain in
nums2
, copy them tonums1
.
class Solution:
def merge(self, nums1, m, nums2, n):
p1, p2, p = m - 1, n - 1, m + n - 1
# Merge from the back
while p1 >= 0 and p2 >= 0:
if nums1[p1] > nums2[p2]:
nums1[p] = nums1[p1]
p1 -= 1
else:
nums1[p] = nums2[p2]
p2 -= 1
p -= 1
# Copy remaining elements from nums2 if any
while p2 >= 0:
nums1[p] = nums2[p2]
p2 -= 1
p -= 1
Step-by-Step Execution
nums1 = [1,2,3,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
nums1 = [1, 2, 3, 0, 0, 0]
nums2 = [2, 5, 6]
Pointers: p1 = 2, p2 = 2, p = 5
Step 1: Compare nums1[2] = 3
and nums2[2] = 6
6 > 3
, place6
atnums1[5]
- Move
p2 = 1
,p = 4
nums1 = [1, 2, 3, 0, 0, 6]
Step 2: Compare nums1[2] = 3
and nums2[1] = 5
5 > 3
, place5
atnums1[4]
- Move
p2 = 0
,p = 3
nums1 = [1, 2, 3, 0, 5, 6]
Step 3: Compare nums1[2] = 3
and nums2[0] = 2
3 > 2
, place3
atnums1[3]
- Move
p1 = 1
,p = 2
nums1 = [1, 2, 3, 3, 5, 6]
Step 4: Compare nums1[1] = 2
and nums2[0] = 2
2 == 2
, place2
fromnums2
atnums1[2]
- Move
p2 = -1
,p = 1
nums1 = [1, 2, 2, 3, 5, 6]
Step 5: nums2
is exhausted, so we are done.
Time and Space Complexity
- Time Complexity:
O(m + n)
since each element is processed once. - Space Complexity:
O(1)
, as we modifynums1
in place without extra space.
Conclusion
The two-pointer approach provides an efficient way to merge two sorted arrays in-place without using extra space. This method is optimal and is commonly used in similar merging problems.
🚀 Stay tuned for more LeetCode solutions in this blog series!