Chuyển tới nội dung chính

[E] Merge Sorted Array

Đề bài

Cho 2 integer arrays nums1nums2, mỗi array đều được sắp xếp theo thứ tự tăng dần. Hai số nguyên mn lần lượt là độ dài của nums1nums2.

Merge nums2 vào nums1 sao cho nums1 array vẫn được sắp xếp theo thứ tự tăng dần.

Ví dụ 1:

Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]

Giải thích
Hai mảng cần gộp là [1,2,3] và [2,5,6].
Kết quả sau khi gộp là [1,2,2,3,5,6], các phần tử được sắp xếp đúng thứ tự.

Ví dụ 2:

Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]

Constraints:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -109 <= nums1[i], nums2[j] <= 109

Phân tích

  • Vì mảng nums1 có đủ chỗ trống để chứa mảng nums2, nên ta có thể gộp nums2 vào nums1 mà không cần tạo mảng mới.
  • Nếu duyệt từ đầu mảng, việc chèn phần tử mới sẽ làm dịch chuyển các phần tử còn lại, dẫn đến độ phức tạp cao.
  • Giải pháp tối ưu:
    • Duyệt từ cuối mảng nums1 (vị trí m + n -1), điền giá trị lớn nhất.
    • Sử dụng 3 con trỏ:
      • p1 trỏ tới vị trí cuối mảng nums1 (vị trí m - 1).
      • p2 trỏ tới vị trí cuối mảng nums2 (vị trí n - 1).
      • p trỏ tới vị trí cuối mảng nums1 (vị trí m + n - 1).

Pseudocode

Function merge(nums1, m, nums2, n):
p1 = m - 1 // Con trỏ cuối cùng của nums1
p2 = n - 1 // Con trỏ cuối cùng của nums2
p = m + n - 1 // Con trỏ cuối cùng của nums1 (vị trí cần điền giá trị)

// Duyệt ngược từ cuối nums1, điền phần tử lớn hơn vào đúng vị trí
While p1 >= 0 AND p2 >= 0:
If nums1[p1] > nums2[p2]: // Nếu nums1 có phần tử lớn hơn
nums1[p] = nums1[p1] // Gán vào vị trí p
p1 = p1 - 1 // Lùi con trỏ nums1
Else:
nums1[p] = nums2[p2] // Gán phần tử từ nums2 vào vị trí p
p2 = p2 - 1 // Lùi con trỏ nums2
p = p - 1 // Lùi con trỏ vị trí điền

// Nếu còn phần tử chưa xét trong nums2, sao chép vào nums1
While p2 >= 0:
nums1[p] = nums2[p2]
p2 = p2 - 1
p = p - 1

Solution

class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1 = m - 1;
int p2 = n - 1;
int p = m + n - 1;
while (p1 >= 0 && p2 >= 0) {
if (nums1[p1] > nums2[p2]) {
nums1[p] = nums1[p1];
p1--;
} else {
nums1[p] = nums2[p2];
p2--;
};
p--;
};
while (p2 >= 0) {
nums1[p] = nums2[p2];
p2--;
p--;
};
};
};