Irbisa · Шпаргалка
Live coding на Go
Big O, хеширование, два указателя, скользящее окно, стек, бинарный поиск, кучи и графы на Go, а также конкурентные задачи вроде пула воркеров с ограничением
Что такое нотация Big-O и сколько стоят поиск, вставка и удаление в слайсе Go, в map и в отсортированном слайсе?
Напишите функцию, которая возвращает пересечение двух неупорядоченных слайсов любой длины. Сколько она стоит и что нужно сначала уточнить про дубликаты?
// Intersect returns the values present in both slices, as many times as// they occur in both: [1 1 2 3] and [1 1 1 3] give [1 1 3].func Intersect[T comparable](a, b []T) []T { if len(a) > len(b) { a, b = b, a // count the smaller slice: O(min(n, m)) memory }…Проверьте, что строка из скобок вроде
([]{})сбалансирована. Какую структуру вы используете и на каких входах ломается решение, которое просто считает скобки?var opening = map[byte]byte{')': '(', ']': '[', '}': '{'} func Balanced(s string) bool { var stack []byte for i := 0; i < len(s); i++ { // bytes are safe: UTF-8 never hides '(' inside a letter switch c := s[i]; c {…Проверьте, является ли строка палиндромом без учёта регистра, пробелов и знаков препинания, чтобы
А роза упала на лапу Азорапроходила. Почему сравнениеs[i]сs[len(s)-1-i]не работает?func IsPalindrome(s string) bool { i, j := 0, len(s) // byte offsets: s[i:j] is what is left to check for i < j { l, lw := utf8.DecodeRuneInString(s[i:]) if !isAlnum(l) { i += lw…Проверьте за один проход, монотонен ли слайс, то есть целиком неубывающий или целиком невозрастающий. На каких входах ошибаются быстрые решения?
func IsMonotonic[T cmp.Ordered](a []T) bool { up, down := true, true for i := 1; i < len(a); i++ { if a[i-1] > a[i] { up = false }…Разверните односвязный список на месте. Напишите итеративную версию и скажите, во что обходится рекурсивная в Go.
type Node[T any] struct { Val T Next *Node[T]} func Reverse[T any](head *Node[T]) *Node[T] {…Дедупликация 200 000 адресов этой функцией занимает около 15 секунд. Какова её временная сложность и как довести её до O(n)?
// uniqueEmails returns each address once, case-insensitively, in input order.func uniqueEmails(emails []string) []string { var out []string for _, e := range emails { e = strings.ToLower(strings.TrimSpace(e)) if !slices.Contains(out, e) { out = append(out, e) } } return out}Сгруппируйте список слов по анаграммам, чтобы
eat,teaиateоказались вместе. Что вы используете как ключ map в Go и сколько это стоит?func GroupAnagrams(words []string) [][]string { index := map[[26]int]int{} // letter counts -> position in groups var groups [][]string for _, w := range words { var key [26]int // an array is comparable, so it can be a map key for i := 0; i < len(w); i++ {…Найдите длину самой длинной подстроки без повторяющихся символов за O(n). Как движется окно и что меняется для текста не в ASCII?
func LongestUnique(s string) int { last := map[rune]int{} // rune -> its position (in runes) when last seen best, start, pos := 0, 0, 0 for _, r := range s { // runes, not bytes: "щука" is 4 characters, not 8 if p, seen := last[r]; seen { start = max(start, p+1) // never move the left edge back…Объедините пересекающиеся интервалы, например слоты бронирования
[1,3] [2,6] [8,10] [9,12]. Зачем сначала сортировать и сколько это стоит?type Interval struct{ Start, End int } func Merge(xs []Interval) []Interval { if len(xs) == 0 { return nil }…Найдите баг: этот бинарный поиск первой метки времени не раньше
tна некоторых входах зависает навсегда.// firstAtOrAfter returns the index of the first element >= t,// or len(ts) if there is none. ts is sorted.func firstAtOrAfter(ts []int64, t int64) int { lo, hi := 0, len(ts)-1 for lo <= hi { mid := lo + (hi-lo)/2 if ts[mid] < t { lo = mid + 1 } else { hi = mid // mid may be the answer, so keep it } } return lo}Найдите баг:
topKнаcontainer/heapвозвращаетkслов, но редко самые частые, и при каждом запуске другой набор.type entry struct { word string count int} // topK uses minHeap, a []entry implementing heap.Interface (least frequent at the root).func topK(counts map[string]int, k int) []entry { h := &minHeap{} for w, c := range counts { h.Push(entry{w, c}) if h.Len() > k { h.Pop() // drop the least frequent } } return *h}Реализуйте LRU-кэш с
GetиPutза O(1). Какие две структуры вы сочетаете в Go и почему одной map недостаточно?type LRU[K comparable, V any] struct { cap int order *list.List // front = most recently used items map[K]*list.Element // key -> its node in order}…Посчитайте острова в сетке из
0и1. BFS или DFS, и почему рекурсивный DFS в Go может упасть на карте 3000×3000?func CountIslands(grid [][]byte) int { if len(grid) == 0 { return 0 } rows, cols := len(grid), len(grid[0]) seen := make([]bool, rows*cols) // leaves the caller's grid untouched…Два канала отдают числа по возрастанию. Слейте их в один канал по возрастанию. Почему не подходит
selectпо обоим и что меняется для k каналов?func MergeSorted[T cmp.Ordered](ctx context.Context, a, b <-chan T) <-chan T { out := make(chan T) go func() { defer close(out) // the only sender closes, once va, okA := recv(ctx, a) vb, okB := recv(ctx, b)…Даны сервисы и сервисы, от которых зависит каждый из них. Верните порядок их запуска или сообщите о цикле, из-за которого это невозможно.
// StartOrder lists services so that each one comes after everything it// depends on, or returns the first dependency cycle it finds.func StartOrder(deps map[string][]string) ([]string, error) { const ( onPath = iota + 1 // on the current DFS path; 0 means not visited yet done…Напишите конкурентный краулер: пройти по ссылкам от одного URL до глубины 2, скачать каждый URL один раз, не больше 10 загрузок одновременно. Как он понимает, что закончил?
type FetchFunc func(ctx context.Context, url string) (links []string, err error) // Crawl fetches every URL within maxDepth links of start, each once, with at// most limit fetches in flight, and returns the URLs it scheduled.func Crawl(ctx context.Context, fetch FetchFunc, start string, maxDepth, limit int) []string { var (…Напишите клиентский балансировщик над ненадёжными бэкендами: распределяйте вызовы по кругу (round-robin), а при ошибке пробуйте следующий бэкенд, пока один не ответит или не истечёт контекст.
type Backend interface { Invoke(ctx context.Context, req []byte) ([]byte, error)} type Balancer struct { backends []Backend…