πŸ”’ Как ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий Π² массивС Python?

ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ инвСрсий Π² массивС Π² Python ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° слияния.


def merge_sort(arr):
    if len(arr) <= 1:
        return arr, 0
    
    mid = len(arr) // 2
    left, inversion_left = merge_sort(arr[:mid])
    right, inversion_right = merge_sort(arr[mid:])
    merged, inversion_merge = merge(left, right)
    
    total_inversions = inversion_left + inversion_right + inversion_merge
    return merged, total_inversions

def merge(left, right):
    merged = []
    inversion_count = 0
    i, j = 0, 0
    
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            inversion_count += len(left) - i
            j += 1
    
    merged += left[i:]
    merged += right[j:]
    
    return merged, inversion_count

arr = [4, 2, 1, 3, 5]
sorted_arr, inversions = merge_sort(arr)
print(f"ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ инвСрсий Π² массивС: {inversions}")
  

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ рСкурсивная рСализация Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° слияния. Основная идСя Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠΈ исходного массива Π½Π° Π΄Π²Π΅ Ρ€Π°Π²Π½Ρ‹Π΅ части, сортировкС ΠΈΡ… ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΈ Π·Π°Ρ‚Π΅ΠΌ объСдинСнии отсортированных массивов.

Π’ΠΎ врСмя слияния, Ссли элСмСнт ΠΈΠ· ΠΏΡ€Π°Π²ΠΎΠΉ части массива мСньшС элСмСнта ΠΈΠ· Π»Π΅Π²ΠΎΠΉ части, Ρ‚ΠΎ это инвСрсия. Π’ этом случаС, ΠΌΡ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ счСтчик инвСрсий Π½Π° количСство ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ элСмСнтов Π² Π»Π΅Π²ΠΎΠΉ части массива.

ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ сортировки, Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ "inversions" Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒΡΡ ΠΎΠ±Ρ‰Π΅Π΅ количСство инвСрсий Π² массивС.

Π”Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚

Как ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий Π² массивС Python

Π˜Π½Π²Π΅Ρ€ΡΠΈΡ Π² массивС происходит, ΠΊΠΎΠ³Π΄Π° Π΄Π²Π° элСмСнта находятся Π² Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ порядкС. НапримСр, Π² массивС [2, 4, 1, 3, 5] инвСрсиями Π±ΡƒΠ΄ΡƒΡ‚ (2, 1) ΠΈ (4, 1). ΠžΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎ ΡƒΠΌΠ΅Ρ‚ΡŒ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий, особСнно ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°ΠΌΠΈ сортировки ΠΈ поиска.

БущСствуСт нСсколько ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΊ поиску количСства инвСрсий Π² массивС, ΠΈ ΠΌΡ‹ Ρ€Π°Π·Π±Π΅Ρ€Ρ‘ΠΌ Π΄Π²Π° ΠΈΠ· Π½ΠΈΡ… - Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ слияния ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ°.

Алгоритм слияния

Алгоритм слияния Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡƒΡ‚Π΅ΠΌ раздСлСния массива Π½Π° Π΄Π²Π΅ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ‹, сортировки ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ‹ ΠΈ Π·Π°Ρ‚Π΅ΠΌ слияния ΠΈΡ… Π² ΠΎΠ΄ΠΈΠ½ отсортированный массив. Π’ΠΎ врСмя слияния ΠΌΡ‹ подсчитываСм количСство инвСрсий.


def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]

    left = merge_sort(left)
    right = merge_sort(right)

    return merge(left, right)

def merge(left, right):
    result = []
    count = 0
    i = j = 0

    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
            count += len(left) - i

    result.extend(left[i:])
    result.extend(right[j:])

    return result, count

arr = [2, 4, 1, 3, 5]
sorted_arr, inversions = merge_sort(arr)
print(f"ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ инвСрсий: {inversions}")

Π’ этом ΠΊΠΎΠ΄Π΅ ΠΌΡ‹ сначала раздСляСм массив ΠΏΠΎΠΏΠΎΠ»Π°ΠΌ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ рСкурсивно Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ merge_sort для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ‹. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ merge, которая сливаСт Π΄Π²Π΅ отсортированныС ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ‹ Π² ΠΎΠ΄ΠΈΠ½ отсортированный массив. Π’ΠΎ врСмя слияния ΠΌΡ‹ считаСм количСство инвСрсий.

ΠœΠ΅Ρ‚ΠΎΠ΄ ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ°

Π’ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ° ΠΌΡ‹ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΠΌ ΠΏΠΎ массиву ΠΈ мСняСм мСстами сосСдниС элСмСнты, Ссли ΠΎΠ½ΠΈ находятся Π² Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ порядкС. ΠŸΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±ΠΌΠ΅Π½Π΅ ΠΌΡ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ счСтчик инвСрсий. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ прост Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½ΠΎ Π½Π΅ являСтся эффСктивным для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов.


def bubble_sort(arr):
    inversions = 0
    n = len(arr)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                inversions += 1

    return inversions

arr = [2, 4, 1, 3, 5]
inversions = bubble_sort(arr)
print(f"ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ инвСрсий: {inversions}")

Π’ этом ΠΊΠΎΠ΄Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ†ΠΈΠΊΠ»Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ ΠΏΠΎ массиву ΠΈ ΠΌΠ΅Π½ΡΡ‚ΡŒ мСстами сосСдниС элСмСнты, Ссли ΠΎΠ½ΠΈ Π½Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ порядку сортировки. Π—Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ ΠΌΡ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ счСтчик инвСрсий. Π’ ΠΊΠΎΠ½Ρ†Π΅ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ количСство инвСрсий Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ inversions.

Оба этих ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ эффСктивно ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий Π² массивС. Алгоритм слияния ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅ для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ Π»ΡƒΡ‡ΡˆΡƒΡŽ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ O(n log n). Однако ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π΅Π½ для Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов ΠΈΠ»ΠΈ Π² случаях, ΠΊΠΎΠ³Π΄Π° Ρƒ нас Π΅ΡΡ‚ΡŒ ограничСния Π½Π° использованиС Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ памяти.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, ΠΊΠ°ΠΊ ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий Π² массивС Python ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π΄Π²ΡƒΡ… Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ². Алгоритм слияния обСспСчиваСт Π»ΡƒΡ‡ΡˆΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ΄ΠΎΠ±Π΅Π½ для Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов ΠΈΠ»ΠΈ Π² случаях с ограничСниями Π½Π° использованиС памяти. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ эти ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π² зависимости ΠΎΡ‚ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ вашСй Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΈ Π²Ρ‹ смоТСтС эффСктивно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с инвСрсиями Π² массивах.

Π’ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

SOLID ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ Π½Π° Python: DIP - ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ инвСрсии зависимостСй / Dependency Inversion Principle

Π£Ρ€ΠΎΠΊΠΈ Python - Бписки (ΠœΠ°ΡΡΠΈΠ²Ρ‹)

Π£Ρ€ΠΎΠΊΠΈ Python / Π˜Π½Π΄Π΅ΠΊΡΡ‹ ΠΈ срСзы Π² массивах, списках

ΠŸΠΎΡ…ΠΎΠΆΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ:

πŸ”§ Как ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π² Python: ПошаговоС руководство с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ 🐍

πŸ”‘ Как Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° нСсколько Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Python: простыС инструкции ΠΈ совСты

πŸ”‘ΠšΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ глобальной Π² Python?

πŸ”’ Как ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство инвСрсий Π² массивС Python?

Как ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π°Ρ‚ΡƒΡ€Π°Π»ΡŒΠ½Ρ‹ΠΉ Π»ΠΎΠ³Π°Ρ€ΠΈΡ„ΠΌ Π² Python: простой Π³Π°ΠΉΠ΄ с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ ΠΊΠΎΠ΄ΠΎΠΌ πŸ‘¨β€πŸ’»

πŸ” Как обозначаСтся Π±Π΅ΡΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΡΡ‚ΡŒ Π½Π° ΠŸΠΈΡ‚ΠΎΠ½Π΅? πŸ’»πŸ ΠΠ°ΡƒΡ‡ΠΈΡΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с бСсконСчными числами!

πŸ–ΌοΈ Как вывСсти ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python PIL