Day 22 of LeetCode

Day 22 of LeetCode

ยท

4 min read

Documenting LeetCode solving.

Q66

239. Sliding Window Maximum

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()
}

Did you find this article valuable?

Support ๐Ÿฐ Evelyn's Learning Journey by becoming a sponsor. Any amount is appreciated!

ย