Матрица. Сегодня немного поиграем с матрицами! : D Они очень полезны в программировании, и я подумал, что у нас должны быть проблемы с кодированием, которые связаны с ними.

Как наш последний вызов, этот также исходит от HackerRank ^ _ ^

Диагональная разница

Учитывая квадратную матрицу размера n * n, вычислите абсолютную разницу между суммами ее диагоналей.

Для тех из вас, кто не слишком знаком с матрицами, вот пример:

2  3  4
5  3 -1
9  8 -2

Что, очевидно, дает нам две диагонали: 2, 3, -2 и 4, 3, 9. Если сложить их, мы получим 3 для первого и 16 для второго. Тогда их абсолютная разность равна: |3 — 16| = 13. Все просто: D.

У нас также может быть матрица 4 * 4 или даже матрица 10 * 10, в основном небо - это предел!

Решение JavaScript

В JavaScript мы собираемся создать матрицу, объединяющую несколько arrays в более крупный array. Таким образом, приведенная выше матрица в JavaScript будет выглядеть так: var matrix = [[2, 3, 4], [5, 3, -1], [9, 8, -2]], и мы можем манипулировать каждым элементом, как с обычным массивом. Например, чтобы получить первый термин, мы должны написать его так: arr[0][0], поскольку массивы JavaScript начинаются с индекса 0. Довольно просто, правда? К этому быстро привыкнешь :).

Хорошо ... тогда наше решение довольно простое, правда? Просто запишите все индексы элементов, которые нам нужны, а затем произведите небольшую математику ... Насколько это может быть сложно?

Что ж ... даже при том, что это может быть «нормально» делать это вручную с матрицей 3 * 3, в нашем случае такой подход не является хорошей идеей, потому что мы можем каждый раз получать матрицу разного размера. В этом случае нам нужно рассчитать его более динамически, используя два цикла.

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

Предположим, у вас есть функция calculateDiagonals, которая в качестве входных данных получит matrix. Давайте сначала напишем эти циклы:

function calculateDiagonals(matrix){
    var n = matrix.length;
    for(var i=0; i<n; i++){
        for(var j=0; j<n; j++){
        }
    }
}

Обратите внимание, что я также сохранил matrix.length в переменной n, которая используется для наших циклов. Таким образом, нам не нужно пересчитывать длину матрицы на каждой итерации. Это хороший способ сэкономить время вычислений.

Отлично ... Итак, теперь у нас есть два индекса: i и j, которые будут увеличиваться на каждой итерации на одну единицу. В основном в матрице 2 * 2 индексы будут выглядеть так на каждой итерации:

i = 0 and j = 0;
i = 0 and j = 1;
i = 1 and j = 0;
i = 1 and j = 1;

Для такой матрицы, как [[2, 3], [4, 0]], мы шаг за шагом получим следующие значения: 2, 3, 4 and 0. Довольно аккуратно!

Теперь, когда мы знаем, как получить каждое значение из матрицы, пришло время сосредоточиться на том, что нам действительно нужно, на диагоналях!

Для лучшего обучения я предлагаю вам потратить некоторое время и самостоятельно выяснить, какова взаимосвязь между индексами (i и j) на каждой диагонали. Я узнал об этом, написав это на листе бумаги. Очень полезный!

Хороший! Теперь, когда вы ее решили, я покажу вам свой подход, и вы сможете их сравнить! : D Вот простая 3 * 3 матрица, содержащая индексы для i и j:

(0, 0) (0, 1) (0, 2)
(1, 0) (1, 1) (1, 2)
(2, 0) (2, 1) (2, 2)

При этом i - первое число, а j - второе.

Первая диагональ

Это довольно очевидно. Главная диагональ, как ее называют, содержит те элементы, у которых индекс i равен индексу j.

Вторая диагональ

Или контрдиагональ, это немного сложнее. Посмотрим, какие отношения.

Как вы могли заметить, если вы сложите индексы на второй диагонали для этой 3 * 3 матрицы, вы всегда получите сумму 2. Это длина матрицы минус один. Это будет работать для любой заданной n * n матрицы. Круто, правда? : D

Теперь, когда мы разобрались с этим, давайте вернемся к нашему коду.

Я собираюсь добавить еще две переменные, которые будут хранить сумму элементов диагоналей, diag1 и diag2, и инициализировать их с помощью 0:

function calculateDiagonals(matrix){
    var n = matrix.length;
    var diag1 = 0;
    var diag2 = 0;
    for(var i=0; i<n; i++){
        for(var j=0; j<n; j++){
        }
    }
}

Затем давайте проверим, есть ли в текущей итерации элемент любой из диагоналей. Если мы это сделаем, мы добавим их к сумме:

function calculateDiagonals(matrix){
    var n = matrix.length;
    var diag1 = 0;
    var diag2 = 0;
    for(var i=0; i<n; i++){
        for(var j=0; j<n; j++){
            // an element from the main diagonal
            if(i === j) { 
                diag1 += matrix[i][j];
            }
            // an element from the second diagonal
            if(i + j === n - 1){
                diag2 += matrix[i][j];
            }
        }
    }
}

Обратите внимание, что я использовал два оператора if, по одному для каждой диагонали. Когда я впервые попытался решить эту проблему, у меня был оператор else для второй диагонали. Но это неверно, потому что, когда у вас есть матрица n * n, где n является нечетным числом, центральный элемент будет находиться на обеих диагоналях, и при использовании оператора else он не будет добавлен для второй суммы диагонали в нашем case diad2. Я потратил несколько минут на то, чтобы выяснить, где была моя ошибка. : D

Идеально! Все, что осталось сделать, это return абсолютную разницу диагоналей:

function calculateDiagonals(matrix){
    var n = matrix.length;
    var diag1 = 0;
    var diag2 = 0;
    for(var i=0; i<n; i++){
        for(var j=0; j<n; j++){
            // an element from the main diagonal
            if(i === j) { 
                diag1 += matrix[i][j];
            }
            // an element from the counterdiagonal
            if(i + j === n - 1){
                diag2 += matrix[i][j];
            }
        }
    }
    return Math.abs(diag1 - diag2);
}

Вот и все, ребята! Поздравляем! : D

Заключение

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

Вы можете подписаться на меня, чтобы получать обновления, когда я публикую новые задачи по программированию. Также вы можете прислать мне свои решения или свои идеи для любой задачи кодирования. Я был бы счастлив их прочитать. ;)

Если вам понравилась эта задача и вы нашли ее полезной, я был бы искренне признателен, если вы нажмете кнопку Рекомендовать 💚.

P.S. Кто-то заметил, что есть лучший способ решить эту проблему. Вы можете найти небольшую статью здесь. Надеюсь, вам понравится! ^ _ ^