diff --git a/solutions/0/q52/solution.go b/solutions/0/q52/solution.go new file mode 100644 index 0000000..8618f23 --- /dev/null +++ b/solutions/0/q52/solution.go @@ -0,0 +1,24 @@ +package q52 + +func findNSolutions(nQueen, row int, rows, cols, diag1, diag2 []bool) int { + solutions := 0 + if row == nQueen { + return 1 + } + for col := range nQueen { + // if grid[row][col] is placeable + if !rows[row] && !cols[col] && !diag1[row+col] && !diag2[row-col+nQueen] { + rows[row], cols[col], diag1[row+col], diag2[row-col+nQueen] = true, true, true, true + solutions += findNSolutions(nQueen, row+1, rows, cols, diag1, diag2) + rows[row], cols[col], diag1[row+col], diag2[row-col+nQueen] = false, false, false, false + } + } + return solutions +} + +func totalNQueens(n int) int { + buf := make([]bool, 6*n) + return findNSolutions(n, 0, buf[0:n], buf[n:2*n], buf[2*n:4*n], buf[4*n:]) +} + +var _ = totalNQueens diff --git a/solutions/0/q63/solution.go b/solutions/0/q63/solution.go new file mode 100644 index 0000000..cf5011e --- /dev/null +++ b/solutions/0/q63/solution.go @@ -0,0 +1,28 @@ +package q63 + +func uniquePathsWithObstacles(obstacleGrid [][]int) int { + w, h := len(obstacleGrid[0]), len(obstacleGrid) + if obstacleGrid[h-1][w-1]+obstacleGrid[0][0] > 0 { + return 0 + } + + obstacleGrid[h-1][w-1] = -1 + for i := w + h - 2; i >= 0; i-- { + for x := min(i, w-1); x >= 0 && i-x < h; x-- { + y := i - x + if obstacleGrid[y][x] == 1 { + continue + } + if x+1 < w && obstacleGrid[y][x+1] != 1 { + obstacleGrid[y][x] += obstacleGrid[y][x+1] + } + if y+1 < h && obstacleGrid[y+1][x] != 1 { + obstacleGrid[y][x] += obstacleGrid[y+1][x] + } + } + } + + return -1 * obstacleGrid[0][0] +} + +var _ = uniquePathsWithObstacles diff --git a/solutions/1/q102/solution.go b/solutions/1/q102/solution.go new file mode 100644 index 0000000..ab5828e --- /dev/null +++ b/solutions/1/q102/solution.go @@ -0,0 +1,43 @@ +package q102 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func levelOrder(root *TreeNode) [][]int { + if root == nil { + return [][]int{} + } + ret := [][]int{} + + type qElem struct { + lvl int + node *TreeNode + } + curLvl := 0 + curLvlNodes := []int{} + queue := []qElem{{0, root}} + for ; len(queue) > 0; queue = queue[1:] { + cur := &queue[0] + if cur.lvl != curLvl { + ret = append(ret, curLvlNodes) + curLvlNodes = []int{cur.node.Val} + curLvl = cur.lvl + } else { + curLvlNodes = append(curLvlNodes, cur.node.Val) + } + if cur.node.Left != nil { + queue = append(queue, qElem{lvl: cur.lvl + 1, node: cur.node.Left}) + } + if cur.node.Right != nil { + queue = append(queue, qElem{lvl: cur.lvl + 1, node: cur.node.Right}) + } + } + + ret = append(ret, curLvlNodes) + return ret +} + +var _ = levelOrder diff --git a/solutions/13/q1390/solution.go b/solutions/13/q1390/solution.go new file mode 100644 index 0000000..dc3778a --- /dev/null +++ b/solutions/13/q1390/solution.go @@ -0,0 +1,45 @@ +package q1390 + +import "slices" + +func sfd(n int) int { + if n < 6 { + return 0 + } + + buf := [6]int{1, n} + divisors := buf[:2] + nn := n + for i := 2; i*i <= nn; i++ { + for nn%i == 0 { + nn /= i + + if !slices.Contains(divisors, i) { + divisors = append(divisors, i) + } + if !slices.Contains(divisors, nn) { + divisors = append(divisors, nn) + } + if !slices.Contains(divisors, n/nn) { + divisors = append(divisors, n/nn) + } + if len(divisors) > 4 { + return 0 + } + } + } + if len(divisors) == 4 { + return divisors[0] + divisors[1] + divisors[2] + divisors[3] + } + return 0 +} + +func sumFourDivisors(nums []int) int { + sum := 0 + for _, n := range nums { + sum += sfd(n) + } + return sum +} + +var _ = sumFourDivisors diff --git a/solutions/14/q1411/solution.go b/solutions/14/q1411/solution.go new file mode 100644 index 0000000..d10f409 --- /dev/null +++ b/solutions/14/q1411/solution.go @@ -0,0 +1,62 @@ +package q1411 + +type Color uint8 + +const MODULO int = 1e9 + 7 + +func numOfWays(n int) int { + patterns := make([][3]Color, 0, 12) + for a := range 3 { + for b := range 3 { + for c := range 3 { + if a == b || b == c { + continue + } + patterns = append(patterns, [3]Color{Color(a), Color(b), Color(c)}) + } + } + } + + // Find compatible patterns + compatiblePtns := make([][]int, len(patterns)) + for i := range len(patterns) - 1 { + for j := i + 1; j < len(patterns); j++ { + ok := true + for k := range 3 { + if patterns[i][k] == patterns[j][k] { + ok = false + break + } + } + if ok { + compatiblePtns[i] = append(compatiblePtns[i], j) + compatiblePtns[j] = append(compatiblePtns[j], i) + } + } + } + + counts := make([]int, len(patterns)) + for i := range counts { + counts[i] = 1 + } + + countsNext := make([]int, len(patterns)) + for range n - 1 { + for i := range len(patterns) { + countsNext[i] = 0 + for _, j := range compatiblePtns[i] { + countsNext[i] += counts[j] + } + countsNext[i] %= MODULO + } + counts, countsNext = countsNext, counts + } + + sum := 0 + for _, c := range counts { + sum += c + } + return sum % MODULO +} + +var _ = numOfWays diff --git a/solutions/19/q1970/solution.go b/solutions/19/q1970/solution.go new file mode 100644 index 0000000..76f2b88 --- /dev/null +++ b/solutions/19/q1970/solution.go @@ -0,0 +1,67 @@ +package q1970 + +var dirs = [4][2]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}} + +func isPossibleOnDay(row, col int, cells [][]bool, day int, floods [][]int) bool { + for i := range col { + cells[0][i] = true + } + for i := range row - 1 { + copy(cells[i+1], cells[0]) + } + for i := range day { + cells[floods[i][0]-1][floods[i][1]-1] = false + } + + // Use bfs to find a path from top to bottom + queue := make([][2]int, 0, col) // {row, col} + for x, ok := range cells[0] { + if ok { + queue = append(queue, [2]int{0, x}) + cells[0][x] = false + } + } + for ; len(queue) > 0; queue = queue[1:] { + r, c := queue[0][0], queue[0][1] + for _, d := range dirs { + tr, tc := r+d[0], c+d[1] + if tr < 0 || tc < 0 || tr >= row || tc >= col { + continue + } + if !cells[tr][tc] { + continue + } + if tr == row-1 { + return true // reached bottom + } + cells[tr][tc] = false + queue = append(queue, [2]int{tr, tc}) + } + } + return false +} + +func latestDayToCross(row int, col int, cells [][]int) int { + walkableBuf := make([]bool, col*row) + walkable := make([][]bool, row) + for i := range row { + walkable[i] = walkableBuf[i*col : (i+1)*col] + } + + // Use binary search to find the last day + l, r := 1, len(cells)+1 + for l < r { + if l+1 == r { + return l + } + m := (l + r) / 2 + if isPossibleOnDay(row, col, walkable, m, cells) { + l = m + } else { + r = m + } + } + return 0 // impossible +} + +var _ = latestDayToCross diff --git a/solutions/2/q226/solution.go b/solutions/2/q226/solution.go index 6e51053..0abc04f 100644 --- a/solutions/2/q226/solution.go +++ b/solutions/2/q226/solution.go @@ -15,3 +15,5 @@ func invertTree(root *TreeNode) *TreeNode { invertTree(root.Right) return root } + +var _ = invertTree diff --git a/solutions/3/q380/solution.go b/solutions/3/q380/solution.go index 98a7857..685279e 100644 --- a/solutions/3/q380/solution.go +++ b/solutions/3/q380/solution.go @@ -1,13 +1,6 @@ package q380 -import ( - "math/rand" - "runtime/debug" -) - -func init() { - debug.SetMemoryLimit(16 << 20) -} +import "math/rand" var rng *rand.Rand = rand.New(rand.NewSource(42)) diff --git a/solutions/8/q840/solution.go b/solutions/8/q840/solution.go new file mode 100644 index 0000000..1a4d2f7 --- /dev/null +++ b/solutions/8/q840/solution.go @@ -0,0 +1,63 @@ +package q840 + +func checkSquare(x, y int, grid [][]int) bool { + seen := uint16(0) + rowSum, colSum := [3]int{}, [3]int{} + diag1sum, diag2sum := 0, 0 + + for ty := range 3 { + for tx := range 3 { + num := grid[y+ty][x+tx] + if num < 1 || num > 9 { + return false + } + tSeen := seen | (1 << (num - 1)) + if tSeen == seen { // duplicate number + return false + } + seen = tSeen + + rowSum[ty] += num + colSum[tx] += num + if tx == ty { + diag1sum += num + } + if tx+ty == 2 { + diag2sum += num + } + } + } + + if diag1sum != diag2sum { + return false + } + for i := range 3 { + if rowSum[i] != diag1sum || colSum[i] != diag1sum { + return false + } + } + return true +} + +func numMagicSquaresInside(grid [][]int) int { + if len(grid) < 3 || len(grid[0]) < 3 { + return 0 + } + w, h := len(grid[0]), len(grid) + + count := 0 + for y := range h - 2 { + for x := range w - 2 { + if grid[y+1][x+1] != 5 { // the center cell has to be 5 + continue + } + if checkSquare(x, y, grid) { + count++ + } + } + } + + return count +} + +var _ = numMagicSquaresInside diff --git a/solutions/9/q961/solution.go b/solutions/9/q961/solution.go new file mode 100644 index 0000000..f689a78 --- /dev/null +++ b/solutions/9/q961/solution.go @@ -0,0 +1,14 @@ +package q961 + +import "math/rand" + +func repeatedNTimes(nums []int) int { + for { + a, b := rand.Intn(len(nums)), rand.Intn(len(nums)) + if b != a && nums[a] == nums[b] { + return nums[a] + } + } +} + +var _ = repeatedNTimes