mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-06 09:23:19 +08:00
Add solution 0284、0703
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
package leetcode
|
||||
|
||||
import "container/heap"
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
|
53
leetcode/0284.Peeking-Iterator/284. Peeking Iterator.go
Normal file
53
leetcode/0284.Peeking-Iterator/284. Peeking Iterator.go
Normal file
@ -0,0 +1,53 @@
|
||||
package leetcode
|
||||
|
||||
//Below is the interface for Iterator, which is already defined for you.
|
||||
|
||||
type Iterator struct {
|
||||
}
|
||||
|
||||
func (this *Iterator) hasNext() bool {
|
||||
// Returns true if the iteration has more elements.
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Iterator) next() int {
|
||||
// Returns the next element in the iteration.
|
||||
return 0
|
||||
}
|
||||
|
||||
type PeekingIterator struct {
|
||||
nextEl int
|
||||
hasEl bool
|
||||
iter *Iterator
|
||||
}
|
||||
|
||||
func Constructor(iter *Iterator) *PeekingIterator {
|
||||
return &PeekingIterator{
|
||||
iter: iter,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) hasNext() bool {
|
||||
if this.hasEl {
|
||||
return true
|
||||
}
|
||||
return this.iter.hasNext()
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) next() int {
|
||||
if this.hasEl {
|
||||
this.hasEl = false
|
||||
return this.nextEl
|
||||
} else {
|
||||
return this.iter.next()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) peek() int {
|
||||
if this.hasEl {
|
||||
return this.nextEl
|
||||
}
|
||||
this.hasEl = true
|
||||
this.nextEl = this.iter.next()
|
||||
return this.nextEl
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Problem284(t *testing.T) {
|
||||
|
||||
}
|
87
leetcode/0284.Peeking-Iterator/README.md
Normal file
87
leetcode/0284.Peeking-Iterator/README.md
Normal file
@ -0,0 +1,87 @@
|
||||
# [284. Peeking Iterator](https://leetcode.com/problems/peeking-iterator/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an Iterator class interface with methods: `next()` and `hasNext()`, design and implement a PeekingIterator that support the `peek()` operation -- it essentially peek() at the element that will be returned by the next call to next().
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Assume that the iterator is initialized to the beginning of the list: [1,2,3].
|
||||
|
||||
Call next() gets you 1, the first element in the list.
|
||||
Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.
|
||||
You call next() the final time and it returns 3, the last element.
|
||||
Calling hasNext() after that should return false.
|
||||
```
|
||||
|
||||
**Follow up**: How would you extend your design to be generic and work with all types, not just integer?
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个迭代器类的接口,接口包含两个方法: next() 和 hasNext()。设计并实现一个支持 peek() 操作的顶端迭代器 -- 其本质就是把原本应由 next() 方法返回的元素 peek() 出来。
|
||||
|
||||
> peek() 是偷看的意思。偷偷看一看下一个元素是什么,但是并不是 next() 访问。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 简单题。在 PeekingIterator 内部保存 2 个变量,一个是下一个元素值,另一个是是否有下一个元素。在 next() 操作和 hasNext() 操作时,访问保存的这 2 个变量。peek() 操作也比较简单,判断是否有下一个元素,如果有,即返回该元素值。这里实现了迭代指针不移动的功能。如果没有保存下一个元素值,即没有 peek() 偷看,next() 操作继续往后移动指针,读取后一位元素。
|
||||
- 这里复用了是否有下一个元素值,来判断 hasNext() 和 peek() 操作中不移动指针的逻辑。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
//Below is the interface for Iterator, which is already defined for you.
|
||||
|
||||
type Iterator struct {
|
||||
}
|
||||
|
||||
func (this *Iterator) hasNext() bool {
|
||||
// Returns true if the iteration has more elements.
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Iterator) next() int {
|
||||
// Returns the next element in the iteration.
|
||||
return 0
|
||||
}
|
||||
|
||||
type PeekingIterator struct {
|
||||
nextEl int
|
||||
hasEl bool
|
||||
iter *Iterator
|
||||
}
|
||||
|
||||
func Constructor(iter *Iterator) *PeekingIterator {
|
||||
return &PeekingIterator{
|
||||
iter: iter,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) hasNext() bool {
|
||||
if this.hasEl {
|
||||
return true
|
||||
}
|
||||
return this.iter.hasNext()
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) next() int {
|
||||
if this.hasEl {
|
||||
this.hasEl = false
|
||||
return this.nextEl
|
||||
} else {
|
||||
return this.iter.next()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PeekingIterator) peek() int {
|
||||
if this.hasEl {
|
||||
return this.nextEl
|
||||
}
|
||||
this.hasEl = true
|
||||
this.nextEl = this.iter.next()
|
||||
return this.nextEl
|
||||
}
|
||||
```
|
@ -0,0 +1,38 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type KthLargest struct {
|
||||
sort.IntSlice
|
||||
k int
|
||||
}
|
||||
|
||||
func Constructor(k int, nums []int) KthLargest {
|
||||
kl := KthLargest{k: k}
|
||||
for _, val := range nums {
|
||||
kl.Add(val)
|
||||
}
|
||||
return kl
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Push(v interface{}) {
|
||||
kl.IntSlice = append(kl.IntSlice, v.(int))
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Pop() interface{} {
|
||||
a := kl.IntSlice
|
||||
v := a[len(a)-1]
|
||||
kl.IntSlice = a[:len(a)-1]
|
||||
return v
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Add(val int) int {
|
||||
heap.Push(kl, val)
|
||||
if kl.Len() > kl.k {
|
||||
heap.Pop(kl)
|
||||
}
|
||||
return kl.IntSlice[0]
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Problem703(t *testing.T) {
|
||||
obj := Constructor(3, []int{4, 5, 8, 2})
|
||||
fmt.Printf("Add 7 = %v\n", obj.Add(3))
|
||||
fmt.Printf("Add 7 = %v\n", obj.Add(5))
|
||||
fmt.Printf("Add 7 = %v\n", obj.Add(10))
|
||||
fmt.Printf("Add 7 = %v\n", obj.Add(9))
|
||||
fmt.Printf("Add 7 = %v\n", obj.Add(4))
|
||||
}
|
93
leetcode/0703.Kth-Largest-Element-in-a-Stream/README.md
Normal file
93
leetcode/0703.Kth-Largest-Element-in-a-Stream/README.md
Normal file
@ -0,0 +1,93 @@
|
||||
# [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/)
|
||||
|
||||
## 题目
|
||||
|
||||
Design a class to find the `kth` largest element in a stream. Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.
|
||||
|
||||
Implement `KthLargest` class:
|
||||
|
||||
- `KthLargest(int k, int[] nums)` Initializes the object with the integer `k` and the stream of integers `nums`.
|
||||
- `int add(int val)` Returns the element representing the `kth` largest element in the stream.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input
|
||||
["KthLargest", "add", "add", "add", "add", "add"]
|
||||
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
|
||||
Output
|
||||
[null, 4, 5, 5, 8, 8]
|
||||
|
||||
Explanation
|
||||
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
|
||||
kthLargest.add(3); // return 4
|
||||
kthLargest.add(5); // return 5
|
||||
kthLargest.add(10); // return 5
|
||||
kthLargest.add(9); // return 8
|
||||
kthLargest.add(4); // return 8
|
||||
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= k <= 104`
|
||||
- `0 <= nums.length <= 104`
|
||||
- `104 <= nums[i] <= 104`
|
||||
- `104 <= val <= 104`
|
||||
- At most `104` calls will be made to `add`.
|
||||
- It is guaranteed that there will be at least `k` elements in the array when you search for the `kth` element.
|
||||
|
||||
## 题目大意
|
||||
|
||||
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。请实现 KthLargest 类:
|
||||
|
||||
- KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
|
||||
- int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 读完题就能明白这一题考察的是最小堆。构建一个长度为 K 的最小堆,每次 pop 堆首(堆中最小的元素),维护堆首即为第 K 大元素。
|
||||
- 这里有一个简洁的写法,常规的构建一个 pq 优先队列需要自己新建一个类型,然后实现 Len()、Less()、Swap()、Push()、Pop() 这 5 个方法。在 sort 包里有一个现成的最小堆,sort.IntSlice。可以借用它,再自己实现 Push()、Pop()就可以使用最小堆了,节约一部分代码。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type KthLargest struct {
|
||||
sort.IntSlice
|
||||
k int
|
||||
}
|
||||
|
||||
func Constructor(k int, nums []int) KthLargest {
|
||||
kl := KthLargest{k: k}
|
||||
for _, val := range nums {
|
||||
kl.Add(val)
|
||||
}
|
||||
return kl
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Push(v interface{}) {
|
||||
kl.IntSlice = append(kl.IntSlice, v.(int))
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Pop() interface{} {
|
||||
a := kl.IntSlice
|
||||
v := a[len(a)-1]
|
||||
kl.IntSlice = a[:len(a)-1]
|
||||
return v
|
||||
}
|
||||
|
||||
func (kl *KthLargest) Add(val int) int {
|
||||
heap.Push(kl, val)
|
||||
if kl.Len() > kl.k {
|
||||
heap.Pop(kl)
|
||||
}
|
||||
return kl.IntSlice[0]
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user