Documenting LeetCode solving.
Q66
Hard. Max Queue
type MotionicQueue struct {
maxq []int
}
// Smash items that are smaller and before
func (mq *MotionicQueue) push(x int) {
for len(mq.maxq) > 0 && mq.maxq[len(mq.maxq) - 1] < x {
mq.maxq = mq.maxq[:len(mq.maxq) - 1]
}
mq.maxq = append(mq.maxq, x)
}
// Only check the item if it equals to the first item in the max queue
// (If it doesn't, it has been smashed already)
func (mq *MotionicQueue) pop(x int) {
if mq.maxq[0] == x {
mq.maxq = mq.maxq[1:]
}
}
func (mq *MotionicQueue) max() int {
return mq.maxq[0]
}
func maxSlidingWindow(nums []int, k int) []int {
window := MotionicQueue{maxq: []int{}}
res := []int{}
for i := 0; i < len(nums); i++ {
if i < k - 1 {
window.push(nums[i])
} else {
window.push(nums[i])
res = append(res, window.max())
window.pop(nums[i - k + 1])
}
}
return res
}
Q67
387. First Unique Character in a String
Easy. Hashmap
func firstUniqChar(s string) int {
count := make(map[rune]int)
// count := map[rune]int{}
for _, c := range s {
count[c]++
}
for i, c := range s {
if count[c] == 1 {
return i
}
}
return -1
}
Q68
295. Find Median from Data Stream
Hard.
Two heaps: min and max heap.
Data stream
// Implement a min heap
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) Peek() int {return h[0]}
func (h *MinHeap) Push(x interface{}) {*h = append(*h, x.(int))}
func (h *MinHeap) Pop() interface{} {
res := (*h)[len(*h) - 1]
*h = (*h)[:len(*h) - 1]
return res
}
type MedianFinder struct {
small *MinHeap
large *MinHeap
}
func Constructor() MedianFinder {
small := make(MinHeap, 0)
heap.Init(&small)
large := make(MinHeap, 0)
heap.Init(&large)
return MedianFinder{&small, &large}
}
func (this *MedianFinder) AddNum(num int) {
// Push negative item into small -> max heap
heap.Push(this.small, -1 * num)
// make sure items in the small heap are smaller then the large heap
if this.small.Len() != 0 && this.large.Len() != 0 && (-1 * this.small.Peek()) > this.large.Peek() {
val := heap.Pop(this.small)
heap.Push(this.large, -1 * val.(int))
}
// make the two heaps even
if this.small.Len() > this.large.Len() + 1 {
val := heap.Pop(this.small)
heap.Push(this.large, -1 * val.(int))
}
if this.large.Len() > this.small.Len() + 1 {
val := heap.Pop(this.large)
heap.Push(this.small, -1 * val.(int))
}
}
func (this *MedianFinder) FindMedian() float64 {
if this.small.Len() > this.large.Len() {
return float64(-1 * this.small.Peek())
}
if this.large.Len() > this.small.Len() {
return float64(this.large.Peek())
}
return float64(((-1 * this.small.Peek()) + this.large.Peek())) / 2
}
Q69
Moving Average from Data Stream
Easy. Queue, data stream
package main
import "fmt"
type MovingAverage struct {
q []int
size int
sum int
}
func constuctor(size int) MovingAverage {
return MovingAverage{
// initialize capasity = size for better efficiency
q: make([]int, 0, size),
size: size,
sum: 0,
}
}
func (ma *MovingAverage) Next(val int) float64 {
if len(ma.q) == ma.size {
ma.sum -= ma.q[0]
ma.q = ma.q[1:]
}
ma.q = append(ma.q, val)
ma.sum += val
return float64(ma.sum) / float64(len(ma.q))
}
func main() {
movingAverage := constuctor(3)
fmt.Printf("%v\n", movingAverage.Next(1)) // returns 1.0
fmt.Printf("%v\n", movingAverage.Next(10)) // returns 5.5
fmt.Printf("%v\n", movingAverage.Next(3)) // returns 4.66667
fmt.Printf("%v\n", movingAverage.Next(5)) // returns 6
}
Q70
703. Kth Largest Element in a Stream
Easy. Min heap
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) Peek() int {return h[0]}
func (h *MinHeap) Push(x interface{}) {*h = append(*h, x.(int))}
func (h *MinHeap) Pop() interface{} {
x := (*h)[len(*h) - 1]
*h = (*h)[:len(*h) - 1]
return x
}
type KthLargest struct {
minh *MinHeap
size int
}
func Constructor(k int, nums []int) KthLargest {
minh := make(MinHeap, 0)
for _, num := range nums {
heap.Push(&minh, num)
}
heap.Init(&minh)
// Initialize min heap with the k most largest items
for minh.Len() > k {
heap.Pop(&minh)
}
return KthLargest{
minh: &minh,
size: k,
}
}
func (this *KthLargest) Add(val int) int {
heap.Push(this.minh, val)
if this.minh.Len() > this.size {
heap.Pop(this.minh)
}
// The smallest in the min heap is the kth largest
return this.minh.Peek()
}
ย