Skip to content

Go for Python Devs: LeetCode One-Page Cheat Sheet

Go for Python Devs: LeetCode One-Page Cheat Sheet

Section titled “Go for Python Devs: LeetCode One-Page Cheat Sheet”
// Most-used imports
import ("container/heap"; "sort")
// Min helpers
func min(a,b int) int { if a<b { return a }; return b }
func max(a,b int) int { if a>b { return a }; return b }
// Binary search (first true in [0,n))
l, r := 0, n
for l < r {
m := l + (r-l)/2
if check(m) { r = m } else { l = m + 1 }
}
// BFS queue (O(1) amortized pop-left)
q, head := []int{start}, 0
seen := map[int]bool{start:true}
for head < len(q) {
x := q[head]; head++
for _, y := range g[x] {
if seen[y] { continue }
seen[y] = true
q = append(q, y)
}
}
// DFS recursive
var dfs func(int)
dfs = func(u int) {
vis[u] = true
for _, v := range g[u] { if !vis[v] { dfs(v) } }
}
// Sliding window
l := 0
for r := 0; r < len(s); r++ {
add(s[r])
for bad() { remove(s[l]); l++ }
ans = max(ans, r-l+1)
}
// Prefix sum + hash (subarray sum == k)
cnt := map[int]int{0:1}
sum := 0
for _, x := range nums {
sum += x
ans += cnt[sum-k]
cnt[sum]++
}
// Monotonic stack skeleton
st := []int{} // usually indices
for i := 0; i < n; i++ {
for len(st) > 0 && bad(st[len(st)-1], i) { st = st[:len(st)-1] }
st = append(st, i)
}
// DSU find
func (d *DSU) Find(x int) int {
if d.p[x] != x { d.p[x] = d.Find(d.p[x]) }
return d.p[x]
}

Rapid gotchas:

  • len(string) is bytes; use []rune for unicode index.
  • for range copies values; mutate via index.
  • map iteration order is random.
  • use int64 for large sums/products.
// Arrays / strings
func twoSum(nums []int, target int) []int {}
func lengthOfLongestSubstring(s string) int {}
// Linked list
type ListNode struct {
Val int
Next *ListNode
}
func reverseList(head *ListNode) *ListNode {}
// Binary tree
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func maxDepth(root *TreeNode) int {}
PythonGo
list[int][]int
dict[k]vmap[K]V
set[int]map[int]struct{}
tuple(a,b)[2]int or struct{a,b int}
Nonenil (for ptr/map/slice/interface/func/channel)
heapqcontainer/heap (interface impl)
deque[]T + head index
package main
import (
"container/heap"
"sort"
"strconv"
"strings"
)
func solve(nums []int) int {
ans := 0
for i := 0; i < len(nums); i++ {
if nums[i] > 0 {
ans += nums[i]
}
}
return ans
}
slice/list
a := []int{1, 2, 3}
a = append(a, 4) // push
x := a[len(a)-1]; a = a[:len(a)-1] // pop
a = append(a[:i], a[i+1:]...) // delete index i
b := make([]int, n) // zeroed len=n
c := make([]int, n, 2*n) // len=n cap=2n
copy(b, a) // copy min(len(b),len(a))
// map/dict
m := map[string]int{}
m["a"]++
v, ok := m["x"] // if !ok, v is zero value
delete(m, "a")
// set
set := map[int]struct{}{}
set[5] = struct{}{}
_, ok = set[5]
delete(set, 5)
s := "abc"
n := len(s) // bytes, not runes
sub := s[l:r] // byte slice
bs := []byte(s) // mutable bytes
bs[0] = 'z'
s2 := string(bs)
rs := []rune(s) // unicode-safe indexing
_ = rs
parts := strings.Split("a,b,c", ",")
joined := strings.Join(parts, "|")
num, _ := strconv.Atoi("123")
str := strconv.Itoa(123)
l, r := 0, len(nums)-1
for l < r {
if nums[l]+nums[r] < target {
l++
} else {
r--
}
}
l, r := 0, n // [l, r)
for l < r {
mid := l + (r-l)/2
if check(mid) {
r = mid
} else {
l = mid + 1
}
}
ans := l
_ = ans
pre := make([]int, len(nums)+1)
for i := 0; i < len(nums); i++ {
pre[i+1] = pre[i] + nums[i]
}
sumLR := pre[r+1] - pre[l] // inclusive [l..r]
_ = sumLR
// Prefix hash map: count subarrays with sum == k
cnt := map[int]int{0: 1}
sum, ans := 0, 0
for _, x := range nums {
sum += x
ans += cnt[sum-k]
cnt[sum]++
}
res := make([]int, len(nums))
st := []int{} // store indices
for i := len(nums) - 1; i >= 0; i-- {
for len(st) > 0 && nums[st[len(st)-1]] <= nums[i] {
st = st[:len(st)-1]
}
if len(st) == 0 {
res[i] = -1
} else {
res[i] = nums[st[len(st)-1]]
}
st = append(st, i)
}
freq := map[byte]int{}
best := 0
l := 0
for r := 0; r < len(s); r++ {
c := s[r]
freq[c]++
for /* invalid window */ false {
d := s[l]
freq[d]--
if freq[d] == 0 {
delete(freq, d)
}
l++
}
if r-l+1 > best {
best = r - l + 1
}
}
q := []int{start}
head := 0
seen := map[int]bool{start: true}
for head < len(q) {
x := q[head]
head++
for _, y := range g[x] {
if seen[y] {
continue
}
seen[y] = true
q = append(q, y)
}
}
func dfs(u int, g [][]int, vis []bool) {
vis[u] = true
for _, v := range g[u] {
if !vis[v] {
dfs(v, g, vis)
}
}
}
path := []int{}
var ans [][]int
var dfs func(int)
dfs = func(i int) {
if i == n {
t := append([]int(nil), path...) // clone
ans = append(ans, t)
return
}
// choose
path = append(path, nums[i])
dfs(i + 1)
path = path[:len(path)-1]
// skip
dfs(i + 1)
}
dfs(0)
indeg := make([]int, n)
g := make([][]int, n)
for _, e := range edges {
u, v := e[0], e[1]
g[u] = append(g[u], v)
indeg[v]++
}
q := []int{}
for i := 0; i < n; i++ {
if indeg[i] == 0 {
q = append(q, i)
}
}
head, order := 0, []int{}
for head < len(q) {
u := q[head]
head++
order = append(order, u)
for _, v := range g[u] {
indeg[v]--
if indeg[v] == 0 {
q = append(q, v)
}
}
}
isDAG := len(order) == n
_ = isDAG
sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] })
out := [][]int{}
for _, it := range intervals {
if len(out) == 0 || out[len(out)-1][1] < it[0] {
out = append(out, []int{it[0], it[1]})
} else if it[1] > out[len(out)-1][1] {
out[len(out)-1][1] = it[1]
}
}
type MinHeap []int
func (h MinHeap) Len() int { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *MinHeap) Pop() interface{} {
old := *h
x := old[len(old)-1]
*h = old[:len(old)-1]
return x
}
h := &MinHeap{}
heap.Init(h)
heap.Push(h, 3)
heap.Push(h, 1)
mn := heap.Pop(h).(int)
_ = mn
type DSU struct {
p []int
r []int
}
func NewDSU(n int) *DSU {
p, r := make([]int, n), make([]int, n)
for i := range p {
p[i] = i
}
return &DSU{p: p, r: r}
}
func (d *DSU) Find(x int) int {
if d.p[x] != x {
d.p[x] = d.Find(d.p[x])
}
return d.p[x]
}
func (d *DSU) Union(a, b int) bool {
ra, rb := d.Find(a), d.Find(b)
if ra == rb {
return false
}
if d.r[ra] < d.r[rb] {
ra, rb = rb, ra
}
d.p[rb] = ra
if d.r[ra] == d.r[rb] {
d.r[ra]++
}
return true
}
// 1D DP: min steps
dp := make([]int, n+1)
const INF = int(1e9)
for i := range dp {
dp[i] = INF
}
dp[0] = 0
for i := 1; i <= n; i++ {
// dp[i] = min(dp[i], dp[i-k]+cost)
}
// 2D DP grid
dp2 := make([][]int, m)
for i := range dp2 {
dp2[i] = make([]int, n)
}
var prev *ListNode
cur := head
for cur != nil {
nxt := cur.Next
cur.Next = prev
prev = cur
cur = nxt
}
head = prev
st := []*TreeNode{}
cur := root
for cur != nil || len(st) > 0 {
for cur != nil {
st = append(st, cur)
cur = cur.Left
}
cur = st[len(st)-1]
st = st[:len(st)-1]
// visit cur.Val
cur = cur.Right
}
dirs := [][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}
in := func(r, c int) bool { return r >= 0 && r < m && c >= 0 && c < n }
  • for range copies element value; mutate slice via index (nums[i] = ...).
  • No while; use for condition {}.
  • No ternary operator.
  • Map iteration order is random.
  • len(string) is bytes; convert to []rune for unicode indexing.
  • Use int64 for large sums/products.
  • Recursive DFS can stack overflow on deep graphs; switch to iterative if needed.
func min(a, b int) int { if a < b { return a }; return b }
func max(a, b int) int { if a > b { return a }; return b }
func abs(x int) int { if x < 0 { return -x }; return x }
isOdd := x&1 == 1
pow2 := x > 0 && (x&(x-1)) == 0
lowbit := x & -x
bits := 0
for y := x; y > 0; y &= y - 1 { bits++ } // popcount
gcd := func(a, b int) int {
for b != 0 { a, b = b, a%b }
return a
}
  • Sort: O(n log n)
  • Hash lookup: average O(1)
  • Heap push/pop: O(log n)
  • BFS/DFS graph: O(V+E)
  • Union-Find: almost O(1) amortized