введение
Бутылка снова здесь, она здесь с фронтенд-алгоритмом👏👏👏
Собеседования на крупных фабриках становятся все сложнее, а требования к алгоритмам — все больше и больше. Когда интервьюер задает алгоритмический вопрос, точный ответ может значительно повысить благосклонность интервьюера. Эта серия посвящена созданию набора алгоритмов. для передней части.
Прошлый замечательный цикл статей:
- Расширенный алгоритм внешнего интерфейса 5: всесторонне интерпретировать структуру стека, используемую во внешнем интерфейсе (+ вопросы по чистке кода)
- Усовершенствованный алгоритм внешнего интерфейса 4: Связанный список такой простой (+ вопросы по кисту leetcode)
- Дополнительный алгоритм переднего уровня 3: Узнайте алгоритм LRU от стратегии устранения кэша браузера и живой
- Передовой расширенный алгоритм 2: просмотр массива JavaScript из исходного кода Chrome V8 (с вопросами интервью Tencent)
- Интерфейсный расширенный алгоритм 1: как проанализировать и подсчитать эффективность выполнения и потребление ресурсов алгоритма?
Резюме трех групповых вопросов по обмену кистями:
-
10 вопросов и 10 ответов, которые быстро приведут вас к интерфейсному алгоритму
-
Резюме первой недели лагеря передовых алгоритмов переднего плана бутылки
Название (название будет выпущено только в «Лагере обучения продвинутому алгоритму», где каждое утро в 9:00):
Массив статей:
- Графический leetcode88: объединить два отсортированных массива
- bytes & leetcode1: сумма двух чисел
- Tencent: выравнивание массивов, дедупликация, сортировка
- leetcode349: Имея два массива, напишите функцию для вычисления их пересечения
- leetcode146: Проектирование и реализация механизма кэширования LRU (наименее недавно использовавшегося)
- Вопрос по алгоритму Али: написать функцию для вычисления пересечения нескольких массивов
Связанный список:
- leetcode21: объединить два упорядоченных связанных списка
- Вам нравится & leetcode141: Определить, есть ли цикл в односвязном списке
- Графический leetcode206: обращение связанного списка
- leetcode876: Найти средний узел связанного списка
- leetcode19: удалить n-й узел снизу связанного списка
- Графический байт и LeetCode160: Написать программу, найдите начальный узел двух таблиц одной ссылки
Строковые статьи:
- Байты диаграммы и leetcode151: поменять местами слова в строке
- Графический leetcode14: самый длинный общий префикс
- Baidu: реализовать функцию для определения того, является ли ввод строкой-палиндромом.
- bytes & Leetcode3: самая длинная подстрока без повторяющихся символов
Стек статей:
- bytes&leetcode155: минимальный стек (стек, содержащий функцию getMin)
- Графика Tencent&leetcode20: Допустимые скобки
- leetcode1047: удалить все соседние дубликаты в строке
Этот раздел представляет собой подведение итогов и обзор четвертой недели, давайте приступим к делу! 👇👇👇
1. Baidu: реализовать функцию для определения того, является ли ввод строкой-палиндромом.
1. Решение 1. Используйте API
function isPlalindrome(input) {
if (typeof input !== 'string') return false;
return input.split('').reverse().join('') === input;
}
2. Решение 2. Не используйте API
function isPlalindrome(input) {
if (typeof input !== 'string') return false;
let i = 0, j = input.length - 1
while(i < j) {
if(input.charAt(i) !== input.charAt(j)) return false
i ++
j --
}
return true
}
3. Больше решений
смотрите подробностиBaidu: реализовать функцию для определения того, является ли ввод строкой-палиндромом.
2. Byte & Leetcode3: самая длинная подстрока без повторяющихся символов.
1. Темы
Дана строка, пожалуйста, найдите ту, которая не содержит повторяющихся символовсамая длинная подстрока длина.
Пример 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
Пример 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
Пример 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
2. Решение
Решение 1. Сохраните массив
Идеи решения проблемы:Используйте массив для поддержки скользящего окна
Пройдите по строке, чтобы определить, находится ли символ в массиве скользящего окна.
- Отсутствие
push
в массив - Затем удалите тот же символ и символ перед тем же символом в массиве скользящего окна, а затем удалите текущий символ
push
в массив - потом
max
Обновление длины текущей самой длинной подстроки
После обхода возвращайтесьmax
Только что
Рисунок для понимания:
Код:
var lengthOfLongestSubstring = function(s) {
let arr = [], max = 0
for(let i = 0; i < s.length; i++) {
let index = arr.indexOf(s[i])
if(index !== -1) {
arr.splice(0, index+1);
}
arr.push(s.charAt(i))
max = Math.max(arr.length, max)
}
return max
};
Временная сложность: O(n2), вarr.indexOf()
Временная сложность O(n) ,arr.splice(0, index+1)
Временная сложность также O (n)
Космическая сложность: O (n)
Решение 2. Сохраняйте подписки
Идеи решения проблемы:Используйте индексы для поддержки скользящих окон
Код:
var lengthOfLongestSubstring = function(s) {
let index = 0, max = 0
for(let i = 0, j = 0; j < s.length; j++) {
index = s.substring(i, j).indexOf(s[j])
if(index !== -1) {
i = i + index + 1
}
max = Math.max(max, j - i + 1)
}
return max
};
Временная сложность: O(n2)
Космическая сложность: O(n)
Решение 3. Оптимизированная карта
Идеи решения проблемы:
использоватьmap
для хранения символов, которые были пройдены до сих пор,key
это персонаж,value
индекс
использоватьi
чтобы отметить начало подстроки без повторения подстрок,j
Индекс текущий обход символ
Пройдитесь по строке, чтобы определить, находится ли текущий символ уже вmap
существует в подстроке, если она существует, обновить подстроку без дубликатов и начать индексациюi
это следующая позиция того же символа, на этот раз отi
прибытьj
для последней неповторяющейся подстроки обновитеmax
, поместите текущий символ и индекс вmap
середина
Наконец, вернитесьmax
Только что
Код:
var lengthOfLongestSubstring = function(s) {
let map = new Map(), max = 0
for(let i = 0, j = 0; j < s.length; j++) {
if(map.has(s[j])) {
i = Math.max(map.get(s[j]) + 1, i)
}
max = Math.max(max, j - i + 1)
map.set(s[j], j)
}
return max
};
Временная сложность: O(n)
Космическая сложность: O(n)
3. Больше решений
смотрите подробностиbytes & Leetcode3: самая длинная подстрока без повторяющихся символов
3. Статья: Комплексная интерпретация структуры стека
1. Стек структуры данных
Стек — это упорядоченная коллекция, работающая по принципу «последним пришел — первым обслужен» (LIFO/Last In First Out) и имеет следующую структуру:
Код
function Stack() {
let items = []
this.push = function(e) {
items.push(e)
}
this.pop = function() {
return items.pop()
}
this.isEmpty = function() {
return items.length === 0
}
this.size = function() {
return items.length
}
this.clear = function() {
items = []
}
}
Поиск: поиск с вершины стека, временная сложность O(n)
Вставка или удаление: временная сложность нажатия и извлечения стека составляет O (1)
2. Интервью: стек вызовов
Стек вызовов – это структура данных, которую JavaScript использует для управления контекстом выполнения функции. Он записывает, где выполняется текущая функция и какая функция выполняется. Если мы выполняем функцию, контекст выполнения создается для функции и помещается на вершину стека. Если мы возвращаемся из функции, извлекать ее контекст выполнения из вершины стека. Также можно сказать, что стек вызовов — это стек, используемый для управления этим контекстом выполнения, или стек контекста выполнения (стек выполнения).
3. Интервью: пространство стека и пространство кучи
В JavaScript существует три основных типа пространства памяти:
- Кодовое пространство: в основном используется для хранения исполняемого кода.
- Пространство стека: пространство для хранения стека вызовов — это пространство стека.
- куча пространства
Кодовое пространство в основном используется для хранения исполняемого кода. Пространство стека и пространство кучи в основном используются для хранения данных. Далее мы в основном вводим пространство стека и пространство кучи.
Когда контекст выполнения выполняется в стеке вызовов, контекст и связанное с ним пространство данных должны быть удалены. сборщик мусора (нового поколения) С основным сборщиком мусора (старого поколения) для сбора.
4. Детали
4. Byte & leetcode155: минимальный стек (стек, содержащий функцию getMin)
1. Темы
спроектировать опоруpush
,pop
,top
операции и может получить стек с наименьшим элементом за постоянное время.
-
push(x)
- Поместить элемент x в стек. -
pop()
—— Удалить элемент в верхней части стека. -
top()
—— Получить верхний элемент стека. -
getMin()
- Получить наименьший элемент в стеке.
Пример:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
2. Решение
Стек с наименьшим элементом извлекается за постоянное время, т.е. только гарантируетgetMin
Временная сложность O (1)
var MinStack = function() {
this.items = []
this.min = null
};
// 进栈
MinStack.prototype.push = function(x) {
if(!this.items.length) this.min = x
this.min = Math.min(x, this.min)
this.items.push(x)
};
// 出栈
MinStack.prototype.pop = function() {
let num = this.items.pop()
this.min = Math.min(...this.items)
return num
};
// 获取栈顶元素
MinStack.prototype.top = function() {
if(!this.items.length) return null
return this.items[this.items.length -1]
};
// 检索栈中的最小元素
MinStack.prototype.getMin = function() {
return this.min
};
Временная сложность: O(1) для нажатия, O(n) для извлечения, O(1) для получения верхнего элемента стека, O(1) для получения наименьшего элемента
Космическая сложность: O(n)
3. Больше решений
смотрите подробностиbytes&leetcode155: минимальный стек (стек, содержащий функцию getMin)
5. Графика Tencent и leetcode20: Допустимые скобки
1. Темы
Учитывая только включить'('
,')'
,'{'
,'}'
,'['
,']'
Строка, чтобы определить, является ли строка допустимой.
Действительная строка должна удовлетворять:
- Открывающие скобки должны быть закрыты закрывающими скобками того же типа.
- Левые скобки должны быть закрыты в правильном порядке.
Обратите внимание, что пустые строки считаются допустимыми строками.
Пример 1:
输入: "()"
输出: true
Пример 2:
输入: "()[]{}"
输出: true
Пример 3:
输入: "(]"
输出: false
Пример 4:
输入: "([)]"
输出: false
Пример 5:
输入: "{[]}"
输出: true
2. Решение: использовать структуру стека
Идеи решения проблемы:Вставьте символы в строку в стек по очереди и пройдитесь по символам, чтобы судить по очереди:
- Сначала определите, является ли элемент
{
,(
,[
, прямо в стек - В противном случае персонаж
}
,)
,]
Один из вариантов, если строка действительна, элемент должен соответствовать вершине стека, например, элемент в стеке имеет({
, если элемент, который продолжает движение,)
, то текущая последовательность элементов({)
Невозможно быть действительным, поэтому, если он не соответствует верхнему элементу стека в это время, он вернется напрямую.false
, строка недействительна
Когда обход завершен, все совпадающие символы были сопоставлены и выскочили из стека. Если стек в это время пуст, строка действительна. Если стек не пуст, это означает, что в строке есть несовпадающие символы. , а строка недействительна.
Рисунок для понимания:
Код:
var isValid = function(s) {
let map = {
'{': '}',
'(': ')',
'[': ']'
}
let stack = []
for(let i = 0; i < s.length ; i++) {
if(map[s[i]]) {
stack.push(s[i])
} else if(s[i] !== map[stack.pop()]){
return false
}
}
return stack.length === 0
};
Временная сложность: O(n)
Космическая сложность: O(n)
3. Больше решений
смотрите подробностиГрафика Tencent&leetcode20: Допустимые скобки
6. leetcode1047: удалить все соседние дубликаты в строке.
1. Темы
дать строку, состоящую из строчных буквS
,Дублирование операции удаленияДве соседние и одинаковые буквы выбираются и удаляются.
Повторяйте операцию дедупликации на S до тех пор, пока его больше нельзя будет удалить.
Возвращает окончательную строку после выполнения всех операций дедупликации. Ответ гарантированно будет уникальным.
Пример:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
намекать:
<= S.length <= 20000
-
S
Состоит только из строчных английских букв.
2. Решение: используйте стек
Идеи решения проблемы:Пройдите строку и поместите ее в стек последовательно. При добавлении в стек оцените, согласуется ли он с элементом заголовка стека. необходимо извлечь из стека, а текущий элемент не нужно помещать в стек.
Этапы решения проблемы:Пройдите по строке, извлеките символ заголовка стека и определите, согласуется ли текущий символ с символом заголовка стека.
- Несовместимо, символ заголовка помещается в стек, а текущий символ помещается в стек.
- Консистентные, то есть символ заголовка стека совпадает с текущим символом, и их не нужно запихивать в стек, просто сразу перейти к следующему обходу
После завершения обхода вернуть строку в стек
Код:
var removeDuplicates = function(S) {
let stack = []
for(c of S) {
let prev = stack.pop()
if(prev !== c) {
stack.push(prev)
stack.push(c)
}
}
return stack.join('')
};
Временная сложность: O(n)
Космическая сложность: O(n)
3. Больше решений
смотрите подробностиleetcode1047: удалить все соседние дубликаты в строке
7. Присоединиться к первой фазе тренировочного лагеря по фронтенд-алгоритму можно бесплатно.
Создайте полную структуру данных и систему алгоритмов от 0 до 1!
Здесь мистер Боттл не только представляет алгоритм, но и объединяет алгоритм с различными полями интерфейса, включая браузеры, HTTP, V8, React, исходный код Vue и т. д.
Здесь вы можете изучать большой вопрос по заводскому алгоритму (Ali, Tencent, Baidu, Byte и т. д.) или литкод каждый день, а мистер Бутылка ответит на него на следующий день!
Отсканируйте код, чтобы присоединиться. Если количество человек в группе достигло линии, подпишитесь на общедоступную учетную запись «Front-end Bottle Gentleman» и ответьте «алгоритм» для автоматического присоединения.
⬆️Отсканируйте код, чтобы подписаться на официальный аккаунт «Front-end Bottle King», и ответьте на «Алгоритм», чтобы автоматически присоединиться к 👍👍👍