Каждый день я решаю несколько задач по программированию и головоломок из рейтингового режима Codr. Цель - достичь звания гения, попутно объясняю, как их решаю. Для начала вам не нужен опыт программирования, и вы узнаете массу нового и интересного по ходу дела.
function canJump(nums) { let max = 0; for(let i = 0; i < nums.length; i++) { if (max < i) return false; max = Math.max(nums[i] + i, max); } return max >= nums.length - 1 }
let A = canJump([5,0,0,6,4,6]);
// A = ? (boolean)
Код этого задания довольно короткий, давайте посмотрим, о чем он вообще. Нам нужно вычислить логическое значение A
: let A = canJump([5,0,0,6,4,6]);
На первый взгляд я понятия не имею, что делает функция canJump
, поэтому нам придется проанализировать ее более внимательно.
for (let i = 0; i < nums.length; i++) {
if (max < i) return false;
max = Math.max(nums[i] + i, max);
}
Эти три строки кода делают следующее: перебирают каждое число в массиве nums
; проверка того, меньше ли max
, чем i
, в этом случае функция немедленно возвращает ложное значение; наконец, он определяет новое максимальное значение. Условие if фактически гарантирует, что размер max
перехода больше текущего индекса i
цикла for.
Этот алгоритм на самом деле определяет, может ли он «прыгнуть» в определенную позицию, где каждое число представляет максимальную длину прыжка.
Последняя строка кода показывает его окончательное состояние: return max >= nums.length - 1
Он проверяет, больше ли max или равен размеру массива nums
', что означает, что весь алгоритм проверяет, можно ли достичь конца массива, начиная с первый индекс.
Ниже приведен псевдокод, чтобы проиллюстрировать это:
nums = [5, 0, 0, 6, 4, 6]
-> i = 0 nums[i] = 5 max = max(5+0, 0) = 5 * from this index, we can jump max 5 positions further
-> i = 1 nums[i] = 0 max = max(0+1, 5) = 5 * if we jump to here, we cannot jump any further (= 0)
-> i = 2 nums[i] = 0 max = max(0+2, 5) = 5 * if we jump to here, we cannot jump any further (= 0)
-> i = 3 nums[i] = 6 max = max(6+3, 5) = 9 * if we jump to here, we can jump max 6 positions further
-> i = 4 nums[i] = 4 max = max(4+4, 9) = 9 * if we jump to here, we can jump max 4 positions further
-> i = 5 nums[i] = 6 max = max(6+5, 9) = 11 * if we jump to here, we can jump max 6 positions further
Эта задача довольно тривиальна и в нашу пользу, потому что мы можем достичь конца массива (i = 5) с самого первого индекса; потому что первое число 5.
Мы даже можем значительно оптимизировать этот алгоритм, выполнив следующие действия:
function canJump(nums) { let max = 0; for(let i = 0; i < nums.length; i++) { if (max < i) return false; else if (max >= nums.length - 1) return true; max = Math.max(nums[i] + i, max); } return max >= nums.length - 1 }
let A = canJump([5,0,0,6,4,6]);
Дополнительный оператор else заставляет функцию возвращаться намного раньше, если она обнаруживает, что конец может быть достигнут, поэтому ей не нужно перебирать все числа.
Альтернативный способ написания этого кода таков:
function canJump(nums) { let max = 0; for(let i = 0; i < nums.length; i++) { if (max < i) return false; max = Math.max(nums[i] + i, max); if (max >= nums.length - 1) return true; } return false; }
let A = canJump([5,0,0,6,4,6]);
Решая эти задачи, вы становитесь лучшим программистом. Вы узнаете новые и лучшие способы анализа, отладки и улучшения кода. В результате вы станете более продуктивным и ценным в бизнесе. Присоединяйтесь ко мне на Пути к гениальности и улучшите свои навыки программирования на https://nevolin.be/codr/