add new solutions
This commit is contained in:
parent
d798d5e8c9
commit
886b5e0a8e
34 changed files with 1164 additions and 0 deletions
39
solutions/0/q12/solution.go
Normal file
39
solutions/0/q12/solution.go
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package q12
|
||||
|
||||
import "strings"
|
||||
|
||||
var mapping = []struct {
|
||||
string
|
||||
int
|
||||
}{
|
||||
{"I", 1},
|
||||
{"IV", 4},
|
||||
{"V", 5},
|
||||
{"IX", 9},
|
||||
{"X", 10},
|
||||
{"XL", 40},
|
||||
{"L", 50},
|
||||
{"XC", 90},
|
||||
{"C", 100},
|
||||
{"CD", 400},
|
||||
{"D", 500},
|
||||
{"CM", 900},
|
||||
{"M", 1000},
|
||||
}
|
||||
|
||||
func intToRoman(num int) string {
|
||||
b := &strings.Builder{}
|
||||
|
||||
for i := len(mapping) - 1; i >= 0; i-- {
|
||||
for num >= mapping[i].int {
|
||||
num -= mapping[i].int
|
||||
b.WriteString(mapping[i].string)
|
||||
}
|
||||
if num == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
var _ = intToRoman
|
||||
26
solutions/0/q19/solution.go
Normal file
26
solutions/0/q19/solution.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package q19
|
||||
|
||||
type ListNode struct {
|
||||
Val int
|
||||
Next *ListNode
|
||||
}
|
||||
|
||||
func removeNthFromEnd(head *ListNode, n int) *ListNode {
|
||||
stub := &ListNode{Next: head}
|
||||
|
||||
probe := stub
|
||||
for range n {
|
||||
probe = probe.Next
|
||||
}
|
||||
prev := stub
|
||||
|
||||
for probe.Next != nil {
|
||||
probe = probe.Next
|
||||
prev = prev.Next
|
||||
}
|
||||
prev.Next = prev.Next.Next
|
||||
|
||||
return stub.Next
|
||||
}
|
||||
|
||||
var _ = removeNthFromEnd
|
||||
20
solutions/0/q3/solution.go
Normal file
20
solutions/0/q3/solution.go
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
package q3
|
||||
|
||||
func lengthOfLongestSubstring(s string) int {
|
||||
seen := make([]bool, 256)
|
||||
maxLen := 0
|
||||
|
||||
l := 0
|
||||
for r := range len(s) {
|
||||
c := s[r]
|
||||
for seen[c] {
|
||||
seen[s[l]] = false
|
||||
l++
|
||||
}
|
||||
seen[c] = true
|
||||
maxLen = max(maxLen, r-l+1)
|
||||
}
|
||||
return maxLen
|
||||
}
|
||||
|
||||
var _ = lengthOfLongestSubstring
|
||||
46
solutions/0/q33/solution.go
Normal file
46
solutions/0/q33/solution.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package q33
|
||||
|
||||
func findK(nums []int) int {
|
||||
if len(nums) < 2 || nums[0] < nums[len(nums)-1] {
|
||||
return 0
|
||||
}
|
||||
|
||||
l, r := 0, len(nums)
|
||||
for l < r && nums[l] > nums[r-1] {
|
||||
m := (l + r) / 2
|
||||
if nums[m] > nums[r-1] {
|
||||
l = m + 1
|
||||
} else {
|
||||
r = m + 1
|
||||
l++
|
||||
}
|
||||
}
|
||||
return len(nums) - l
|
||||
}
|
||||
|
||||
func translate(n, k, i int) int {
|
||||
if i < k {
|
||||
return n + i - k
|
||||
}
|
||||
return i - k
|
||||
}
|
||||
|
||||
func search(nums []int, target int) int {
|
||||
k := findK(nums)
|
||||
|
||||
l, r := 0, len(nums)
|
||||
for l < r {
|
||||
m := (l + r) / 2
|
||||
mt := translate(len(nums), k, m)
|
||||
if nums[mt] == target {
|
||||
return mt
|
||||
} else if nums[mt] > target {
|
||||
r = m
|
||||
} else {
|
||||
l = m + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
var _ = search
|
||||
26
solutions/0/q34/solution.go
Normal file
26
solutions/0/q34/solution.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package q34
|
||||
|
||||
func find(nums []int, target int) int {
|
||||
l, r := 0, len(nums)
|
||||
for l < r {
|
||||
m := (l + r) / 2
|
||||
switch {
|
||||
case nums[m] < target:
|
||||
l = m + 1
|
||||
default:
|
||||
r = m
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func searchRange(nums []int, target int) []int {
|
||||
pos := find(nums, target)
|
||||
if pos < 0 || pos >= len(nums) || nums[pos] != target {
|
||||
return []int{-1, -1}
|
||||
}
|
||||
pos2 := find(nums[pos:], target+1)
|
||||
return []int{pos, pos + pos2 - 1}
|
||||
}
|
||||
|
||||
var _ = searchRange
|
||||
30
solutions/0/q39/solution.go
Normal file
30
solutions/0/q39/solution.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package q39
|
||||
|
||||
import "slices"
|
||||
|
||||
func mkCombs(candidates []int, target int, buf []int, ret [][]int) [][]int {
|
||||
if target == 0 {
|
||||
cp := make([]int, len(buf))
|
||||
copy(cp, buf)
|
||||
return append(ret, buf)
|
||||
}
|
||||
if len(candidates) == 0 || candidates[0] > target {
|
||||
return ret
|
||||
}
|
||||
for i := 0; candidates[0]*i <= target; i++ {
|
||||
ret = mkCombs(candidates[1:], target-i*candidates[0], buf, ret)
|
||||
buf = append(buf, candidates[0])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func combinationSum(candidates []int, target int) [][]int {
|
||||
slices.Sort(candidates)
|
||||
|
||||
ret := make([][]int, 0, 150)
|
||||
buf := make([]int, target/candidates[0]+1)
|
||||
|
||||
return mkCombs(candidates, target, buf[:0], ret)
|
||||
}
|
||||
|
||||
var _ = combinationSum
|
||||
34
solutions/0/q46/solution.go
Normal file
34
solutions/0/q46/solution.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package q46
|
||||
|
||||
func recurse(nums []int, offset int, buf []int, seen []bool, ret [][]int) [][]int {
|
||||
if offset == len(nums) {
|
||||
a := make([]int, len(buf))
|
||||
copy(a, buf)
|
||||
return append(ret, a)
|
||||
}
|
||||
|
||||
for i := range nums {
|
||||
if seen[i] {
|
||||
continue
|
||||
}
|
||||
seen[i] = true
|
||||
buf[offset] = nums[i]
|
||||
ret = recurse(nums, offset+1, buf, seen, ret)
|
||||
seen[i] = false
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func permute(nums []int) [][]int {
|
||||
totalLen := 1
|
||||
for i := range len(nums) {
|
||||
totalLen *= i + 1
|
||||
}
|
||||
ret := make([][]int, 0, totalLen)
|
||||
buf := make([]int, len(nums))
|
||||
seen := make([]bool, len(nums))
|
||||
|
||||
return recurse(nums, 0, buf, seen, ret)
|
||||
}
|
||||
|
||||
var _ = permute
|
||||
21
solutions/0/q48/solution.go
Normal file
21
solutions/0/q48/solution.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package q48
|
||||
|
||||
func rotateCell(matrix [][]int, x, y int) {
|
||||
t := matrix[y][x]
|
||||
for range 4 {
|
||||
nextX, nextY := len(matrix)-1-y, x
|
||||
matrix[nextY][nextX], t = t, matrix[nextY][nextX]
|
||||
x, y = nextX, nextY
|
||||
}
|
||||
}
|
||||
|
||||
func rotate(matrix [][]int) {
|
||||
w := len(matrix)
|
||||
for y := range w / 2 {
|
||||
for x := y; x < w-y-1; x++ {
|
||||
rotateCell(matrix, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ = rotate
|
||||
22
solutions/0/q49/solution.go
Normal file
22
solutions/0/q49/solution.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package q49
|
||||
|
||||
import "slices"
|
||||
|
||||
func groupAnagrams(strs []string) [][]string {
|
||||
groups := map[string][]string{}
|
||||
|
||||
for i := range strs {
|
||||
byt := []byte(strs[i])
|
||||
slices.Sort(byt)
|
||||
sorted := string(byt)
|
||||
groups[sorted] = append(groups[sorted], strs[i])
|
||||
}
|
||||
|
||||
ret := make([][]string, 0, len(groups))
|
||||
for _, g := range groups {
|
||||
ret = append(ret, g)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = groupAnagrams
|
||||
40
solutions/0/q54/solution.go
Normal file
40
solutions/0/q54/solution.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package q54
|
||||
|
||||
import "math"
|
||||
|
||||
var dirs = [4][2]int{
|
||||
{1, 0}, // right
|
||||
{0, 1}, // down
|
||||
{-1, 0}, // left
|
||||
{0, -1}, // up
|
||||
}
|
||||
|
||||
const VISITED = math.MinInt
|
||||
|
||||
func spiralOrder(matrix [][]int) []int {
|
||||
w, h := len(matrix[0]), len(matrix)
|
||||
cnt := w * h
|
||||
ret := make([]int, cnt)
|
||||
|
||||
x, y := 0, 0
|
||||
dir := 0
|
||||
vect := dirs[dir]
|
||||
|
||||
for i := range cnt {
|
||||
ret[i] = matrix[y][x]
|
||||
matrix[y][x] = VISITED
|
||||
|
||||
// Can move?
|
||||
nextX, nextY := x+vect[0], y+vect[1]
|
||||
if nextX < 0 || nextY < 0 || nextX == w || nextY == h || matrix[nextY][nextX] == VISITED {
|
||||
dir = (dir + 1) % 4
|
||||
vect = dirs[dir]
|
||||
nextX, nextY = x+vect[0], y+vect[1]
|
||||
}
|
||||
x, y = nextX, nextY
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = spiralOrder
|
||||
30
solutions/0/q57/solution.go
Normal file
30
solutions/0/q57/solution.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package q57
|
||||
|
||||
func insert(intervals [][]int, newInterval []int) [][]int {
|
||||
ret := make([][]int, 0, len(intervals)+1)
|
||||
|
||||
i := 0
|
||||
for ; i < len(intervals) && intervals[i][0] <= newInterval[0]; i++ {
|
||||
ret = append(ret, intervals[i])
|
||||
}
|
||||
|
||||
if len(ret) > 0 && ret[len(ret)-1][1] >= newInterval[0] {
|
||||
ret[len(ret)-1][1] = max(ret[len(ret)-1][1], newInterval[1])
|
||||
} else {
|
||||
ret = append(ret, newInterval)
|
||||
}
|
||||
|
||||
for ; i < len(intervals); i++ {
|
||||
last := ret[len(ret)-1]
|
||||
next := intervals[i]
|
||||
if last[1] >= next[0] {
|
||||
last[1] = max(last[1], next[1])
|
||||
} else {
|
||||
ret = append(ret, next)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = insert
|
||||
27
solutions/0/q6/solution.go
Normal file
27
solutions/0/q6/solution.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package q6
|
||||
|
||||
import "strings"
|
||||
|
||||
func convert(s string, numRows int) string {
|
||||
loopLen := numRows + max(0, numRows-2)
|
||||
rows := make([][]byte, numRows)
|
||||
for i := range numRows {
|
||||
rows[i] = make([]byte, 0, (len(s)/loopLen+1)*2)
|
||||
}
|
||||
|
||||
for i := range len(s) {
|
||||
row := i % loopLen
|
||||
if row >= numRows {
|
||||
row = numRows - row%numRows - 2
|
||||
}
|
||||
rows[row] = append(rows[row], s[i])
|
||||
}
|
||||
|
||||
b := strings.Builder{}
|
||||
for i := range rows {
|
||||
_, _ = b.Write(rows[i])
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
var _ = convert
|
||||
35
solutions/0/q61/solution.go
Normal file
35
solutions/0/q61/solution.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package q61
|
||||
|
||||
type ListNode struct {
|
||||
Val int
|
||||
Next *ListNode
|
||||
}
|
||||
|
||||
func rotateRight(head *ListNode, k int) *ListNode {
|
||||
if head == nil {
|
||||
return nil
|
||||
}
|
||||
n := 1
|
||||
p := head
|
||||
for p.Next != nil {
|
||||
p = p.Next
|
||||
n++
|
||||
}
|
||||
tail := p
|
||||
|
||||
k %= n
|
||||
if k == 0 {
|
||||
return head
|
||||
}
|
||||
|
||||
tail.Next = head
|
||||
p = head
|
||||
for range n - k - 1 {
|
||||
p = p.Next
|
||||
}
|
||||
newHead := p.Next
|
||||
p.Next = nil
|
||||
return newHead
|
||||
}
|
||||
|
||||
var _ = rotateRight
|
||||
21
solutions/0/q64/solution.go
Normal file
21
solutions/0/q64/solution.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package q64
|
||||
|
||||
func minPathSum(grid [][]int) int {
|
||||
w, h := len(grid[0]), len(grid)
|
||||
|
||||
for y := 1; y < h; y++ {
|
||||
grid[y][0] += grid[y-1][0]
|
||||
}
|
||||
for x := 1; x < w; x++ {
|
||||
grid[0][x] += grid[0][x-1]
|
||||
}
|
||||
|
||||
for y := 1; y < h; y++ {
|
||||
for x := 1; x < w; x++ {
|
||||
grid[y][x] += min(grid[y-1][x], grid[y][x-1])
|
||||
}
|
||||
}
|
||||
return grid[h-1][w-1]
|
||||
}
|
||||
|
||||
var _ = minPathSum
|
||||
32
solutions/0/q71/solution.go
Normal file
32
solutions/0/q71/solution.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package q71
|
||||
|
||||
import "strings"
|
||||
|
||||
func simplifyPath(path string) string {
|
||||
b := strings.Builder{}
|
||||
fields := strings.FieldsFunc(path, func(r rune) bool { return r == '/' })
|
||||
|
||||
p := 0
|
||||
for i := range fields {
|
||||
switch fields[i] {
|
||||
case ".":
|
||||
continue
|
||||
case "..":
|
||||
p = max(p-1, 0)
|
||||
default:
|
||||
fields[p] = fields[i]
|
||||
p++
|
||||
}
|
||||
}
|
||||
for i := range p {
|
||||
b.WriteByte('/')
|
||||
b.WriteString(fields[i])
|
||||
}
|
||||
|
||||
if p == 0 {
|
||||
return "/"
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
var _ = simplifyPath
|
||||
24
solutions/0/q73/solution.go
Normal file
24
solutions/0/q73/solution.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package q73
|
||||
|
||||
func setZeroes(matrix [][]int) {
|
||||
zRows := make([]bool, len(matrix))
|
||||
zCols := make([]bool, len(matrix[0]))
|
||||
for r := range matrix {
|
||||
for c := range matrix[0] {
|
||||
if matrix[r][c] == 0 {
|
||||
zRows[r] = true
|
||||
zCols[c] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for r := range matrix {
|
||||
for c := range matrix[0] {
|
||||
if zRows[r] || zCols[c] {
|
||||
matrix[r][c] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ = setZeroes
|
||||
51
solutions/0/q77/solution.go
Normal file
51
solutions/0/q77/solution.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package q77
|
||||
|
||||
var (
|
||||
allocBuf []int
|
||||
allocP int
|
||||
)
|
||||
|
||||
func alloc(sz int) []int {
|
||||
if allocBuf == nil || allocP+sz > 8192 {
|
||||
allocP = 0
|
||||
allocBuf = make([]int, 8192)
|
||||
}
|
||||
ret := allocBuf[allocP : allocP+sz]
|
||||
allocP += sz
|
||||
return ret
|
||||
}
|
||||
|
||||
func combine(n int, k int) [][]int {
|
||||
buf := alloc(k)
|
||||
for i := range buf {
|
||||
buf[i] = i + 1
|
||||
}
|
||||
|
||||
sz := 1
|
||||
for i := 1; i <= k; i++ {
|
||||
sz = sz * (n - i + 1) / i
|
||||
}
|
||||
ret := make([][]int, 0, sz)
|
||||
for {
|
||||
t := alloc(k)
|
||||
copy(t, buf)
|
||||
ret = append(ret, t)
|
||||
|
||||
if buf[0] == n-k+1 {
|
||||
break
|
||||
}
|
||||
|
||||
buf[k-1]++
|
||||
i := k - 1
|
||||
for ; i > 0 && buf[i] > n-(k-1-i); i-- {
|
||||
buf[i-1]++
|
||||
}
|
||||
for i++; i < k; i++ {
|
||||
buf[i] = buf[i-1] + 1
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = combine
|
||||
61
solutions/0/q79/solution.go
Normal file
61
solutions/0/q79/solution.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package q79
|
||||
|
||||
func search(board [][]byte, word string, prefixLen, row, col int) bool {
|
||||
if row < 0 || col < 0 || row >= len(board) || col >= len(board[0]) {
|
||||
return false
|
||||
}
|
||||
if word[prefixLen] != board[row][col] {
|
||||
return false
|
||||
}
|
||||
if prefixLen+1 == len(word) {
|
||||
return true
|
||||
}
|
||||
|
||||
c := board[row][col]
|
||||
board[row][col] = '#'
|
||||
yes := false ||
|
||||
search(board, word, prefixLen+1, row, col+1) ||
|
||||
search(board, word, prefixLen+1, row, col-1) ||
|
||||
search(board, word, prefixLen+1, row+1, col) ||
|
||||
search(board, word, prefixLen+1, row-1, col)
|
||||
|
||||
board[row][col] = c
|
||||
return yes
|
||||
}
|
||||
|
||||
func exist(board [][]byte, word string) bool {
|
||||
w, h := len(board[0]), len(board)
|
||||
if len(word) > w*h {
|
||||
return false
|
||||
}
|
||||
charFreq := make([]int, 26*2)
|
||||
idx := func(b byte) byte {
|
||||
if b >= 'a' {
|
||||
return b - 'a' + 26
|
||||
}
|
||||
return b - 'A'
|
||||
}
|
||||
for row := range board {
|
||||
for col := range board[0] {
|
||||
charFreq[idx(board[row][col])]++
|
||||
}
|
||||
}
|
||||
for i := range len(word) {
|
||||
ii := idx(word[i])
|
||||
charFreq[ii]--
|
||||
if charFreq[ii] < 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for row := range board {
|
||||
for col := range board[0] {
|
||||
if search(board, word, 0, row, col) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var _ = exist
|
||||
30
solutions/0/q86/solution.go
Normal file
30
solutions/0/q86/solution.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package q86
|
||||
|
||||
type ListNode struct {
|
||||
Val int
|
||||
Next *ListNode
|
||||
}
|
||||
|
||||
func partition(head *ListNode, x int) *ListNode {
|
||||
stub := &ListNode{Next: head}
|
||||
before := stub
|
||||
for before.Next != nil && before.Next.Val < x {
|
||||
before = before.Next
|
||||
}
|
||||
|
||||
for p := before.Next; p != nil && p.Next != nil; {
|
||||
if p.Next.Val < x {
|
||||
move := p.Next
|
||||
p.Next = move.Next
|
||||
|
||||
move.Next = before.Next
|
||||
before.Next = move
|
||||
before = move
|
||||
} else {
|
||||
p = p.Next
|
||||
}
|
||||
}
|
||||
return stub.Next
|
||||
}
|
||||
|
||||
var _ = partition
|
||||
25
solutions/0/q92/solution.go
Normal file
25
solutions/0/q92/solution.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package q92
|
||||
|
||||
type ListNode struct {
|
||||
Val int
|
||||
Next *ListNode
|
||||
}
|
||||
|
||||
func reverseBetween(head *ListNode, left int, right int) *ListNode {
|
||||
stub := &ListNode{Next: head}
|
||||
before := stub
|
||||
for range left - 1 {
|
||||
before = before.Next
|
||||
}
|
||||
|
||||
curr := before.Next
|
||||
for range right - left {
|
||||
move := curr.Next
|
||||
curr.Next = move.Next
|
||||
move.Next = before.Next
|
||||
before.Next = move
|
||||
}
|
||||
return stub.Next
|
||||
}
|
||||
|
||||
var _ = reverseBetween
|
||||
39
solutions/0/q98/solution.go
Normal file
39
solutions/0/q98/solution.go
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package q98
|
||||
|
||||
type TreeNode struct {
|
||||
Val int
|
||||
Left *TreeNode
|
||||
Right *TreeNode
|
||||
}
|
||||
|
||||
func isValid(node *TreeNode) (bool, int, int) {
|
||||
if node.Left == nil && node.Right == nil {
|
||||
return true, node.Val, node.Val
|
||||
}
|
||||
|
||||
minv, maxv := node.Val, node.Val
|
||||
|
||||
if node.Left != nil {
|
||||
valid, lmin, lmax := isValid(node.Left)
|
||||
if !valid || lmax >= node.Val {
|
||||
return false, 0, 0
|
||||
}
|
||||
minv = lmin
|
||||
}
|
||||
if node.Right != nil {
|
||||
valid, rmin, rmax := isValid(node.Right)
|
||||
if !valid || rmin <= node.Val {
|
||||
return false, 0, 0
|
||||
}
|
||||
maxv = rmax
|
||||
}
|
||||
|
||||
return true, minv, maxv
|
||||
}
|
||||
|
||||
func isValidBST(root *TreeNode) bool {
|
||||
valid, _, _ := isValid(root)
|
||||
return valid
|
||||
}
|
||||
|
||||
var _ = isValidBST
|
||||
27
solutions/1/q128/solution.go
Normal file
27
solutions/1/q128/solution.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package q128
|
||||
|
||||
func longestConsecutive(nums []int) int {
|
||||
set := make(map[int]struct{}, len(nums))
|
||||
for _, n := range nums {
|
||||
set[n] = struct{}{}
|
||||
}
|
||||
|
||||
longest := 0
|
||||
for n := range set {
|
||||
if _, ok := set[n-1]; ok {
|
||||
continue
|
||||
}
|
||||
r := n
|
||||
for {
|
||||
if _, ok := set[r+1]; ok {
|
||||
r++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
longest = max(longest, r-n+1)
|
||||
}
|
||||
return longest
|
||||
}
|
||||
|
||||
var _ = longestConsecutive
|
||||
37
solutions/1/q130/solution.go
Normal file
37
solutions/1/q130/solution.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package q130
|
||||
|
||||
func markI(board [][]byte, x, y int) {
|
||||
w, h := len(board[0]), len(board)
|
||||
if x < 0 || y < 0 || x >= w || y >= h || board[y][x] != 'O' {
|
||||
return
|
||||
}
|
||||
board[y][x] = 'I'
|
||||
markI(board, x, y+1)
|
||||
markI(board, x, y-1)
|
||||
markI(board, x+1, y)
|
||||
markI(board, x-1, y)
|
||||
}
|
||||
|
||||
func solve(board [][]byte) {
|
||||
for i := range len(board) {
|
||||
markI(board, 0, i)
|
||||
markI(board, len(board[0])-1, i)
|
||||
}
|
||||
for i := range len(board[0]) {
|
||||
markI(board, i, 0)
|
||||
markI(board, i, len(board)-1)
|
||||
}
|
||||
|
||||
for y := range board {
|
||||
for x := range board[0] {
|
||||
switch board[y][x] {
|
||||
case 'O':
|
||||
board[y][x] = 'X'
|
||||
case 'I':
|
||||
board[y][x] = 'O'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ = solve
|
||||
34
solutions/1/q138/solution.go
Normal file
34
solutions/1/q138/solution.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package q138
|
||||
|
||||
type Node struct {
|
||||
Val int
|
||||
Next *Node
|
||||
Random *Node
|
||||
}
|
||||
|
||||
func copyRandomList(head *Node) *Node {
|
||||
idx := make(map[*Node]*Node, 256)
|
||||
|
||||
p := head
|
||||
for p != nil {
|
||||
newNode := *p // copy
|
||||
idx[p] = &newNode
|
||||
p = p.Next
|
||||
}
|
||||
|
||||
p = head
|
||||
for p != nil {
|
||||
newNode := idx[p]
|
||||
if newNode.Next != nil {
|
||||
newNode.Next = idx[newNode.Next]
|
||||
}
|
||||
if newNode.Random != nil {
|
||||
newNode.Random = idx[newNode.Random]
|
||||
}
|
||||
p = p.Next
|
||||
}
|
||||
|
||||
return idx[head]
|
||||
}
|
||||
|
||||
var _ = copyRandomList
|
||||
28
solutions/1/q139/solution.go
Normal file
28
solutions/1/q139/solution.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package q139
|
||||
|
||||
func wordBreak(s string, wordDict []string) bool {
|
||||
possible := make([]bool, len(s)+1)
|
||||
possible[0] = true
|
||||
|
||||
for l := range possible {
|
||||
if !possible[l] {
|
||||
continue
|
||||
}
|
||||
for i := range wordDict {
|
||||
newLen := len(wordDict[i]) + l
|
||||
if newLen > len(s) {
|
||||
continue
|
||||
}
|
||||
if possible[newLen] {
|
||||
continue
|
||||
}
|
||||
if s[l:newLen] == wordDict[i] {
|
||||
possible[newLen] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return possible[len(s)]
|
||||
}
|
||||
|
||||
var _ = wordBreak
|
||||
18
solutions/1/q153/solution.go
Normal file
18
solutions/1/q153/solution.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package q153
|
||||
|
||||
func findMin(nums []int) int {
|
||||
l, r := 0, len(nums)
|
||||
|
||||
for l < r && nums[l] > nums[r-1] {
|
||||
m := (l + r) / 2
|
||||
if nums[m] > nums[r-1] {
|
||||
l = m + 1
|
||||
} else {
|
||||
r = m + 1
|
||||
l++
|
||||
}
|
||||
}
|
||||
return nums[l]
|
||||
}
|
||||
|
||||
var _ = findMin
|
||||
24
solutions/1/q162/solution.go
Normal file
24
solutions/1/q162/solution.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package q162
|
||||
|
||||
// Important constraint: nums[i] != nums[i + 1]
|
||||
|
||||
func findPeakElement(nums []int) int {
|
||||
l, r := 0, len(nums)
|
||||
for l < r {
|
||||
m := (l + r) / 2
|
||||
|
||||
lLower := m == 0 || nums[m-1] < nums[m]
|
||||
rLower := m == len(nums)-1 || nums[m+1] < nums[m]
|
||||
if lLower && rLower {
|
||||
return m
|
||||
}
|
||||
if !lLower { // left side is higher
|
||||
r = m
|
||||
} else {
|
||||
l = m + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
var _ = findPeakElement
|
||||
63
solutions/2/q211/solution.go
Normal file
63
solutions/2/q211/solution.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
package q211
|
||||
|
||||
type TrieNode struct {
|
||||
word bool
|
||||
next [26]*TrieNode
|
||||
}
|
||||
|
||||
func (n *TrieNode) hasMatch(pattern string, offset int) bool {
|
||||
if n == nil {
|
||||
return false
|
||||
}
|
||||
if offset == len(pattern) {
|
||||
return n.word
|
||||
}
|
||||
|
||||
c := pattern[offset]
|
||||
if c != '.' {
|
||||
return n.next[toIdx(c)].hasMatch(pattern, offset+1)
|
||||
}
|
||||
|
||||
// Wildcard character
|
||||
for _, t := range n.next {
|
||||
if t != nil && t.hasMatch(pattern, offset+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func toIdx(b byte) int8 { return int8(b - 'a') }
|
||||
|
||||
type WordDictionary struct{ root *TrieNode }
|
||||
|
||||
func Constructor() WordDictionary {
|
||||
return WordDictionary{
|
||||
root: &TrieNode{},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *WordDictionary) AddWord(word string) {
|
||||
curr := d.root
|
||||
for i := range len(word) {
|
||||
c := word[i]
|
||||
idx := toIdx(c)
|
||||
if curr.next[idx] == nil {
|
||||
curr.next[idx] = &TrieNode{}
|
||||
}
|
||||
curr = curr.next[idx]
|
||||
}
|
||||
curr.word = true
|
||||
}
|
||||
|
||||
func (d *WordDictionary) Search(word string) bool {
|
||||
return d.root.hasMatch(word, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Your WordDictionary object will be instantiated and called as such:
|
||||
* obj := Constructor();
|
||||
* obj.AddWord(word);
|
||||
* param_2 := obj.Search(word);
|
||||
*/
|
||||
31
solutions/2/q236/solution.go
Normal file
31
solutions/2/q236/solution.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package q236
|
||||
|
||||
type TreeNode struct {
|
||||
Val int
|
||||
Left *TreeNode
|
||||
Right *TreeNode
|
||||
}
|
||||
|
||||
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
|
||||
if root == nil {
|
||||
return nil
|
||||
}
|
||||
if root == p || root == q {
|
||||
return root
|
||||
}
|
||||
|
||||
l := lowestCommonAncestor(root.Left, p, q)
|
||||
r := lowestCommonAncestor(root.Right, p, q)
|
||||
|
||||
switch {
|
||||
case l == nil && r == nil:
|
||||
return nil
|
||||
case l != nil && r != nil:
|
||||
return root
|
||||
case l != nil:
|
||||
return l
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
var _ = lowestCommonAncestor
|
||||
50
solutions/29/q2975/solution.go
Normal file
50
solutions/29/q2975/solution.go
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package q2975
|
||||
|
||||
import "slices"
|
||||
|
||||
func maximizeSquareArea(m int, n int, hFences []int, vFences []int) int {
|
||||
slices.Sort(hFences)
|
||||
slices.Sort(vFences)
|
||||
nHFences := len(hFences) + 2
|
||||
|
||||
lengths := make(map[int]struct{}, nHFences*(nHFences-1)/2)
|
||||
for i := -1; i < len(hFences); i++ {
|
||||
a := 1
|
||||
if i >= 0 {
|
||||
a = hFences[i]
|
||||
}
|
||||
for j := i + 1; j <= len(hFences); j++ {
|
||||
b := m
|
||||
if j < len(hFences) {
|
||||
b = hFences[j]
|
||||
}
|
||||
lengths[b-a] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
maxEdge := -1
|
||||
for i := -1; i < len(vFences); i++ {
|
||||
a := 1
|
||||
if i >= 0 {
|
||||
a = vFences[i]
|
||||
}
|
||||
for j := i + 1; j <= len(vFences); j++ {
|
||||
b := n
|
||||
if j < len(vFences) {
|
||||
b = vFences[j]
|
||||
}
|
||||
|
||||
if _, ok := lengths[b-a]; ok {
|
||||
maxEdge = max(maxEdge, b-a)
|
||||
}
|
||||
}
|
||||
}
|
||||
if maxEdge == -1 {
|
||||
return -1
|
||||
}
|
||||
|
||||
maxEdge %= 1e9 + 7
|
||||
return (maxEdge * maxEdge) % (1e9 + 7)
|
||||
}
|
||||
|
||||
var _ = maximizeSquareArea
|
||||
21
solutions/3/q300/solution.go
Normal file
21
solutions/3/q300/solution.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package q300
|
||||
|
||||
func lengthOfLIS(nums []int) int {
|
||||
maxSeqLen := make([]int, len(nums))
|
||||
maxSeqLen[0] = 1
|
||||
globalMax := 1
|
||||
|
||||
for i := 1; i < len(nums); i++ {
|
||||
locMax := 0
|
||||
for j := 0; j < i; j++ {
|
||||
if nums[j] < nums[i] {
|
||||
locMax = max(locMax, maxSeqLen[j])
|
||||
}
|
||||
}
|
||||
maxSeqLen[i] = locMax + 1
|
||||
globalMax = max(globalMax, maxSeqLen[i])
|
||||
}
|
||||
return globalMax
|
||||
}
|
||||
|
||||
var _ = lengthOfLIS
|
||||
42
solutions/30/q3047/solution.go
Normal file
42
solutions/30/q3047/solution.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package q3047
|
||||
|
||||
import "slices"
|
||||
|
||||
func intersectingSquareArea(bl1, tr1, bl2, tr2 []int) int64 {
|
||||
l1, r1, l2, r2 := bl1[0], tr1[0], bl2[0], tr2[0]
|
||||
iW := max(0, min(r1, r2)-max(l1, l2))
|
||||
|
||||
l1, r1, l2, r2 = bl1[1], tr1[1], bl2[1], tr2[1]
|
||||
iH := max(0, min(r1, r2)-max(l1, l2))
|
||||
|
||||
edge := min(iW, iH)
|
||||
return int64(edge * edge)
|
||||
}
|
||||
|
||||
func largestSquareArea(bottomLeft [][]int, topRight [][]int) int64 {
|
||||
squares := make([]int, len(bottomLeft))
|
||||
for i := range squares {
|
||||
squares[i] = i
|
||||
}
|
||||
slices.SortFunc(squares, // bottom-up order
|
||||
func(a, b int) int { return bottomLeft[a][1] - bottomLeft[b][1] })
|
||||
|
||||
var largest int64
|
||||
|
||||
for i := range squares {
|
||||
for j := i + 1; j < len(squares); j++ {
|
||||
yI, yJ := topRight[squares[i]][1], bottomLeft[squares[j]][1]
|
||||
if yJ >= yI {
|
||||
break
|
||||
}
|
||||
|
||||
largest = max(largest, intersectingSquareArea(
|
||||
bottomLeft[squares[i]], topRight[squares[i]],
|
||||
bottomLeft[squares[j]], topRight[squares[j]],
|
||||
))
|
||||
}
|
||||
}
|
||||
return largest
|
||||
}
|
||||
|
||||
var _ = largestSquareArea
|
||||
44
solutions/4/q427/solution.go
Normal file
44
solutions/4/q427/solution.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package q427
|
||||
|
||||
type Node struct {
|
||||
Val bool
|
||||
IsLeaf bool
|
||||
TopLeft *Node
|
||||
TopRight *Node
|
||||
BottomLeft *Node
|
||||
BottomRight *Node
|
||||
}
|
||||
|
||||
func mkTree(grid [][]int, x, y, w int) *Node {
|
||||
if w == 1 {
|
||||
return &Node{
|
||||
Val: grid[y][x] == 1,
|
||||
IsLeaf: true,
|
||||
}
|
||||
}
|
||||
|
||||
subtreeW := w / 2
|
||||
node := &Node{
|
||||
TopLeft: mkTree(grid, x, y, subtreeW),
|
||||
TopRight: mkTree(grid, x+subtreeW, y, subtreeW),
|
||||
BottomLeft: mkTree(grid, x, y+subtreeW, subtreeW),
|
||||
BottomRight: mkTree(grid, x+subtreeW, y+subtreeW, subtreeW),
|
||||
}
|
||||
if !node.TopLeft.IsLeaf || !node.TopRight.IsLeaf || !node.BottomLeft.IsLeaf || !node.BottomRight.IsLeaf {
|
||||
return node
|
||||
}
|
||||
if node.TopLeft.Val && node.TopRight.Val && node.BottomLeft.Val && node.BottomRight.Val ||
|
||||
!node.TopLeft.Val && !node.TopRight.Val && !node.BottomLeft.Val && !node.BottomRight.Val {
|
||||
return &Node{
|
||||
Val: node.TopLeft.Val,
|
||||
IsLeaf: true,
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func construct(grid [][]int) *Node {
|
||||
return mkTree(grid, 0, 0, len(grid))
|
||||
}
|
||||
|
||||
var _ = construct
|
||||
66
solutions/9/q986/solution.go
Normal file
66
solutions/9/q986/solution.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package q986
|
||||
|
||||
import "slices"
|
||||
|
||||
type listElem struct {
|
||||
x int
|
||||
listId int8 // 0, 1
|
||||
isStart bool
|
||||
}
|
||||
|
||||
func intervalIntersection(firstList [][]int, secondList [][]int) [][]int {
|
||||
locations := make([]listElem, 0, len(firstList)*2+len(secondList)*2)
|
||||
|
||||
for i := range firstList {
|
||||
locations = append(
|
||||
locations,
|
||||
listElem{x: firstList[i][0], listId: 0, isStart: true},
|
||||
listElem{x: firstList[i][1], listId: 0, isStart: false},
|
||||
)
|
||||
}
|
||||
for i := range secondList {
|
||||
locations = append(
|
||||
locations,
|
||||
listElem{x: secondList[i][0], listId: 1, isStart: true},
|
||||
listElem{x: secondList[i][1], listId: 1, isStart: false},
|
||||
)
|
||||
}
|
||||
slices.SortFunc(locations, func(a, b listElem) int {
|
||||
if a.x != b.x {
|
||||
return a.x - b.x
|
||||
}
|
||||
if a.isStart {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
})
|
||||
|
||||
ret := [][]int{}
|
||||
start := 0
|
||||
isA, isB := false, false
|
||||
for _, loc := range locations {
|
||||
if loc.isStart {
|
||||
start = loc.x
|
||||
switch loc.listId {
|
||||
case 0:
|
||||
isA = true
|
||||
default:
|
||||
isB = true
|
||||
}
|
||||
} else {
|
||||
if isA && isB {
|
||||
ret = append(ret, []int{start, loc.x})
|
||||
}
|
||||
switch loc.listId {
|
||||
case 0:
|
||||
isA = false
|
||||
default:
|
||||
isB = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = intervalIntersection
|
||||
Loading…
Add table
Add a link
Reference in a new issue