JavaScript | LeetCode – Telegram
JavaScript | LeetCode
9.44K subscribers
228 photos
1.14K links
Cайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp

Тесты t.me/+T0COHtFzCJkwMDUy
Вопросы собесов t.me/+kXKgJEjRUww3N2Ni
Вакансии t.me/+CgCAzIyGHHg0Nzky
Download Telegram
Задача: 32. Longest Valid Parentheses #hard

Условие:
Учитывая строку, содержащую только символы «(» и «)», верните длину самых длинных допустимых (правильно сформированных) круглых скобок. подстрока



Решение:
var longestValidParentheses = function(s) {
const n = s.length; const S = [-1];
let x = 0; for (let i = 0; i < n; ++i)
if (s[i] === '(') S.push(i); // open; mark start index
else { S.pop(); // close; remove a start index
if (!S.length) S.push(i); // invalid; reset index to new start
else x = Math.max(x, i - S[S.length - 1]); // valid; save the length
} return x;
};

Пояснение:
1. Создаётся функция longestValidParentheses, которая принимает строку s в качестве аргумента.2. Вычисляется длина строки s и создаётся массив S с начальным элементом -1 и переменная x для хранения длины самой длинной правильной скобочной последовательности.
3. Происходит итерация по символам строки s. Если текущий символ - это открывающая скобка (, то индекс текущего символа добавляется в массив S, что помечает начало текущей возможной последовательности скобок.4. Если текущий символ - это закрывающая скобка ), то удаляется последний элемент из массива S, что соответствует удалению начального индекса открывающей скобки.
5. Проверяется длина массива S. Если он пустой (после удаления всех открывающих скобок), то текущий индекс добавляется обратно в массив S, что обычно указывает на начало новой последовательности скобок.6. Если массив S не пустой после удаления открывающей скобки, то вычисляется длина текущей валидной скобочной последовательности и обновляется переменная x с максимальным значением.
7. В конце выполнения итерации возвращается значение x, которое представляет собой длину самой длинной правильной скобочной последовательности в строке s.
👍3
Задача: 33. Search in Rotated Sorted Array #medium

Условие:
Существует целочисленный массив nums, отсортированный по возрастанию (с разными значениями).
Перед передачей в вашу функцию nums, возможно, поворачивается с неизвестным индексом поворота k (1 <= k < nums.length), так что результирующий массив имеет вид [nums[k], nums[k+1],... , nums[n-1], nums[0], nums[1], ..., nums[k-1]] (с индексом 0). Например, [0,1,2,4,5,6,7] можно повернуть с опорным индексом 3 и превратить в [4,5,6,7,0,1,2].
Учитывая массив nums после возможного поворота и целочисленную цель, верните индекс цели, если он находится в nums, или -1, если он не в nums.
Вы должны написать алгоритм со сложностью выполнения O(log n).


Решение:
/** * @param {number[]} nums
* @param {number} target * @return {number}
*/var search = function(nums, target) {
let res=nums.indexOf(target);
if(res){ return res;
} else if(res==-1)
{ return -1;
} else{
return res; }
};


Пояснение:
1. Объявление функции search, которая принимает массив чисел nums и целевое число target в качестве аргументов.

2. В комментарии указаны типы аргументов и возвращаемое значение функции.
3. В теле функции начинается выполнение:
- Создается переменная res, которая содержит индекс первого вхождения целевого числа target в массиве nums. Функция indexOf возвращает -1, если значение не найдено.
- Далее выполняется проверка if, где мы первоначально проверяем res как булево значение свойства объекта. Если индекс числа target был найден (не равен -1), то значение res будет истинным и мы возвращаем его. - В случае, если res равно -1, что означает, что число target не найдено в массиве, мы возвращаем -1.
- Если ни одно из предыдущих условий не сработало, это означает, что res содержит индекс числа target, и мы возвращаем его.
4. Выполнение функции завершается возвратом соответствующего значения: индекса числа target, -1 в случае его отсутствия или индекса числа target в противном случае.

5. Этот код проверяет наличие целевого числа в массиве и возвращает его индекс в случае нахождения, -1 в случае отсутствия числа. Однако стоит отметить, что внутри if (res) res будет равен 0 (индекс первого элемента), а это может быть истолковано как false, что может привести к неправильной работе функции при значении target равном 0. Необходимо учесть этот момент при работе с функцией.
👍3👀21
Задача: 34. Find First and Last Position of Element in Sorted Array #medium

Условие:
Учитывая массив целых чисел, отсортированных в порядке неубывания, найдите начальную и конечную позицию заданного целевого значения.
Если цель не найдена в массиве, верните [-1, -1].
Вы должны написать алгоритм со сложностью выполнения O(log n).



Решение:
/** * @param {number[]} nums
* @param {number} target * @return {number[]}
*/var searchRange = function(nums, target) {
return [nums.indexOf(target), nums.lastIndexOf(target)]
};

Пояснение:
1. Объявление функции searchRange, которая принимает массив чисел nums и целевое число target в качестве аргументов.
2. В комментарии указаны типы аргументов и возвращаемое значение функции.
3. В теле функции происходит выполнение следующих действий: - Функция indexOf(target) возвращает индекс первого вхождения целевого числа target в массиве nums.
- Функция lastIndexOf(target) возвращает индекс последнего вхождения целевого числа target в массиве nums. - Оба индекса (первого и последнего вхождения числа target) затем помещаются в новый массив, который затем возвращается как результат работы функции.
4. После выполнения поиска индексов первого и последнего вхождения числа target в массиве, функция возвращает массив с двумя элементами: индекс первого вхождения и индекс последнего вхождения числа target.
5. Этот код помогает быстро найти и вернуть индексы первого и последнего вхождения целевого числа target в массиве nums. Это может быть полезно, если нужно найти все интервалы, в которых встречается целевое число.


🖥 1429 вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2
Задача: 35. Search Insert Position #easy

Условие:
Учитывая отсортированный массив различных целых чисел и целевое значение, верните индекс, если цель найдена. Если нет, верните индекс там, где он был бы, если бы он был вставлен по порядку.
Вы должны написать алгоритм со сложностью выполнения O(log n).




Решение:
/** * @param {number[]} nums
* @param {number} target * @return {number}
*/var searchInsert = function(nums, target) {
if (nums.indexOf(target) === -1) { for (let i = 0; i <= nums.length; ) {
if (nums[i] < target) { i++;
} else { return i
} }
} else { return nums.indexOf(target);
}};

Пояснение:

1. Объявление функции searchInsert, которая принимает массив чисел nums и целевое число target в качестве аргументов.
2. В комментарии указаны типы аргументов и возвращаемое значение функции.
3. В теле функции выполняются следующие действия: - Проверяется, есть ли целевое число target в массиве nums. Если его индекс равен -1 (то есть он не найден), выполняется следующее:
- Начинается цикл for, который проверяет каждый элемент массива nums. - Если текущий элемент nums[i] меньше целевого числа target, индекс i увеличивается.
- Если текущий элемент nums[i] больше или равен целевому числу target, функция возвращает текущий индекс i. - Если целевое число target найдено в массиве, функция возвращает его индекс, найденный с помощью indexOf.
4. После выполнения поиска индекса для вставки числа target в массив, функция возвращает индекс, указывающий позицию, на которую нужно вставить целевое число.
5. Этот код помогает найти позицию для вставки целевого числа target в упорядоченный массив nums. Если число target уже присутствует в массиве, возвращается его индекс; в противном случае возвращается индекс, указывающий позицию для вставки target так, чтобы массив оставался упорядоченным.
1
Задача: 36. Valid Sudoku #medium

Условие:
Определите, действительна ли доска для судоку 9 x 9. Только заполненные ячейки подлежат проверке согласно следующим правилам:
Каждая строка должна содержать цифры от 1 до 9 без повторений.Каждый столбец должен содержать цифры 1–9 без повторений.
Каждый из девяти подполей сетки размером 3х3 должен содержать цифры от 1 до 9 без повторений.Примечание:
Доска судоку (частично заполненная) может быть допустимой, но не обязательно решаемой.
Только заполненные ячейки должны быть проверены в соответствии с указанными правилами.



Решение:

/**
* @param {character[][]} board * @return {boolean}
*/var isValidSudoku = function(board) {
let rowMap = new Map(); let colmMap = new Map();
let grid33 = new Map();
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++){ let m = board[3 * Math.floor(i / 3) + Math.floor(j / 3)][((i * 3) % 9) + (j % 3)]
if(!rowMap.get(board[i][j]) board[i][j] == '.' ) { rowMap.set(board[i][j], 1)
} else { return false}
if (!colmMap.get(board[j][i]) board[j][i] == '.' ) { colmMap.set(board[j][i], 1)
} else { return false}
if (!grid33.get(m) || m == '.'){ grid33.set(m, 1)
} else { return false}


} rowMap.clear();
grid33.clear(); colmMap.clear();
} return true
};

Пояснение:
1. Объявление функции isValidSudoku, принимающей двумерный массив board, представляющий судоку.
2. В комментарии указаны типы аргументов и возвращаемое значение функции.
3. Создание трех Map (rowMap, colmMap, grid33) для отслеживания уникальности значений в строках, столбцах и 3x3 квадратах судоку.
4. Внешний цикл for от 0 до 8 для перебора строк судоку.
5. Внутренний цикл for от 0 до 8 для перебора ячеек в строке:
- Вычисление индекса m текущей ячейки в 3x3 квадрате. - Проверка условий для строки, столбца и 3x3 квадрата:
- Если значение board[i][j] еще не встречалось в rowMap или равно '.', оно добавляется в rowMap. - Если значение board[j][i] еще не встречалось в colmMap или равно '.', оно добавляется в colmMap.
- Если значение m еще не встречалось в grid33 или равно '.', оно добавляется в grid33. - Если значение уже встречалось, возвращается false.
6. После проверки каждой строки, значения в rowMap, colmMap, grid33 очищаются для следующей итерации.
7. По завершении всех итераций по строкам, если все значения уникальны, функция возвращает true, иначе false.
Этот код проверяет, является ли судоку действительным. Если все условия для уникальности значений в строках, столбцах и 3x3 квадратах выполняются, функция возвращает true. В противном случае возвращается false.
1
Задача: 38. Count and Say #medium

Условие:
Последовательность count-and-say - это последовательность цифровых строк, определяемая рекурсивной формулой:

count-And-Say(1) = "1"
countAndSay(n) - это кодировка длины цикла countAndSay(n - 1).
Кодирование по длине строки (RLE) - это метод сжатия строк, который работает путем замены последовательных идентичных символов (повторяющихся 2 или более раз) путем объединения символа и числа, обозначающего количество символов (длину строки). Например, чтобы сжать строку "3322251", мы заменяем "33" на "23", заменяем "222" на "32", заменяем "5" на "15" и заменяем "1" на "11". Таким образом, сжатая строка становится "23321511".

Учитывая положительное целое число n, верните n-й элемент последовательности подсчета и произнесения.


Решение:
class Solution {
countAndSay(n) {
if (n === 1) {
return "1"; // Base case
}

let ans = "";
let temp = "1";

for (let i = 2; i <= n; i++) {
let cnt = 0;
let prev = temp[0];

for (let j = 0; j < temp.length; j++) {
const char = temp[j];

if (prev === char) {
cnt++; // brute force
} else {
ans += cnt.toString(); // adding count to the end
ans += temp[j - 1];
prev = char;
cnt = 1;
}
}

ans += cnt.toString();
ans += temp[temp.length - 1];
temp = ans; // assigning ans to temp and making ans = ""
ans = ""; // so that we can iterate over temp again!
}

return temp;
}
}

Пояснение:
1
. Базовый случай:
- Если `n` равен 1, то функция возвращает "1" - это первая строка последовательности.

2. Инициализация:
- `ans` - строка, которая будет хранить результат генерации следующей строки.
- `temp` - строка, которая хранит предыдущую строку. Изначально она равна "1".

3. Цикл для генерации строк:
- Цикл `for` выполняется `n-1` раз, чтобы сгенерировать строки с 2-й по `n`-ю.
- Внутри цикла:
- `cnt` - счетчик, который хранит количество повторений текущего символа.
- `prev` - предыдущий символ, который мы обрабатываем.

4. Генерация следующей строки:
- В цикле `for` мы проходим по всем символам в `temp`:
- Сравниваем текущий символ `char` с предыдущим символом `prev`.
- Если они равны, увеличиваем счетчик `cnt`.
- Если они не равны, то добавляем в `ans` количество повторений `cnt` и предыдущий символ `prev`. Затем устанавливаем `prev` равным текущему символу и сбрасываем `cnt` в 1.
- После обработки всех символов в `temp` мы добавляем в `ans` окончательное количество повторений `cnt` и последний символ из `temp`.

5. Обновление строк:
- После генерации новой строки в `ans` мы присваиваем ее значение переменной `temp` для дальнейшего использования.
- Сбрасываем `ans` в пустую строку, чтобы можно было использовать ее для генерации следующей строки.

6. Возврат результата:
- После завершения циклов `temp` содержит `n`-ю строку последовательности, поэтому мы ее возвращаем.
👍31
Задача: 39. Combination Sum #medium
Условие:
При наличии массива различных целых чисел-кандидатов и целевого целевого числа target возвращает список всех уникальных комбинаций кандидатов, в которых выбранные числа суммируются с target. Вы можете возвращать комбинации в любом порядке.
Одно и то же число может быть выбрано из кандидатов неограниченное количество раз. Две комбинации считаются уникальными, если частота, по крайней мере, одного из выбранных чисел различна.
Тестовые примеры генерируются таким образом, чтобы количество уникальных комбинаций, которые в сумме дают целевое значение, составляло менее 150 комбинаций для заданных входных данных.

Решение:
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum = function(candidates, target) {
let sols = [];
let sum_rec = (curr_trial, curr_sum, start_idx) => {
for (let i = start_idx; i < candidates.length; i++) {
const c = candidates[i];
curr_sum += c;
curr_trial.push(c);
if (curr_sum < target) {
sum_rec(curr_trial, curr_sum, i);
} else if (curr_sum === target) {
sols.push(JSON.parse(JSON.stringify(curr_trial)));
}
curr_sum -= c;
curr_trial.pop();
}
}
sum_rec([], 0, 0);
return sols;
};

Пояснение:
Данный код реализует функцию combinationSum для поиска всех уникальных комбинаций чисел из массива candidates, которые в сумме дают целевое число target. Вот краткое объяснение кода:

1. Использование рекурсивной функции:
- Функция sum_rec - это рекурсивная функция, которая принимает текущую пробу curr_trial (текущую комбинацию чисел), текущую сумму curr_sum (сумму чисел в текущей комбинации), и индекс start_idx (индекс, с которого начинать итерацию по массиву candidates).

2. Проход по массиву candidates:
- Цикл for проходит по элементам массива candidates, начиная с индекса start_idx.
- Для каждого элемента массива c = candidates[i]:
- Увеличивается текущая сумма curr_sum на значение c.
- Элемент c добавляется в текущую пробу curr_trial.
- Если curr_sum меньше целевого значения target, вызывается рекурсивная функция sum_rec для продолжения поиска комбинаций.
- Если curr_sum равна целевому значению target, текущая комбинация добавляется в массив решений sols.

3. Удаление элемента и возврат:
- После завершения итерации по элементам, элемент c удаляется из текущей пробы curr_trial, и его значение вычитается из текущей суммы curr_sum.
- Функция возвращает массив sols, содержащий все найденные комбинации чисел, дающие целевую сумму target.

Этот код эффективно использует рекурсию для поиска всех возможных комбинаций чисел из массива candidates, которые в сумме дают целевое число target. Каждая найденная комбинация добавляется в массив решений sols.
1
Задача: 40. Combination Sum ll #medium
Условие:
Учитывая набор номеров-кандидатов (candidates) и целевой номер (target), найдите все уникальные комбинации в кандидатах, где номера-кандидаты суммируются с целевыми.
Каждое число в кандидатах является комбинацией.
может использоваться только один раз в
Примечание: Набор решений не должен содержать повторяющихся комбинаций.

Решение:
var combinationSum2 = function(candidates, target) {

const res = [];
const track = [];
let trackSum = 0;

const backtrack = (nums, start) => {
if(trackSum === target){
res.push(track.slice());
return
}
if(trackSum > target){
return
}

for(let i = start; i < nums.length; i++){
if(i > start && nums[i] === nums[i-1]) continue;
track.push(nums[i]);
trackSum += nums[i];
backtrack(nums, i+1);
track.pop();
trackSum -= nums[i];
}

}

const sorted = candidates.sort((a, b)=>a-b);

backtrack(sorted, 0)
return res

};

Пояснение:
Данный код реализует функцию combinationSum2 для поиска уникальных комбинаций чисел из массива candidates, которые в сумме дают целевое число target. В отличие от функции combinationSum, данная функция также учитывает, что каждый элемент из массива candidates может использоваться только один раз в каждой комбинации. Вот краткое объяснение кода:

1. Инициализация переменных:
- Создается пустой массив res для хранения найденных комбинаций, пустой массив track для временного хранения текущей комбинации чисел, и переменная trackSum для отслеживания суммы чисел в текущей комбинации.

2. Функция backtrack:
- Функция backtrack рекурсивно итерирует по массиву nums начиная с индекса start.
- На каждом шаге проверяется, достигнута ли целевая сумма target. Если да, то текущая комбинация добавляется в массив решений res.
- Если текущая сумма trackSum становится больше целевой суммы target, то рекурсия завершается для данной ветви.
- При итерации по массиву nums, пропускаются дубликаты элементов, чтобы избежать повторных комбинаций.
- Для каждого числа nums[i]: добавляется в текущую комбинацию track, увеличивается trackSum, вызывается рекурсия для следующего элемента, после чего число удаляется из текущей комбинации и value trackSum уменьшается.

3. Сортировка и вызов рекурсии:
- Массив candidates сортируется в порядке возрастания.
- Затем вызывается функция backtrack, начиная с отсортированного массива candidates.
- В конце возвращается массив res, содержащий все уникальные комбинации чисел, дающие целевую сумму target без повторений элементов.

Этот код использует метод возврата к трассировке (backtracking) для нахождения всех уникальных комбинаций чисел из массива candidates, дающих сочетание, равное целевой сумме target. Функция учитывает возможные повторяющиеся числа в массиве candidates, исключая их из возможных комбинаций.
👍21
Задача: 41. First Missing Positive #hard
Условие:
Задан несортированный целочисленный массив nums. Возвращает наименьшее положительное целое число, которого нет в nums.
Необходимо реализовать алгоритм, который выполняется за 0(n) времени и использует 0(1) вспомогательного пространства.

Решение:
/**
* @param {number[]} nums
* @return {number}
*/
var firstMissingPositive = function(nums) {
const n = nums.length
const n1 = n + 1
for (let i = 0; i < n; i++)
if (nums[i] <= 0 || nums[i] > n)
nums[i] = n1
for (let num of nums) {
i = Math.abs(num) - 1
if (i < n && nums[i] > 0)
nums[i] *= -1
}
for (let i = 0; i < n; i++)
if (nums[i] > 0)
return i + 1
return n1
};

Пояснение:
Данный код представляет собой решение задачи нахождения наименьшего положительного целого числа, которого нет в массиве чисел nums. Давай разберем детальное пояснение к каждой части кода:

1. Инициализация переменных:
- Создается переменная n, которая хранит длину массива nums.
- Создается переменная n1, которая равна n + 1. Она будет использоваться для обозначения отсутствующего значения.

2. Обработка отрицательных чисел и чисел, превышающих длину массива:
- В цикле for перебираются все элементы массива nums.
- Если текущий элемент nums[i] меньше или равен 0 или больше длины массива n, то он заменяется на значение n1, чтобы исключить отрицательные числа и числа, превышающие длину массива.

3. Обработка и пометка чисел:
- Далее выполняется цикл for...of по массиву nums.
- Для каждого числа num выполняются следующие действия:
- Вычисляется индекс i как модуль числа num - 1.
- Если индекс i меньше n и значение nums[i] больше 0, то значение nums[i] умножается на -1. Это помечает, что число i+1 присутствует в массиве nums.

4. Поиск недостающего числа:
- Затем выполняется третий цикл for, который проверяет массив nums на наличие первого положительного числа.
- Если такое число найдено, функция возвращает его индекс + 1.

5. Возврат значения по умолчанию:
- Если в предыдущем цикле не было найдено положительное число, функция возвращает значение n1, так как все числа от 1 до n уже присутствуют в массиве.

Данный подход позволяет эффективно определить наименьшее положительное целое число, отсутствующее в массиве nums, использовав маркировку и отслеживание присутствия чисел в массиве.
#hard
Задача: 42. Trapping Rain Water

Дано n неотрицательных целых чисел, представляющих карту высот, где ширина каждого столбца равна 1. Вычислите, сколько воды он может удержать после дождя.

Пример:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6


👨‍💻 Алгоритм:

1️⃣Найдите максимальную высоту столбца с левого конца до индекса i в массиве left_max.

2️⃣Найдите максимальную высоту столбца с правого конца до индекса i в массиве right_max.

3️⃣Итерируйте по массиву высот height и обновляйте ans: добавьте min(left_max[i], right_max[i]) - height[i] к ans.

😎 Решение:
var trap = function (height) {
if (height.length == 0) return 0;
let ans = 0;
let size = height.length;
let left_max = new Array(size).fill(0),
right_max = new Array(size).fill(0);
left_max[0] = height[0];
for (let i = 1; i < size; i++) {
left_max[i] = Math.max(height[i], left_max[i - 1]);
}
right_max[size - 1] = height[size - 1];
for (let i = size - 2; i >= 0; i--) {
right_max[i] = Math.max(height[i], right_max[i + 1]);
}
for (let i = 1; i < size - 1; i++) {
ans += Math.min(left_max[i], right_max[i]) - height[i];
}
return ans;
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 43. Multiply Strings

Даны два неотрицательных целых числа num1 и num2, представленные в виде строк. Верните произведение num1 и num2, также представленное в виде строки.

Примечание: Вы не должны использовать встроенную библиотеку BigInteger или прямо преобразовывать входные данные в целые числа.

Пример:
Input: num1 = "2", num2 = "3"
Output: "6"


👨‍💻 Алгоритм:

1️⃣Переверните оба числа. Инициализируйте массив ans с (N+M) нулями. Для каждой цифры в secondNumber:
Инициализируйте переменную carry, первоначально равную 0.
Инициализируйте массив (currentResult), который начинается с некоторого количества нулей, основываясь на позиции цифры в secondNumber.

2️⃣Для каждой цифры в firstNumber:
Умножьте цифру из secondNumber на цифру из firstNumber и добавьте предыдущий carry к умножению.
Возьмите остаток от деления умножения на 10, чтобы получить последнюю цифру.
Добавьте последнюю цифру в массив currentResult.
Разделите умножение на 10, чтобы получить новое значение для carry.

3️⃣После итерации по каждой цифре в первом числе, если carry не равен нулю, добавьте carry в currentResult.
Добавьте currentResult к ans.
Если последняя цифра в ans равна нулю, перед тем как перевернуть ans, необходимо удалить ноль из ans. В противном случае в финальном ответе будет ведущий ноль.
Переверните ans и верните его.

😎 Решение:
let addStrings = function (num1, num2) {
let ans = [];
let carry = 0;

for (let i = 0; i < num1.length || i < num2.length; ++i) {
let digit1 = i < num1.length ? num1[i] : 0;
let digit2 = i < num2.length ? num2[i] : 0;

let sum = digit1 + digit2 + carry;
carry = Math.floor(sum / 10);
ans.push(sum % 10);
}

if (carry) {
ans.push(carry);
}
return ans;
};

let multiplyOneDigit = function (firstNumber, secondNumberDigit, numZeros) {
let currentResult = [];
for (let i = 0; i < numZeros; ++i) {
currentResult.push(0);
}

let carry = 0;

for (let i = 0; i < firstNumber.length; ++i) {
let multiplication = Number(secondNumberDigit) * Number(firstNumber[i]) + carry;
carry = Math.floor(multiplication / 10);
currentResult.push(multiplication % 10);
}

if (carry) {
currentResult.push(carry);
}
return currentResult;
};

let multiply = function (num1, num2) {
if (num1 === "0" || num2 === "0") {
return "0";
}

let firstNumber = [...num1];
let secondNumber = [...num2];

firstNumber.reverse();
secondNumber.reverse();

let N = firstNumber.length + secondNumber.length;
let ans = new Array(N).fill(0);

for (let i = 0; i < secondNumber.length; ++i) {
ans = addStrings(
multiplyOneDigit(firstNumber, secondNumber[i], i),
ans,
);
}

if (ans[ans.length - 1] === 0) {
ans.pop();
}

ans.reverse();
return ans.join("");
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
#hard
Задача: 44. Wildcard Matching

Дана входная строка (s) и шаблон (p), реализуйте сопоставление с шаблоном с поддержкой символов '?' и '*' где:

'?' соответствует любому одиночному символу.
'*' соответствует любой последовательности символов (включая пустую последовательность).
Сопоставление должно покрывать всю входную строку (не частично).

Пример:
Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".


👨‍💻 Алгоритм:

1️⃣Очистите входные данные, заменив несколько звездочек подряд одной звездочкой: p = remove_duplicate_stars(p).
Инициируйте хеш-карту для мемоизации dp.
Верните вспомогательную функцию с очищенным входом: helper(s, p).

2️⃣Функция helper(s, p):
Если пара (s, p) уже известна и сохранена в dp, верните значение.
Если строки равны (p == s) или шаблон соответствует любой строке (p == '*'), добавьте dp[(s, p)] = True.
В противном случае, если p пусто или s пусто, добавьте dp[(s, p)] = False.
Если текущие символы совпадают (p[0] == s[0] или p[0] == '?'), то сравните следующие и добавьте dp[(s, p)] = helper(s[1:], p[1:]).

3️⃣Если текущий символ шаблона - звездочка (p[0] == '*'), то возможны две ситуации: звездочка не соответствует никаким символам, и звездочка соответствует одному или нескольким символам: dp[(s, p)] = helper(s, p[1:]) или helper(s[1:], p).
Если p[0] != s[0], тогда добавьте dp[(s, p)] = False.
Когда значение вычислено, верните его: dp[(s, p)].

😎 Решение:
var isMatch = function (s, p) {
var dp = {};
var remove_duplicate_stars = function (p) {
var new_string = "";
for (var c of p) {
if (new_string.length == 0 || c != "*") new_string += c;
else if (new_string[new_string.length - 1] != "*") new_string += c;
}
return new_string;
};
var helper = function (si, pi) {
var key = si + "," + pi;
if (key in dp) return dp[key];
if (pi == p.length) dp[key] = si == s.length;
else if (si == s.length) dp[key] = pi + 1 == p.length && p[pi] == "*";
else if (p[pi] == s[si] || p[pi] == "?")
dp[key] = helper(si + 1, pi + 1);
else if (p[pi] == "*")
dp[key] = helper(si, pi + 1) || helper(si + 1, pi);
else dp[key] = false;
return dp[key];
};
p = remove_duplicate_stars(p);
return helper(0, 0);
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 45. Jump Game II

Вам дан массив целых чисел nums с индексацией с нуля и длиной n. Изначально вы находитесь в позиции nums[0].

Каждый элемент nums[i] представляет максимальную длину прыжка вперед с индекса i. Другими словами, если вы находитесь в nums[i], вы можете прыгнуть на любой nums[i + j], где:

0 <= j <= nums[i] и
i + j < n
Верните минимальное количество прыжков, чтобы достичь nums[n - 1]. Тестовые случаи сгенерированы таким образом, что вы можете достичь nums[n - 1].

Пример:
Input: nums = [2,3,0,1,4]
Output: 2


👨‍💻 Алгоритм:

1️⃣Инициализируйте curEnd = 0, curFar = 0 и количество прыжков как answer = 0.

2️⃣Итерируйтесь по массиву nums. Для каждого индекса i наибольший индекс, до которого мы можем добраться из i, равен i + nums[i]. Обновите curFar = max(curFar, i + nums[i]).

3️⃣Если i = curEnd, это означает, что текущий прыжок завершен, и следует перейти к следующему прыжку. Увеличьте answer и установите curEnd = curFar как наибольшее расстояние, которое мы можем преодолеть следующим прыжком. Повторите с шага 2.

😎 Решение:
var jump = function (nums) {
let answer = 0,
n = nums.length;
let curEnd = 0,
curFar = 0;
for (let i = 0; i < n - 1; ++i) {
curFar = Math.max(curFar, i + nums[i]);
if (i === curEnd) {
++answer;
curEnd = curFar;
}
}
return answer;
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 46. Permutations

Дан массив nums, состоящий из различных целых чисел, верните все возможные перестановки. Вы можете вернуть ответ в любом порядке.

Пример:
Input: nums = [0,1]
Output: [[0,1],[1,0]]


👨‍💻 Алгоритм:

1️⃣Если длина curr равна длине nums, добавьте копию curr в ans и вернитесь.

2️⃣Итерируйтесь по nums. Для каждого num, если num не в curr, выполните следующее:
Добавьте num в curr и вызовите backtrack(curr), затем удалите num из curr.

3️⃣Вызовите backtrack с изначально пустым curr.
Верните ans.

😎 Решение:
var permute = function (nums) {
var ans = [];
var backtrack = function (curr) {
if (curr.length === nums.length) {
ans.push([...curr]);
return;
}
for (var num of nums) {
if (!curr.includes(num)) {
curr.push(num);
backtrack(curr);
curr.pop();
}
}
};
backtrack([]);
return ans;
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
#medium
Задача: 47. Permutations II

Дана коллекция чисел, nums, которая может содержать дубликаты. Верните все возможные уникальные перестановки в любом порядке.

Пример:
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]


👨‍💻 Алгоритм:

1️⃣Для реализации алгоритма сначала определим функцию под названием backtrack(comb, counter), которая генерирует все перестановки, начиная с текущей комбинации (comb) и оставшихся чисел (counter).

2️⃣После реализации функции достаточно вызвать её с начальной пустой комбинацией и хеш-таблицей, построенной из входного массива, чтобы решить задачу.

3️⃣Это позволяет эффективно и систематически исследовать все возможные уникальные перестановки, учитывая дубликаты в исходном наборе чисел.

😎 Решение:
var permuteUnique = function (nums) {
let results = [];
let counter = {};
for (let num of nums) {
if (!(num in counter)) counter[num] = 0;
counter[num]++;
}
function backtrack(comb, N) {
if (comb.length === N) {
results.push([...comb]);
return;
}
for (let num in counter) {
if (counter[num] === 0) continue;
comb.push(parseInt(num));
counter[num]--;
backtrack(comb, N);
counter[num]++;
comb.pop();
}
}
backtrack([], nums.length);
return results;
};


🪙 1429 вопроса вопроса на Frontend разработчика

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
#medium
Задача: 48. Rotate Image

Вам дана квадратная матрица размером n x n, представляющая изображение. Поверните изображение на 90 градусов по часовой стрелке.

Вы должны повернуть изображение на месте, что означает необходимость изменения исходной матрицы 2D напрямую. НЕ создавайте другую матрицу 2D для выполнения поворота.

Пример:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]


👨‍💻 Алгоритм:

1️⃣Самым элегантным решением для поворота матрицы является первоначальное транспонирование матрицы вокруг главной диагонали.

2️⃣После транспонирования следует выполнить отражение матрицы слева направо.

3️⃣Эти операции в линейной алгебре называются транспонированием и отражением.

😎 Решение:
var rotate = function (matrix) {
const n = matrix.length;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
}
}
for (let i = 0; i < n; i++) {
for (let j = 0; j < n / 2; j++) {
[matrix[i][j], matrix[i][n - 1 - j]] = [
matrix[i][n - 1 - j],
matrix[i][j],
];
}
}
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
#medium
Задача: 49. Group Anagrams

Дан массив строк strs. Сгруппируйте анаграммы вместе. Вы можете вернуть ответ в любом порядке.

Анаграмма — это слово или фраза, сформированная путем перестановки букв другого слова или фразы, обычно используя все исходные буквы ровно один раз.

Пример:
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]


👨‍💻 Алгоритм:

1️⃣Поддерживайте карту ans: {String -> List}, где каждый ключ K — это отсортированная строка, а каждое значение — это список строк из исходного ввода, которые при сортировке равны K.

2️⃣В Java ключ будет храниться как строка, например, code. В Python ключ будет храниться как хешируемый кортеж, например, ('c', 'o', 'd', 'e').

3️⃣Используя эту структуру данных, можно легко сгруппировать анаграммы, сопоставляя строки после сортировки их символов с ключами в карте.

😎 Решение:
var groupAnagrams = function (strs) {
let map = new Map();
for (let str of strs) {
let chars = Array.from(str);
chars.sort();
let key = chars.join("");
if (!map.has(key)) map.set(key, []);
map.get(key).push(str);
}
return Array.from(map.values());
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
#medium
Задача: 50. Pow(x, n)

Реализуйте функцию pow(x, n), которая вычисляет x, возведенное в степень n (то есть x^n).

Пример:
Input: x = 2.00000, n = 10
Output: 1024.00000


👨‍💻 Алгоритм:

1️⃣Создайте метод binaryExp, который принимает параметры x и n.
Если n равно 0, мы возвращаем 1.
Если n отрицательное, вычисляем результат, как если бы n было положительным, и возвращаем обратное значение, то есть 1 / binaryExp(x, -n). При этом -n может выйти за пределы диапазона целых чисел, поэтому n должно быть 64-битной целочисленной переменной.

2️⃣В противном случае, используя бинарное возведение в степень, мы уменьшаем показатель степени n вдвое и рекурсивно вычисляем и возвращаем результат после решения новой подзадачи, как обсуждалось ранее.

3️⃣Вызовите метод binaryExp(x, n) и верните результат.

😎 Решение:
function binaryExp(x, n) {
if (n === 0) {
return 1;
}
if (n < 0) {
return 1 / binaryExp(x, -1 * n);
}
if (n % 2 === 1) {
return x * binaryExp(x * x, (n - 1) / 2);
} else {
return binaryExp(x * x, n / 2);
}
}

var myPow = function (x, n) {
return binaryExp(x, n);
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
#medium
Задача: 51. N-Queens

Задача о n-ферзях заключается в размещении n ферзей на шахматной доске n на n таким образом, чтобы ни один из ферзей не атаковал друг друга.

Для заданного целого числа n верните все различные решения этой задачи. Ответ можно предоставить в любом порядке.

Каждое решение содержит уникальную конфигурацию доски с размещением ферзей, где символы 'Q' и '.' обозначают ферзя и пустое пространство соответственно.

Пример:
Input: n = 4
Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above


👨‍💻 Алгоритм:

1️⃣Создание рекурсивной функции backtrack, которая использует несколько аргументов для сохранения состояния доски. Первый параметр — это строка, на которой мы собираемся разместить следующую ферзя. Также будут использоваться три набора, которые отслеживают, в каких столбцах, диагоналях и антидиагоналях уже были размещены ферзи. Кроме того, текущее состояние доски сохраняется для включения в ответ, если найдено действительное решение. Если текущая рассматриваемая строка равна n, значит, найдено решение. Текущее состояние доски добавляется в список решений и функция завершается. Для получения корректного формата вывода используется вспомогательная функция.

2️⃣Итерация по столбцам текущей строки. В каждом столбце пытаемся разместить ферзя на клетке (row, col). Вычисляется диагональ и антидиагональ, к которым принадлежит клетка. Если в столбце, диагонали или антидиагонали ещё не было размещено ферзя, то в текущем ряду в этом столбце можно разместить ферзя.

3️⃣Если размещение ферзя возможно, ферзь добавляется на доску, и обновляются три набора данных (cols, diagonals и antiDiagonals). Затем функция вызывается снова, но с row + 1. Вызов функции в шаге 3 исследует все допустимые состояния доски с учетом размещенного ферзя на шаге 2. После завершения исследования этого пути выполняется откат: ферзь удаляется из клетки, что включает удаление значений, добавленных в наборы, и удаление "Q" с доски.

😎 Решение:
var solveNQueens = function (n) {
const solutions = [];
const emptyBoard = Array.from({ length: n }, () => Array(n).fill("."));
const createBoard = (state) => {
const board = [];
for (let row = 0; row < n; row++) {
board.push(state[row].join(""));
}
return board;
};
const backtrack = (row, diagonals, antiDiagonals, cols, state) => {
if (row === n) {
solutions.push(createBoard(state));
return;
}
for (let col = 0; col < n; col++) {
const currDiagonal = row - col;
const currAntiDiagonal = row + col;
if (
cols.has(col) ||
diagonals.has(currDiagonal) ||
antiDiagonals.has(currAntiDiagonal)
) {
continue;
}
cols.add(col);
diagonals.add(currDiagonal);
antiDiagonals.add(currAntiDiagonal);
state[row][col] = "Q";
backtrack(row + 1, diagonals, antiDiagonals, cols, state);
cols.delete(col);
diagonals.delete(currDiagonal);
antiDiagonals.delete(currAntiDiagonal);
state[row][col] = ".";
}
};
backtrack(0, new Set(), new Set(), new Set(), emptyBoard);
return solutions;
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
#hard
Задача: 52. N-Queens II

Задача "n-ферзей" заключается в размещении n ферзей на шахматной доске размером n x n таким образом, чтобы ни одна пара ферзей не атаковала друг друга.

Дано целое число n, верните количество различных решений задачи "n-ферзей".

Пример:
Input: n = 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown.


👨‍💻 Алгоритм:

1️⃣Создание рекурсивной функции backtrack, принимающей четыре аргумента для поддержания состояния шахматной доски. Первый параметр — это строка, в которой следует разместить ферзя, а остальные три параметра — это наборы, отслеживающие, в каких столбцах, диагоналях и антидиагоналях уже размещены ферзи. Если текущая рассматриваемая строка больше n, то найдено решение. Возвращается 1.

2️⃣Введение локальной переменной solutions = 0, представляющей все возможные решения, которые могут быть получены из текущего состояния доски. Итерация по столбцам текущей строки, попытка разместить ферзя в каждом квадрате (row, col), учитывая текущую строку через аргументы функции.

3️⃣Расчёт принадлежности квадрата к диагонали и антидиагонали. Если в столбце, диагонали или антидиагонали ещё не размещен ферзь, то ферзь можно разместить в этом столбце текущей строки. Если ферзя разместить нельзя, переходим к следующему столбцу. Если ферзь успешно размещён, обновляем три набора (cols, diagonals, и antiDiagonals) и вызываем функцию снова, но с row + 1. После завершения исследования этого пути происходит откат, путём удаления ферзя из квадрата — это означает удаление значений, добавленных в наши наборы.

😎 Решение:
var totalNQueens = function (n) {
function backtrack(row, diagonals, anti_diagonals, cols) {
if (row == n) {
return 1;
}
let solutions = 0;
for (let col = 0; col < n; col++) {
let curr_diagonal = row - col;
let curr_anti_diagonal = row + col;
if (
cols.has(col) ||
diagonals.has(curr_diagonal) ||
anti_diagonals.has(curr_anti_diagonal)
) {
continue;
}
cols.add(col);
diagonals.add(curr_diagonal);
anti_diagonals.add(curr_anti_diagonal);
solutions += backtrack(row + 1, diagonals, anti_diagonals, cols);
cols.delete(col);
diagonals.delete(curr_diagonal);
anti_diagonals.delete(curr_anti_diagonal);
}
return solutions;
}
return backtrack(0, new Set(), new Set(), new Set());
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
#hard
Задача: 53. Maximum Subarray

Дан массив целых чисел nums, найдите подмассив с наибольшей суммой и верните его сумму.

Пример:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum 6.


👨‍💻 Алгоритм:

1️⃣Инициализируйте переменную maxSubarray значением минус бесконечность, чтобы отслеживать лучший подмассив. Необходимо использовать отрицательную бесконечность, а не 0, поскольку в массиве могут быть только отрицательные числа.

2️⃣Используйте цикл for, который рассматривает каждый индекс массива в качестве начальной точки. Для каждой начальной точки создайте переменную currentSubarray с начальным значением 0. Затем пройдитесь по массиву, начиная с указанного индекса, прибавляя каждый элемент к currentSubarray. При каждом добавлении элемента получается возможный подмассив, поэтому непрерывно обновляйте maxSubarray, чтобы он содержал максимум из currentSubarray и самого себя.

3️⃣Верните значение maxSubarray.

😎 Решение:
var maxSubArray = function (nums) {
let max_subarray = Number.NEGATIVE_INFINITY;
for (let i = 0; i < nums.length; i++) {
let current_subarray = 0;
for (let j = i; j < nums.length; j++) {
current_subarray += nums[j];
max_subarray = Math.max(max_subarray, current_subarray);
}
}
return max_subarray;
};


🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥51