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
Channel created
Задача: №16. 3Sum Closest #medium

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


Решение:
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function (nums, target) {
nums.sort((a, b) => a - b);
let ans = 1 << 30;
const n = nums.length;
for (let i = 0; i < n; ++i) {
let j = i + 1;
let k = n - 1;
while (j < k) {
const t = nums[i] + nums[j] + nums[k];
if (t === target) {
return t;
}
if (Math.abs(t - target) < Math.abs(ans - target)) {
ans = t;
}
if (t > target) {
--k;
} else {
++j;
}
}
}
return ans;
};


Пояснение:
Сначала мы сортируем массив, а затем просматриваем его. Для каждого элемента nums[i], мы используем указатели j и k
указать на n+1
и n - 1 соответственно, вычислите сумму трех чисел. Если сумма трех чисел равна целевому значению, мы напрямую возвращаем цель. В противном случае мы обновляем ответ в зависимости от отличия от целевого.
Если сумма трех чисел больше целевого, мы перемещаем k
на одну позицию влево, иначе мы перемещаем j одно место вправо.
Временная сложность равна O(n^2), а пространственная сложность равна O(log n).
Вот, n длина массива.
👍5🤯3🔥2
Задача: №17. Letter Combinations of a Phone Number #medium

Условие:
Учитывая строку, содержащую цифры от 2 до 9 включительно, верните все возможные комбинации букв, которые может представлять число. Верните ответ в любом порядке. Соответствие цифр буквам (как на кнопках телефона) приведено ниже. Обратите внимание, что 1 не соответствует никаким буквам.


Решение:
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function (digits) {
if (digits.length == 0) {
return [];
}
const ans = [''];
const d = ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'];
for (const i of digits) {
const s = d[parseInt(i) - 2];
const t = [];
for (const a of ans) {
for (const b of s) {
t.push(a + b);
}
}
ans.splice(0, ans.length, ...t);
}
return ans;
};


Пояснение:
Во-первых, мы используем массив или хеш-таблицу для хранения букв, соответствующих каждой цифре. Затем мы проходим каждую цифру, объединяем соответствующие ей буквы с предыдущими результатами, чтобы получить новые результаты. Временная сложность O(4^n), а пространственная сложность равна O(4^n). Вот, n длина входных цифр.
👍1
Задача: №18. 4Sum #medium

Условие:
Учитывая массив nums из n целых чисел, верните массив всех уникальных четверок [nums[a], nums[b], nums[c], nums[d]] таких, что:
0 <= a, b, c, d < n
a, b, c и d различны.
nums[a] + nums[b] + nums[c] + nums[d] == цель
Вы можете вернуть ответ в любом порядке.



Решение:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
var fourSum = function (nums, target) {
const n = nums.length;
const ans = [];
if (n < 4) {
return ans;
}
nums.sort((a, b) => a - b);
for (let i = 0; i < n - 3; ++i) {
if (i > 0 && nums[i] === nums[i - 1]) {
continue;
}
for (let j = i + 1; j < n - 2; ++j) {
if (j > i + 1 && nums[j] === nums[j - 1]) {
continue;
}
let [k, l] = [j + 1, n - 1];
while (k < l) {
const x = nums[i] + nums[j] + nums[k] + nums[l];
if (x < target) {
++k;
} else if (x > target) {
--l;
} else {
ans.push([nums[i], nums[j], nums[k++], nums[l--]]);
while (k < l && nums[k] === nums[k - 1]) {
++k;
}
while (k < l && nums[l] === nums[l + 1]) {
--l;
}
}
}
}
}
return ans;
};


Пояснение:
Учитывая массив nums из n целых чисел, верните массив всех уникальных четверок [nums [a], nums [b], nums [c], nums [d]], таких, что:
• 0 = a, b, c, d < n
• a, b, c и d различны.
• цифры[a] + цифры[b] + цифры[c] + цифры[d] == цель
Вы можете вернуть ответ в любом порядке.
2😁1🤔1
Задача: №19. Remove Nth Node From End of List #medium

Условие:
Учитывая заголовок связанного списка, удалите n-й узел из конца списка и верните его заголовок.


Решение:

/
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function (head, n) {
const dummy = new ListNode(0, head);
let fast = dummy,
slow = dummy;
while (n--) {
fast = fast.next;
}
while (fast.next) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummy.next;
};


Пояснение:
Мы определяем два указателя, быстрый и медленный,
оба из которых изначально указывают на фиктивный головной
узел связанного списка.
Затем сначала быстрый указатель перемещается вперед на n
шагов, затем быстрый и медленный указатели
перемещаются вперед вместе, пока быстрый
указатель не достигнет конца связанного списка. На
данный момент узел, на который указывает
slow. next, является предшественником n-го
узла с конца, и мы можем удалить его.
Временная сложность равна O(n), где n -
длина связанного списка. Сложность пространства
равна O(1).
1
Задача: №20. Valid Parentheses #easy

Условие:
Учитывая строку s, содержащую только символы '(', ')', '{', '}', '[' и ']', определите, является ли входная строка допустимой. Входная строка действительна, если: Открытые скобки должны закрываться скобками того же типа.
Открытые скобки должны закрываться в правильном порядке.
Каждой закрывающей скобке соответствует открытая скобка того же типа.


Решение:

/**
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
let stk = [];
for (const c of s) {
if (c == '(' c == '{' c == '[') {
stk.push(c);
} else if (stk.length == 0 !match(stk[stk.length - 1], c)) {
return false;
} else {
stk.pop();
}
}
return stk.length == 0;
};

function match(l, r) {
return (l == '(' && r == ')') (l == '[' && r == ']') || (l == '{' && r == '}');
}


Пояснение:
Пройдите по строке скобок s. При
обнаружении левой скобки вставьте
текущую левую скобку в стек; при
обнаружении правой скобки извлеките верхний
элемент из стека (если стек пуст,
сразу верните значение false ) и оцените
, соответствует ли оно. Если оно не совпадает, напрямую
верните значение false.
В качестве альтернативы, при обнаружении левой
скобки вы можете поместить соответствующую
правую скобку в стек; при
обнаружении правой скобки извлеките верхний
элемент стека (если стек пуст,
непосредственно верните значение false ) и оцените, равны ли
они. Если они не совпадают,
напрямую верните значение false.

Разница между этими двумя
методами заключается только во времени
преобразования скобок: один - при вставке в стек
, а другой - при
извлечении из стека.

В конце обхода, если стек
пуст, это означает, что строка в скобках верна,
возвращает значение true; в противном случае возвращает значение false.
Временная сложность равна O(n), а
пространственная сложность равна O(n). Здесь n - это
длина строки скобок s.
👍2
Задача: №21. Merge Two Sorted Lists #easy

Условие:
Вам даны заголовки двух отсортированных связанных списков list1 и list2. Объедините два списка в один отсортированный список. Список должен быть составлен путем сращивания узлов первых двух списков. Возвращает заголовок объединенного связанного списка.


Решение:

/
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function (list1, list2) {
if (!list1 !list2) {
return list1 list2;
}
if (list1.val <= list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
} else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
};


Пояснение:
Сначала мы оцениваем, являются ли связанные списки l1
и l2 пустыми. Если один из них пуст,
мы возвращаем другой связанный список. В противном случае
мы сравниваем головные узлы l1 и l2:
• Если значение головного узла из ₁
меньше или равно значению
головного узла из l2, мы рекурсивно вызываем
функцию mergeTwoLists (l1. далее, l2)
и соединяем головной узел из ₁ с
возвращаемым головным узлом связанного списка и
возвращаем головной узел из l1.
• В противном случае мы рекурсивно вызываем
функцию mergeTwoLists (l1, l2. next)
и соединяем головной узел l2 с
возвращаемым головным узлом связанного списка и
возвращаем головной узел l2.
Временная сложность равна O(m + n), а
пространственная - O(m + n). Здесь m
и n - длины двух связанных списков
соответственно.
🔥3🤮1
Задача: №22. Generate Parentheses #medium

Условие:
Учитывая n пар круглых скобок, напишите функцию, которая генерирует все комбинации правильных круглых скобок.
Решение:
/**
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = function (n) {
function dfs(l, r, t) {
if (l > n r > n l < r) {
return;
}
if (l == n && r == n) {
ans.push(t);
return;
}
dfs(l + 1, r, t + '(');
dfs(l, r + 1, t + ')');
}
let ans = [];
dfs(0, 0, '');
return ans;
};


Пояснение:
Диапазон значений n в задаче равен [1, 8], поэтому
мы можем напрямую решить эту проблему с помощью
"поиска методом перебора + обрезки".
Мы создаем функцию dfs(l,r,t), где I
и представляют количество левых и
правых скобок соответственно, а t
представляет текущую последовательность скобок.
Тогда мы можем получить следующую рекурсивную
структуру:
• Если > n или r > n или l<r, то
текущая комбинация скобок t
недопустима, возвращайте напрямую;
• Если l = n и r = n, то текущая
комбинация скобок t допустима, добавьте ее в
массив ответов ans и возвращайте
напрямую;
• Мы можем добавить левую скобку
и рекурсивно выполнить dfs (1 + 1,
r, t + "(")). ;
• Мы также можем добавить правую
скобку и рекурсивно выполнить
dfs(1, r +1, t + ")").
Временная сложность равна O(2×2 × n), а
пространственная - O(n).
🔥2🤮2
Channel name was changed to «JavaScript | LeetCode»
Задача: №23. Merge k Sorted Lists #hard

Условие:
Вам дан массив из k списков связанных списков, каждый связанный список отсортирован в порядке возрастания. Объедините все связанные списки в один отсортированный связанный список и верните его.


Решение:

/
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function (lists) {
const pq = new MinPriorityQueue({ priority: node => node.val });
for (const head of lists) {
if (head) {
pq.enqueue(head);
}
}
const dummy = new ListNode();
let cur = dummy;
while (!pq.isEmpty()) {
const node = pq.dequeue().element;
cur.next = node;
cur = cur.next;
if (node.next) {
pq.enqueue(node.next);
}
}
return dummy.next;
};


Пояснение:
Диапазон значений n в задаче равен [1, 8], поэтому
мы можем напрямую решить эту проблему с помощью
"поиска методом перебора + обрезки".
Мы создаем функцию dfs(l,r,t), где I
и представляют количество левых и
правых скобок соответственно, а t
представляет текущую последовательность скобок.
Тогда мы можем получить следующую рекурсивную
структуру:
• Если > n или r > n или l<r, то
текущая комбинация скобок t
недопустима, возвращайте напрямую;
• Если l = n и r = n, то текущая
комбинация скобок t допустима, добавьте ее в
массив ответов ans и возвращайте
напрямую;
• Мы можем добавить левую скобку
и рекурсивно выполнить dfs (1 + 1,
r, t + "(")). ;
• Мы также можем добавить правую
скобку и рекурсивно выполнить
dfs(1, r +1, t + ")").
Временная сложность равна O(2×2 × n), а
пространственная - O(n).
👍1
Задача: №24. Swap Nodes in Pairs #medium

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


Решение:

/
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/
* @param {ListNode} head
* @return {ListNode}
*/
var swapPairs = function (head) {
if (!head || !head.next) {
return head;
}
const t = swapPairs(head.next.next);
const p = head.next;
p.next = head;
head.next = t;
return p;
};


Пояснение:
Мы можем реализовать замену двух узлов в связанном списке с помощью рекурсии.
Условием завершения рекурсии является отсутствие узлов в связанном списке или наличие только одного узла в связанном списке. В данный момент замена не может быть выполнена, поэтому мы возвращаем этот узел напрямую.
В противном случае мы рекурсивно меняем заголовок связанного списка местами. следующий. далее, и пусть замененный головной узел будет t. Затем мы позволяем p быть следующим узлом head, и пусть p указывает на head, а head указывает на t, и, наконец, возвращаем p.
Временная сложность равна O(n), а пространственная - O(n). Здесь n - длина связанного списка.
👍1
Задача: №26.Remove Duplicates from Sorted Array #easy

Условие:
При наличии целочисленного массива nums, отсортированного в порядке неубывания, удалите дубликаты на месте, чтобы каждый уникальный элемент отображался только один раз. Относительный порядок элементов должен оставаться неизменным. Затем верните количество уникальных элементов в nums. Предположим, что количество уникальных элементов nums равно k, для того, чтобы их приняли, вам нужно выполнить следующие действия: Измените массив nums таким образом, чтобы первые k элементов nums содержали уникальные элементы в том порядке, в котором они изначально присутствовали в nums. Остальные элементы nums не важны, так же как и размер nums.
Верните k.


Решение:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function (nums) {
let k = 0;
for (const x of nums) {
if (k === 0 || x !== nums[k - 1]) {
nums[k++] = x;
}
}
return k;
};


Пояснение:
Мы используем переменную k для записи текущей длины обрабатываемого массива. Изначально
значение k = 0 представляет пустой массив.
Затем мы проходим по массиву слева направо. Для каждого элемента x, с которым мы сталкиваемся, если
k = 0 или x != nums|k - 1], мы помещаем x в позицию nums|k|, а затем увеличиваем k на 1. В противном случае значение x совпадает с значением nums|k - 1], поэтому мы пропускаем этот элемент.
Продолжайте обход, пока не будет пройден весь массив.
Таким образом, когда обход завершается, первые k элементов в числах являются ответом, который мы ищем, а k - это длина ответа.
Временная сложность равна O(n), а пространственная сложность равна O(1). Здесь n - это длина массива.
Дополнение:
Исходная задача требует, чтобы одно и то же число появлялось не более одного раза. Мы можем расширить ее, чтобы сохранить не более k одинаковых чисел.
Поскольку одно и то же число может сохраняться не более k раз, мы можем напрямую сохранить первые k элементов исходного массива;
Для следующих чисел предпосылка их сохранения такова: текущее число x сравнивается с последним k-м элементом из ранее сохраненных чисел. Если они отличаются друг от друга, сохраните их, в противном случае пропустите.
👍4🤯2
Задача: №27.Remove Element #easy

Условие:
Учитывая целочисленный массив nums и целое значение val, удалите все вхождения val в nums на месте. Порядок элементов может быть изменен. Затем верните количество элементов в nums, которые не равны val. Учтите, что количество элементов в nums, которые не равны val, равно k, чтобы их приняли, вам нужно выполнить следующие действия: Измените массив nums таким образом, чтобы первые k элементов в nums содержали элементы, которые не равны val. Остальные элементы nums не важны, так же как и размер nums. Верните k.

Решение:
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function (nums, val) {
let k = 0;
for (const x of nums) {
if (x !== val) {
nums[k++] = x;
}
}
return k;
};


Пояснение:
Мы используем переменную k для записи количества элементов, которые не равны val.
Проходим по массиву nums, если текущий элемент x не равен val, затем присваиваем x значение nums|k) и увеличиваем k на 1.
Наконец, возвращаем k.
Временная сложность равна O(n), а пространственная - O(1), где n - длина массива nums
.
2
Задача: 28. Find the Index of the First Occurrence in a String #easy

Условие:
Учитывая две строки, игла и стог сена, верните индекс первого вхождения иглы в стоге сена или -1, если игла не является частью стога сена.



Решение:
function strStr(haystack, needle) {  if (needle === "") {
return 0; }
for (let i = 0; i < haystack.length; i++) {
let haySlice = haystack.slice(i, i + needle.length); if (haySlice === needle) {
return i; }
} return -1;
}

Пояснение:
1. Функция strStr принимает две строки: haystack - строку, в которой нужно найти подстроку, и needle - подстроку, которую нужно найти.
2. Сначала функция проверяет, если needle пустая строка, то возвращает 0, так как подстрока пустая и она есть в любой строке на любой позиции.
3. Далее функция использует цикл for, чтобы пройтись по каждому символу в строке haystack.
4. На каждой итерации цикла, функция создает подстроку haySlice, начиная с текущей позиции i и длиной подстроки needle.
5. Затем происходит сравнение подстроки haySlice с needle. Если они равны, функция возвращает индекс i, то есть позицию, с которой начинается найденная подстрока needle в строке haystack.
6. Если подстрока haySlice не равна needle, цикл продолжает итерироваться через строку haystack.
7. Если не удалось найти подстроку needle в строке haystack, функция возвращает -1, указывая на отсутствие искомой подстроки в строке.
4