Разбор задачи: Симметричное дерево

Задача заключается в проверке симметричности двоичного дерева относительно его центра. В представлении дерева мы используем список, где каждый узел дерева имеет вид [значение, левое поддерево, правое поддерево]. Если поддерево отсутствует, оно представлено как None.

Алгоритм

  1. Основная идея:
    • Чтобы дерево было симметричным, для каждого узла его левое поддерево должно быть зеркальным его правому поддереву. То есть, левое поддерево и правое поддерево должны быть зеркальными изображениями друг друга.
  2. Рекурсивная проверка:
    • Мы будем использовать рекурсивную функцию is_mirror, которая будет проверять два поддерева (один для левого и один для правого узлов). Если они зеркальны, то дерево симметрично.
    • Функция is_mirror будет проверять следующие условия:
      1. Если оба поддерева пусты, они симметричны.
      2. Если одно поддерево пусто, а другое нет, они не симметричны.
      3. Если корни поддеревьев равны, рекурсивно проверяются их дочерние узлы: для левого поддерева проверяются правые дочерние узлы, а для правого поддерева — левые.
  3. Взаимодействие с основной функцией:
    • Основная функция is_symmetric будет проверять только корень дерева. Если дерево пустое (root равно None), то оно считается симметричным.
    • После этого вызывается рекурсивная проверка с левого и правого поддерева корня.

Код

def is_symmetric(root):
    """
    Проверяет, является ли двоичное дерево симметричным относительно своего центра.
    :param root: list, корень двоичного дерева в виде вложенного списка [значение, левое_поддерево, правое_поддерево]
    :return: bool, True если дерево симметрично, иначе False
    """
    def is_mirror(t1, t2):
        # Если оба поддерева пусты, то они симметричны
        if not t1 and not t2:
            return True
        # Если одно из поддеревьев пусто, а другое нет, то не симметричны
        if not t1 or not t2:
            return False
        # Если корни поддеревьев равны, то проверяем их дочерние узлы
        return t1[0] == t2[0] and is_mirror(t1[1] if len(t1) > 1 else None, t2[2] if len(t2) > 2 else None) and is_mirror(t1[2] if len(t1) > 2 else None, t2[1] if len(t2) > 1 else None)

    if not root:
        return True
    return is_mirror(root[1] if len(root) > 1 else None, root[2] if len(root) > 2 else None)

Разбор по шагам:

  1. Основная функция is_symmetric:
    • Принимает корень дерева в виде вложенного списка.
    • Если дерево пустое (root равно None), возвращается True, так как пустое дерево считается симметричным.
    • Для непустого дерева вызывается вспомогательная функция is_mirror, которая проверяет симметричность двух поддеревьев: левого и правого.
  2. Вспомогательная функция is_mirror:
    • Принимает два поддерева t1 и t2 (левое и правое поддерево для данного узла).
    • Условия симметричности:
      • Если оба поддерева пусты (not t1 and not t2), они симметричны, возвращается True.
      • Если одно из поддеревьев пусто, а другое нет (not t1 or not t2), возвращается False.
      • Если корни поддеревьев равны (t1[0] == t2[0]), проверяются их дочерние узлы:
        • Левое поддерево t1 должно быть зеркалом правого поддерева t2.
        • Правое поддерево t1 должно быть зеркалом левого поддерева t2.
    • Для этого вызываются рекурсивные вызовы с соответствующими дочерними узлами:
      • is_mirror(t1[1], t2[2]): проверка, если левое поддерево t1 и правое поддерево t2 симметричны.
      • is_mirror(t1[2], t2[1]): проверка, если правое поддерево t1 и левое поддерево t2 симметричны.
  3. Как работает решение:
    • Для каждого узла дерева мы проверяем, зеркальны ли его левые и правые поддеревья.
    • Если на любом уровне дерева не выполняется условие симметрии, дерево сразу считается несимметричным и функция возвращает False.
    • Если на всех уровнях условия симметрии выполняются, функция возвращает True.

Пример:

Для дерева:

    1
   / \
  2   2
 / \ / \
3  4 4  3

Выполнится следующий процесс:

  • Проверяем корень 1:
    • Левое поддерево: [2, [3, None, None], [4, None, None]]
    • Правое поддерево: [2, [4, None, None], [3, None, None]]
  • Проверяем поддеревья для 2:
    • Левое поддерево для первого 2: [3, None, None], правое для второго 2: [3, None, None], и они одинаковы.
    • Правое поддерево для первого 2: [4, None, None], левое для второго 2: [4, None, None], и они одинаковы.
  • Все условия симметрии выполняются, дерево считается симметричным.

 



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