Разбор задачи: Объединение отсортированных массивов

Предложенный нами код решения:

def sort_merge(nums1, m, nums2, n):
    """
    Объединяет два отсортированных массива nums1 и nums2 в массив nums1, 
    сохраняя порядок неубывания. 
    :param nums1: list[int], массив длиной m + n, первые m элементов значимы
    :param m: int, количество значимых элементов в nums1
    :param nums2: list[int], массив длиной n
    :param n: int, количество значимых элементов в nums2
    """
    # Указатели для массивов
    p1 = m - 1  # Последний значимый элемент в nums1
    p2 = n - 1  # Последний элемент в nums2
    p = m + n - 1  # Последняя позиция в nums1
    
    # Сравнение элементов с конца и заполнение nums1
    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

    # Если остались элементы в nums2
    while p2 >= 0:
        nums1[p] = nums2[p2]
        p2 -= 1
        p -= 1

Функция sort_merge(nums1, m, nums2, n) должна объединить два отсортированных массива (nums1 и nums2) в один отсортированный массив. Объединение выполняется "на месте", в массиве nums1, который изначально имеет достаточную длину для хранения всех элементов из обоих массивов.


Параметры функции

  1. nums1 — список длиной m + n, где первые m элементов содержат значимые данные, а оставшиеся n элементов равны 0 (запасные места для объединения).
  2. m — количество значимых элементов в массиве nums1.
  3. nums2 — второй массив длиной n, который нужно объединить с nums1.
  4. n — количество значимых элементов в массиве nums2.

Подход к решению

Для объединения массивов используется обратный подход:

  • Заполнение nums1 начинается с конца массива, где расположены запасные места, чтобы избежать необходимости сдвига элементов.
  • Сравнение идет между последними элементами значимой части nums1 и nums2.

Шаги алгоритма

  1. Инициализация указателей:
    • p1 указывает на последний значимый элемент в nums1 (m - 1).
    • p2 указывает на последний элемент в nums2 (n - 1).
    • p указывает на последнюю позицию в массиве nums1 (m + n - 1).
  2. Сравнение элементов:
    • Пока оба указателя p1 и p2 находятся в допустимых пределах (p1 >= 0 и p2 >= 0), элементы на позициях p1 и p2 сравниваются.
    • Больший из элементов записывается в позицию p массива nums1. Указатели p и p1 или p2 уменьшаются в зависимости от того, откуда был взят элемент.
  3. Заполнение остатка из nums2:
    • Если в nums2 остались неиспользованные элементы (т.е., p2 >= 0), они записываются в массив nums1 начиная с позиции p.

Пример работы

Входные данные:

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

Ход выполнения:

  • Инициализация: p1 = 2, p2 = 2, p = 5.
  • Шаг 1: Сравниваем nums1[2] (3) и nums2[2] (6). Берем 6, записываем в nums1[5]. Обновляем: nums1 = [1, 2, 3, 0, 0, 6], p2 = 1, p = 4.
  • Шаг 2: Сравниваем nums1[2] (3) и nums2[1] (5). Берем 5, записываем в nums1[4]. Обновляем: nums1 = [1, 2, 3, 0, 5, 6], p2 = 0, p = 3.
  • Шаг 3: Сравниваем nums1[2] (3) и nums2[0] (2). Берем 3, записываем в nums1[3]. Обновляем: nums1 = [1, 2, 3, 3, 5, 6], p1 = 1, p = 2.
  • Шаг 4: Сравниваем nums1[1] (2) и nums2[0] (2). Берем 2, записываем в nums1[2]. Обновляем: nums1 = [1, 2, 2, 3, 5, 6], p2 = -1, p = 1.
  • nums2 пустой, алгоритм завершен.

Результат:

nums1 = [1, 2, 2, 3, 5, 6]

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии