diff --git a/solutions/0/q1/solution.go b/solutions/0/q1/solution.go new file mode 100644 index 0000000..72db61f --- /dev/null +++ b/solutions/0/q1/solution.go @@ -0,0 +1,22 @@ +package q1 + +import "slices" + +func twoSum(nums []int, target int) []int { + pointers := make([]int, len(nums)) + for i := range pointers { + pointers[i] = i + } + + slices.SortFunc(pointers, func(a, b int) int { return nums[a] - nums[b] }) + for l, r := 0, len(pointers)-1; l < r; l++ { + for ; l < r-1 && nums[pointers[l]]+nums[pointers[r]] > target; r-- { + } + if nums[pointers[l]]+nums[pointers[r]] == target { + return []int{pointers[l], pointers[r]} + } + } + return nil +} + +var _ = twoSum diff --git a/solutions/0/q13/solution.go b/solutions/0/q13/solution.go new file mode 100644 index 0000000..b281763 --- /dev/null +++ b/solutions/0/q13/solution.go @@ -0,0 +1,37 @@ +package q13 + +func lookup(b byte) int { + switch b { + case 'I': + return 1 + case 'V': + return 5 + case 'X': + return 10 + case 'L': + return 50 + case 'C': + return 100 + case 'D': + return 500 + case 'M': + return 1000 + } + return 0 +} + +func romanToInt(s string) int { + num := 0 + prev := 0 + for i := range len(s) { + cur := lookup(s[i]) + num += cur + if prev < cur { + num -= prev + prev + } + prev = cur + } + return num +} + +var _ = romanToInt diff --git a/solutions/0/q21/solution.go b/solutions/0/q21/solution.go new file mode 100644 index 0000000..79cb325 --- /dev/null +++ b/solutions/0/q21/solution.go @@ -0,0 +1,36 @@ +package q21 + +type ListNode struct { + Val int + Next *ListNode +} + +func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { + root := &ListNode{} + cur := root + + for { + if list1 == nil && list2 == nil { + return root.Next + } + if list1 == nil { + cur.Next = list2 + return root.Next + } else if list2 == nil { + cur.Next = list1 + return root.Next + } else if list1.Val < list2.Val { + cur.Next = list1 + cur = cur.Next + list1 = list1.Next + cur.Next = nil + } else { + cur.Next = list2 + cur = cur.Next + list2 = list2.Next + cur.Next = nil + } + } +} + +var _ = mergeTwoLists diff --git a/solutions/1/q100/solution.go b/solutions/1/q100/solution.go new file mode 100644 index 0000000..255748e --- /dev/null +++ b/solutions/1/q100/solution.go @@ -0,0 +1,27 @@ +package q100 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func traverse(p, q *TreeNode) bool { + if p == nil && q == nil { + return true + } + if p == nil || q == nil { + return false + } + if p.Val != q.Val { + return false + } + return traverse(p.Left, q.Left) && + traverse(p.Right, q.Right) +} + +func isSameTree(p *TreeNode, q *TreeNode) bool { + return traverse(p, q) +} + +var _ = isSameTree diff --git a/solutions/1/q101/solution.go b/solutions/1/q101/solution.go new file mode 100644 index 0000000..062ca32 --- /dev/null +++ b/solutions/1/q101/solution.go @@ -0,0 +1,27 @@ +package q101 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func traverse(left, right *TreeNode) bool { + if left == nil && right == nil { + return true + } + if left == nil || right == nil { + return false + } + if left.Val != right.Val { + return false + } + return traverse(left.Left, right.Right) && + traverse(left.Right, right.Left) +} + +func isSymmetric(root *TreeNode) bool { + return traverse(root.Left, root.Right) +} + +var _ = isSymmetric diff --git a/solutions/1/q112/solution.go b/solutions/1/q112/solution.go new file mode 100644 index 0000000..5571d73 --- /dev/null +++ b/solutions/1/q112/solution.go @@ -0,0 +1,26 @@ +package q112 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func traverse(node *TreeNode, tgtSum, curSum int) bool { + if node == nil { + return false + } + + sum := curSum + node.Val + if node.Left == nil && node.Right == nil && sum == tgtSum { + return true + } + return traverse(node.Left, tgtSum, sum) || + traverse(node.Right, tgtSum, sum) +} + +func hasPathSum(root *TreeNode, targetSum int) bool { + return traverse(root, targetSum, 0) +} + +var _ = hasPathSum diff --git a/solutions/13/q1351/solution.go b/solutions/13/q1351/solution.go new file mode 100644 index 0000000..823d8c3 --- /dev/null +++ b/solutions/13/q1351/solution.go @@ -0,0 +1,17 @@ +package q1351 + +func countNegatives(grid [][]int) int { + w := len(grid[0]) + count := 0 + + countRow := 0 + for r := range grid { + for countRow < w && (grid[r][w-countRow-1] < 0) { + countRow++ + } + count += countRow + } + return count +} + +var _ = countNegatives diff --git a/solutions/2/q205/solution.go b/solutions/2/q205/solution.go new file mode 100644 index 0000000..aea8514 --- /dev/null +++ b/solutions/2/q205/solution.go @@ -0,0 +1,26 @@ +package q205 + +func isIsomorphic(s string, t string) bool { + if len(s) != len(t) { + return false + } + + ab := make(map[byte]byte, 256) + ba := make(map[byte]byte, 256) + for i := range len(s) { + if b, ok := ab[s[i]]; ok { + if t[i] != b { + return false + } + } else { + if _, ok := ba[t[i]]; ok { + return false + } + ab[s[i]] = t[i] + ba[t[i]] = s[i] + } + } + return true +} + +var _ = isIsomorphic diff --git a/solutions/2/q219/solution.go b/solutions/2/q219/solution.go new file mode 100644 index 0000000..86b96d8 --- /dev/null +++ b/solutions/2/q219/solution.go @@ -0,0 +1,18 @@ +package q219 + +func containsNearbyDuplicate(nums []int, k int) bool { + seen := make(map[int]struct{}, k) + + for i, num := range nums { + if _, ok := seen[num]; ok { + return true + } + seen[num] = struct{}{} + if i >= k { + delete(seen, nums[i-k]) + } + } + return false +} + +var _ = containsNearbyDuplicate diff --git a/solutions/2/q290/solution.go b/solutions/2/q290/solution.go new file mode 100644 index 0000000..8f29154 --- /dev/null +++ b/solutions/2/q290/solution.go @@ -0,0 +1,30 @@ +package q290 + +import "strings" + +func wordPattern(pattern string, s string) bool { + index := map[byte]string{} + invIndex := map[string]struct{}{} + + fields := strings.Fields(s) + if len(fields) != len(pattern) { + return false + } + + for i, word := range fields { + if w, ok := index[pattern[i]]; ok { + if w != word { + return false + } + } else { + if _, ok := invIndex[word]; ok { + return false + } + index[pattern[i]] = word + invIndex[word] = struct{}{} + } + } + return true +} + +var _ = wordPattern diff --git a/solutions/24/q2402/solution.go b/solutions/24/q2402/solution.go new file mode 100644 index 0000000..c95acc6 --- /dev/null +++ b/solutions/24/q2402/solution.go @@ -0,0 +1,77 @@ +package q2402 + +import ( + "container/heap" + "slices" +) + +type Room struct { + id int + meetingStart int + meetingEnd int +} + +type Rooms []Room + +func (r *Rooms) Len() int { return len(*r) } +func (r *Rooms) Push(x any) { (*r) = append((*r), x.(Room)) } +func (r *Rooms) Swap(i int, j int) { (*r)[i], (*r)[j] = (*r)[j], (*r)[i] } + +func (r *Rooms) Less(i int, j int) bool { + if (*r)[i].meetingEnd == (*r)[j].meetingEnd { + return (*r)[i].id < (*r)[j].id + } + return (*r)[i].meetingEnd < (*r)[j].meetingEnd +} + +func (r *Rooms) Pop() any { + last := len(*r) - 1 + ret := (*r)[last] + *r = (*r)[:last] + return ret +} + +func mostBooked(n int, meetings [][]int) int { + timesBooked := make([]int, n) + empty := make(Rooms, n) + for i := range empty { + empty[i] = Room{id: i} + } + inUse := make(Rooms, 0, n) + + slices.SortFunc(meetings, func(a, b []int) int { return a[0] - b[0] }) + for i := range meetings { + start, end := meetings[i][0], meetings[i][1] + for len(inUse) > 0 && inUse[0].meetingEnd <= start { + heap.Push(&empty, Room{id: inUse[0].id}) + heap.Pop(&inUse) + } + + if len(empty) > 0 { + id := empty[0].id + timesBooked[id]++ + heap.Push(&inUse, Room{ + id: id, + meetingStart: start, + meetingEnd: end, + }) + heap.Pop(&empty) + } else { + room := &inUse[0] + timesBooked[room.id]++ + room.meetingStart, room.meetingEnd = room.meetingEnd, end-start+room.meetingEnd + heap.Fix(&inUse, 0) + } + } + + mb, mbIdx := timesBooked[0], 0 + for i := 1; i < len(timesBooked); i++ { + if timesBooked[i] > mb { + mb, mbIdx = timesBooked[i], i + } + } + return mbIdx +} + +var _ heap.Interface = &Rooms{} +var _ = mostBooked