Рубрики

Kth наименьший элемент по рядам и столбцам сортируются 2D массив | Комплект 1

Дана матрица nxn, где каждая строка и столбец отсортированы в неубывающем порядке. Найдите k-й наименьший элемент в данном двумерном массиве.

Например, рассмотрим следующий 2D массив.

        10, 20, 30, 40
        15, 25, 35, 45
        24, 29, 37, 48
        32, 33, 39, 50
The 3rd smallest element is 20 and 7th smallest element is 30

Идея заключается в том, чтобы использовать мин кучу. Ниже приведен подробный шаг.
1) Постройте минимальную кучу элементов из первого ряда. Запись кучи также хранит номер строки и номер столбца.
2) Выполните следующие K раз.
… А) Получить минимальный элемент (или корень) из минимальной кучи.
… Б) Найти номер строки и номер столбца минимального элемента.
… с) Заменить корень со следующим элементом из тех же самой колонки и мин-heapify корня.
3) Возвращает последний экстрагированных корень.

Ниже приведена реализация вышеуказанного алгоритма.

C ++

// k-й по величине элемент в 2d массиве, отсортированный по строкам и столбцам
#include<iostream>
#include<climits>

using namespace std;

  
// Структура для хранения записи кучи. Запись содержит
// значение от 2D массива, строк и столбцов чисел значения

struct HeapNode {

    int val;  // значение для хранения

    int r;    // номер строки значения в 2D массиве

    int c;    // номер столбца значения в 2D массиве

};

  
// Утилита для замены двух элементов HeapNode.

void swap(HeapNode *x, HeapNode *y) {

    HeapNode z = *x;

    *x = *y;

    *y = z;

}

  
// Вспомогательная функция для minheapify узла harr [i] кучи
// хранится в harr []

void minHeapify(HeapNode harr[], int i, int heap_size)

{

    int l = i*2 + 1;

    int r = i*2 + 2;

    int smallest = i;

    if (l < heap_size && harr[l].val < harr[i].val)

        smallest = l;

    if (r < heap_size && harr[r].val < harr[smallest].val)

        smallest = r;

    if (smallest != i)

    {

        swap(&harr[i], &harr[smallest]);

        minHeapify(harr, smallest, heap_size);

    }

}

  
// Функция полезности для преобразования Harr [] к максимальной куче

void buildHeap(HeapNode harr[], int n)

{

    int i = (n - 1)/2;

    while (i >= 0)

    {

        minHeapify(harr, i, n);

        i--;

    }

}

  
// Эта функция возвращает k-й наименьший элемент в двумерном массиве mat [] []

int kthSmallest(int mat[4][4], int n, int k)

{

    // k должно быть больше 0 и меньше n * n

    if (k <= 0 || k > n*n)

       return INT_MAX;

  

    // Создать минимальную кучу элементов из первого ряда 2D-массива

    HeapNode harr[n];

    for (int i = 0; i < n; i++)

        harr[i] =  {mat[0][i], 0, i};

    buildHeap(harr, n);

  

    HeapNode hr;

    for (int i = 0; i < k; i++)

    {

       // Получить текущий корень кучи

       hr = harr[0];

  

       // Получить следующее значение из столбца корневого значения. Если

       // значение, сохраненное в корне, было последним значением в его столбце,

       // затем присваиваем INFINITE как следующее значение

       int nextval = (hr.r < (n-1))? mat[hr.r + 1][hr.c]: INT_MAX;

  

       // Обновляем корень кучи следующим значением

       harr[0] =  {nextval, (hr.r) + 1, hr.c};

  

       // Heapify root

       minHeapify(harr, 0, n);

    }

  

    // Возвращаем значение в последний извлеченный корень

    return hr.val;

}

  
// программа драйвера для проверки вышеуказанной функции

int main()

{

  int mat[4][4] = { {10, 20, 30, 40},

                    {15, 25, 35, 45},

                    {25, 29, 37, 48},

                    {32, 33, 39, 50},

                  };

  cout << "7th smallest element is " << kthSmallest(mat, 4, 7);

  return 0;

}

python3

# Программа для k-го по величине элемента в 2d-массиве
# отсортировано по строкам и столбцам

from sys import maxsize

  
# Структура для хранения записи кучи.
# Запись содержит значение из 2D-массива,
# строки и номера столбцов значения

class HeapNode:

    def __init__(self, val, r, c):

        self.val = val # значение для хранения

        self.r = r # Номер строки значения в 2D массиве

        self.c = c # Номер столбца значения в 2D массиве

  
# Утилита для минимизации узла harr [i]
# кучи, хранящейся в harr []

def minHeapify(harr, i, heap_size):

    l = i * 2 + 1

    r = i * 2 + 2

    smallest = i

    if l < heap_size and harr[l].val < harr[i].val:

        smallest = l

    if r < heap_size and harr[r].val < harr[smallest].val:

        smallest = r

  

    if smallest != i:

        harr[i], harr[smallest] = harr[smallest], harr[i]

        minHeapify(harr, smallest, heap_size)

  
# Полезная функция для преобразования harr [] в максимальную кучу

def buildHeap(harr, n):

    i = (n - 1) // 2

    while i >= 0:

        minHeapify(harr, i, n)

        i -= 1

  
# Эта функция возвращает k-й наименьший элемент
# в 2D массиве mat [] []

def kthSmallest(mat, n, k):

  

    # k должно быть больше 0 и меньше n * n

    if k <= 0 or k > n * n:

        return maxsize

  

    # Создайте минимальную кучу элементов из

    # первая строка двумерного массива

    harr = [0] * n

    for i in range(n):

        harr[i] = HeapNode(mat[0][i], 0, i)

    buildHeap(harr, n)

  

    hr = HeapNode(0, 0, 0)

    for i in range(k):

  

        # Получить текущий корень кучи

        hr = harr[0]

  

        # Получить следующее значение из столбца значения root.

        # Если значение, хранящееся в корне, было последним значением

        # в столбце, затем присвойте INFINITE в качестве следующего значения

        nextval = mat[hr.r + 1][hr.c] if (hr.r < n - 1) else maxsize

  

        # Обновить корень кучи следующим значением

        harr[0] = HeapNode(nextval, hr.r + 1, hr.c)

  

        # Heapify root

        minHeapify(harr, 0, n)

  

    # Вернуть значение в последний извлеченный корень

    return hr.val

  
Код водителя

if __name__ == "__main__":

    mat = [[10, 20, 30, 40], 

           [15, 25, 35, 45], 

           [25, 29, 37, 48],

           [32, 33, 39, 50]]

    print("7th smallest element is"

             kthSmallest(mat, 4, 7))

  
# Этот код предоставлен
# sanjeev2552


Выход:

7th smallest element is 30

Сложность времени: вышеуказанное решение включает в себя следующие шаги.
1) Создайте минимальную кучу, которая занимает O (n) время
2) Heapify k раз, что занимает O (kLogn) время.
Следовательно, общая временная сложность составляет O (n + kLogn) время.

Выше код может быть оптимизирован, чтобы построить кучу размера к, когда к меньше, чем п. В этом случае, к-й наименьший элемент должен быть в первых к строк и к столбцов.

Скоро мы опубликуем более эффективные алгоритмы для нахождения k-го наименьшего элемента.

Эта статья составлена Рави Гуптой. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Kth наименьший элемент по рядам и столбцам сортируются 2D массив | Комплект 1

0.00 (0%) 0 votes