Матрица. Сегодня немного поиграем с матрицами! : 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. Кто-то заметил, что есть лучший способ решить эту проблему. Вы можете найти небольшую статью здесь. Надеюсь, вам понравится! ^ _ ^