LeetCode in Go: Patterns and Templates
LeetCode in Go: Patterns and Templates
Section titled “LeetCode in Go: Patterns and Templates”This page is the working notebook for Go-first LeetCode practice.
Go Quick Reference (for LeetCode)
Section titled “Go Quick Reference (for LeetCode)”flowchart LR A[Variables] --> B[Control Flow] B --> C[Functions] C --> D[Collections] D --> E[Sort / String / Convert] E --> F[Solve Problem]Variable Types
Section titled “Variable Types”var a int = 10var b int64 = 20var c float64 = 3.14var d bool = truevar e string = "go"var f byte = 'A' // alias for uint8var g rune = '中' // alias for int32 (unicode code point)Short declaration (most common in solutions):
x := 42name := "leet"ok := falseUseful composites:
arr := [3]int{1, 2, 3} // fixed-size arraynums := []int{1, 2, 3} // slice (dynamic)freq := map[int]int{} // mapseen := make(map[string]bool) // map with makeLooping Options
Section titled “Looping Options”flowchart TD A[Choose loop style] --> B{Known iteration count?} B -- Yes --> C[Classic for i := 0; i < n; i++] B -- No --> D{Condition-based?} D -- Yes --> E[for condition] D -- No --> F[for range collection]Classic for:
for i := 0; i < n; i++ { // use i}while style:
for left < right { left++}Infinite loop:
for { break}Range over slice:
for i, v := range nums { _ = i _ = v}Range over map:
for k, v := range freq { _ = k _ = v}Conditionals and Switch
Section titled “Conditionals and Switch”if x > 0 { // ...} else if x == 0 { // ...} else { // ...}
switch x {case 1, 2: // ...default: // ...}Functions (value vs pointer)
Section titled “Functions (value vs pointer)”func add(a, b int) int { return a + b}
func setZero(nums []int) { // slices are descriptor values; underlying array can change if len(nums) > 0 { nums[0] = 0 }}
func grow(mp map[int]int) { // maps are reference-like mp[1]++}Common Built-ins
Section titled “Common Built-ins”n := len(nums)nums = append(nums, 4)copy(dst, src)delete(freq, key)Sorting
Section titled “Sorting”import "sort"
sort.Ints(nums)sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0]})Strings and Conversions
Section titled “Strings and Conversions”import "strconv"
s := "123"v, _ := strconv.Atoi(s)str := strconv.Itoa(v)
for i, ch := range s { // ch is rune _ = i _ = ch}Tips for LeetCode in Go
Section titled “Tips for LeetCode in Go”- Prefer slices over arrays for inputs.
- Preallocate when size is known:
make([]int, 0, n). - Use
map[value]indexfor lookup problems. - Keep helper functions small and typed explicitly.
- Return
nilfor “not found” slice answers when accepted.
Data Structure Templates (Go + Python)
Section titled “Data Structure Templates (Go + Python)”Stack (LIFO)
Section titled “Stack (LIFO)”graph LR A[push 1] --> B[push 2] B --> C[push 3] C --> D[pop -> 3] D --> E[pop -> 2]Go:
stack := []int{}
// pushstack = append(stack, 10)
// poptop := stack[len(stack)-1]stack = stack[:len(stack)-1]_ = top
// peekpeek := stack[len(stack)-1]_ = peekPython:
stack = []
# pushstack.append(10)
# poptop = stack.pop()
# peekpeek = stack[-1]Queue (FIFO)
Section titled “Queue (FIFO)”graph LR A[enqueue 1] --> B[enqueue 2] B --> C[enqueue 3] C --> D[dequeue -> 1] D --> E[dequeue -> 2]Go:
q := []int{}
// enqueueq = append(q, 1)
// dequeuefront := q[0]q = q[1:]_ = frontPython:
from collections import deque
q = deque()q.append(1) # enqueuefront = q.popleft() # dequeueDeque (Double-Ended Queue)
Section titled “Deque (Double-Ended Queue)”graph LR A[pushFront 2] --> B[2] B --> C[pushBack 3] C --> D[2 then 3] D --> E[popFront -> 2] E --> F[popBack -> 3]Go (simple slice approach):
dq := []int{}
// push backdq = append(dq, 3)
// push frontdq = append([]int{2}, dq...)
// pop frontfront := dq[0]dq = dq[1:]_ = front
// pop backback := dq[len(dq)-1]dq = dq[:len(dq)-1]_ = backPython:
from collections import deque
dq = deque()dq.append(3) # push backdq.appendleft(2) # push frontfront = dq.popleft()back = dq.pop()Heap / Priority Queue
Section titled “Heap / Priority Queue”flowchart TD A[Push values] --> B[Heap property maintained] B --> C[Pop returns smallest] C --> D[Repeat for k-smallest / Dijkstra / scheduling]Go (min-heap):
import "container/heap"
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }func (h *IntHeap) Push(x any) { *h = append(*h, x.(int)) }func (h *IntHeap) Pop() any { old := *h n := len(old) x := old[n-1] *h = old[:n-1] return x}
h := &IntHeap{}heap.Init(h)heap.Push(h, 5)heap.Push(h, 1)min := heap.Pop(h).(int)_ = minPython (min-heap):
import heapq
h = []heapq.heappush(h, 5)heapq.heappush(h, 1)mn = heapq.heappop(h)Hash Map / Dictionary
Section titled “Hash Map / Dictionary”flowchart LR A[Read element x] --> B{map has x?} B -- Yes --> C[update count/index] B -- No --> D[insert x]Go:
freq := map[int]int{}for _, n := range nums { freq[n]++}Python:
freq = {}for n in nums: freq[n] = freq.get(n, 0) + 1flowchart LR A[Value v] --> B{v in set?} B -- Yes --> C[skip / found duplicate] B -- No --> D[add v]Go:
seen := map[int]struct{}{}seen[5] = struct{}{}_, ok := seen[5]delete(seen, 5)_ = okPython:
seen = set()seen.add(5)ok = 5 in seenseen.remove(5)Linked List Node
Section titled “Linked List Node”Go:
type ListNode struct { Val int Next *ListNode}Python:
class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = nextBinary Tree Node + DFS
Section titled “Binary Tree Node + DFS”graph TD A[root] --> B[left] A --> C[right] B --> D[left.left] B --> E[left.right]Go:
type TreeNode struct { Val int Left *TreeNode Right *TreeNode}
func dfs(root *TreeNode) { if root == nil { return } dfs(root.Left) dfs(root.Right)}Python:
class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right
def dfs(root): if not root: return dfs(root.left) dfs(root.right)BFS on Tree
Section titled “BFS on Tree”flowchart TD A[Init queue with root] --> B[Pop front] B --> C[Process node] C --> D[Push children] D --> E{Queue empty?} E -- No --> B E -- Yes --> F[Done]Go:
func bfs(root *TreeNode) { if root == nil { return } q := []*TreeNode{root} for len(q) > 0 { node := q[0] q = q[1:] _ = node if node.Left != nil { q = append(q, node.Left) } if node.Right != nil { q = append(q, node.Right) } }}Python:
from collections import deque
def bfs(root): if not root: return q = deque([root]) while q: node = q.popleft() if node.left: q.append(node.left) if node.right: q.append(node.right)DateTime (Go + Python)
Section titled “DateTime (Go + Python)”flowchart LR A[Input time string / now] --> B[Parse or get current] B --> C[Normalize timezone] C --> D[Compute duration / compare] D --> E[Format output]Current Time and UTC
Section titled “Current Time and UTC”Go:
import "time"
now := time.Now()utc := now.UTC()Python:
from datetime import datetime, timezone
now = datetime.now()utc_now = datetime.now(timezone.utc)Unix Timestamps
Section titled “Unix Timestamps”Go:
tsSec := time.Now().Unix() // secondstsMilli := time.Now().UnixMilli()
t := time.Unix(tsSec, 0)Python:
from datetime import datetime
ts_sec = int(datetime.now().timestamp())t = datetime.fromtimestamp(ts_sec)Parse and Format
Section titled “Parse and Format”Go (time uses reference layout 2006-01-02 15:04:05):
import "time"
s := "2026-02-22T05:00:00Z"t, err := time.Parse(time.RFC3339, s)if err != nil { // handle error}
out := t.Format("2006-01-02 15:04:05")_ = outPython:
from datetime import datetime
s = "2026-02-22T05:00:00+00:00"t = datetime.fromisoformat(s)out = t.strftime("%Y-%m-%d %H:%M:%S")Time Zones
Section titled “Time Zones”Go:
import "time"
loc, err := time.LoadLocation("America/Chicago")if err != nil { // handle error}local := time.Now().In(loc)_ = localPython:
from datetime import datetimefrom zoneinfo import ZoneInfo
local = datetime.now(ZoneInfo("America/Chicago"))Durations and Date Math
Section titled “Durations and Date Math”Go:
import "time"
start := time.Now()deadline := start.Add(30 * time.Minute)elapsed := time.Since(start)diff := deadline.Sub(start)_ = elapsed_ = diffPython:
from datetime import datetime, timedelta
start = datetime.now()deadline = start + timedelta(minutes=30)elapsed = datetime.now() - startdiff = deadline - startLeetCode Tip
Section titled “LeetCode Tip”When a problem is about intervals/scheduling, convert times to int minutes or seconds early and work with integers for simpler comparisons and sorting.
File I/O (Go + Python)
Section titled “File I/O (Go + Python)”flowchart LR A[Open/read file] --> B[Transform data] B --> C[Write/append result] C --> D[Close/flush]Read Entire File
Section titled “Read Entire File”Go:
import "os"
data, err := os.ReadFile("input.txt")if err != nil { // handle error}text := string(data)_ = textPython:
with open("input.txt", "r", encoding="utf-8") as f: text = f.read()Write Entire File (overwrite)
Section titled “Write Entire File (overwrite)”Go:
import "os"
err := os.WriteFile("output.txt", []byte("hello\n"), 0o644)if err != nil { // handle error}Python:
with open("output.txt", "w", encoding="utf-8") as f: f.write("hello\n")Append to File
Section titled “Append to File”Go:
import "os"
f, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)if err != nil { // handle error}defer f.Close()
_, err = f.WriteString("new line\n")if err != nil { // handle error}Python:
with open("log.txt", "a", encoding="utf-8") as f: f.write("new line\n")Read Line by Line
Section titled “Read Line by Line”Go:
import ( "bufio" "os")
f, err := os.Open("input.txt")if err != nil { // handle error}defer f.Close()
scanner := bufio.NewScanner(f)for scanner.Scan() { line := scanner.Text() _ = line}if err := scanner.Err(); err != nil { // handle error}Python:
with open("input.txt", "r", encoding="utf-8") as f: for line in f: line = line.rstrip("\n")Go Template
Section titled “Go Template”flowchart TD A[Read input] --> B[Call solve function] B --> C[Apply pattern] C --> D[Return answer] D --> E[Print output]package main
import "fmt"
func solve(nums []int) int { // TODO return 0}
func main() { fmt.Println(solve([]int{1, 2, 3}))}Pattern Checklist
Section titled “Pattern Checklist”- Arrays and Hash Maps
- Two Pointers
- Sliding Window
- Binary Search
- Stack / Monotonic Stack
- BFS / DFS
- Backtracking
- Dynamic Programming
- Graph Shortest Paths
- Heaps / Priority Queues
Common Snippets (Go)
Section titled “Common Snippets (Go)”Frequency Map
Section titled “Frequency Map”freq := make(map[int]int)for _, n := range nums { freq[n]++}Queue (BFS)
Section titled “Queue (BFS)”q := []int{start}for len(q) > 0 { cur := q[0] q = q[1:] _ = cur}Min-Heap (Priority Queue)
Section titled “Min-Heap (Priority Queue)”import "container/heap"
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x any) { *h = append(*h, x.(int))}
func (h *IntHeap) Pop() any { old := *h n := len(old) x := old[n-1] *h = old[:n-1] return x}
// usage:h := &IntHeap{}heap.Init(h)heap.Push(h, 3)heap.Push(h, 1)min := heap.Pop(h).(int)_ = minNext Problems To Add
Section titled “Next Problems To Add”- Two Sum (hash map)
- Valid Parentheses (stack)
- Binary Search (iterative)
- Maximum Subarray (Kadane)
- Number of Islands (DFS/BFS)