From b8cc9190df49f2186d784fe56badd59aa65f8fb6 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Tue, 9 Jul 2024 19:50:26 +0800 Subject: [PATCH] feat: update solutions to lc problems: No.0702,0703,1704 (#3237) --- .../README.md | 109 +++++-- .../README_EN.md | 109 +++++-- .../Solution.cpp | 16 +- .../Solution.go | 18 +- .../Solution.java | 16 +- .../Solution.py | 22 +- .../Solution.ts | 24 ++ .../README.md | 298 ++++++------------ .../README_EN.md | 298 ++++++------------ .../Solution.cpp | 21 +- .../Solution.go | 68 ++-- .../Solution.java | 20 +- .../Solution.js | 99 +----- .../Solution.py | 17 +- .../Solution.ts | 17 +- .../README.md | 64 ++-- .../README_EN.md | 64 ++-- .../Solution.java | 11 +- .../Solution.js | 9 +- .../Solution.php | 12 +- .../Solution.rs | 22 +- .../Solution.ts | 12 +- .../README.md | 2 +- 23 files changed, 578 insertions(+), 770 deletions(-) create mode 100644 solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.ts diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README.md b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README.md index 0d6ca0f6ab57a..a7bd3b2c6550b 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README.md +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README.md @@ -70,7 +70,13 @@ tags: -### 方法一 +### 方法一:二分查找 + +我们先定义一个指针 $r = 1$,每一次判断 $r$ 处的值是否小于目标值,如果小于目标值,我们将 $r$ 乘以 $2$,即左移一位,直到 $r$ 处的值大于等于目标值。此时,我们可以确定目标值在 $[r / 2, r]$ 的区间内。 + +接下来,我们定义一个指针 $l = r / 2$,然后我们可以使用二分查找的方法在 $[l, r]$ 的区间内查找目标值的位置。 + +时间复杂度 $O(\log M)$,其中 $M$ 为目标值的位置。空间复杂度 $O(1)$。 @@ -86,20 +92,18 @@ tags: class Solution: - def search(self, reader, target): - """ - :type reader: ArrayReader - :type target: int - :rtype: int - """ - left, right = 0, 20000 - while left < right: - mid = (left + right) >> 1 + def search(self, reader: "ArrayReader", target: int) -> int: + r = 1 + while reader.get(r) < target: + r <<= 1 + l = r >> 1 + while l < r: + mid = (l + r) >> 1 if reader.get(mid) >= target: - right = mid + r = mid else: - left = mid + 1 - return left if reader.get(left) == target else -1 + l = mid + 1 + return l if reader.get(l) == target else -1 ``` #### Java @@ -115,16 +119,20 @@ class Solution: class Solution { public int search(ArrayReader reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } } ``` @@ -144,16 +152,20 @@ class Solution { class Solution { public: int search(const ArrayReader& reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } }; ``` @@ -171,22 +183,55 @@ public: */ func search(reader ArrayReader, target int) int { - left, right := 0, 20000 - for left < right { - mid := (left + right) >> 1 + r := 1 + for reader.get(r) < target { + r <<= 1 + } + l := r >> 1 + for l < r { + mid := (l + r) >> 1 if reader.get(mid) >= target { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - if reader.get(left) == target { - return left + if reader.get(l) == target { + return l } return -1 } ``` +#### TypeScript + +```ts +/** + * class ArrayReader { + * // This is the ArrayReader's API interface. + * // You should not implement it, or speculate about its implementation + * get(index: number): number {}; + * }; + */ + +function search(reader: ArrayReader, target: number): number { + let r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + let l = r >> 1; + while (l < r) { + const mid = (l + r) >> 1; + if (reader.get(mid) >= target) { + r = mid; + } else { + l = mid + 1; + } + } + return reader.get(l) === target ? l : -1; +} +``` + diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README_EN.md b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README_EN.md index 405d0dbe8ce2e..d7281cf075cf0 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README_EN.md +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/README_EN.md @@ -65,7 +65,13 @@ tags: -### Solution 1 +### Solution 1: Binary Search + +First, we define a pointer $r = 1$. Each time, we check if the value at position $r$ is less than the target value. If it is, we multiply $r$ by $2$, i.e., shift it left by one bit, until the value at position $r$ is greater than or equal to the target value. At this point, we can determine that the target value is within the interval $[r / 2, r]$. + +Next, we define a pointer $l = r / 2$, and then we can use the binary search method to find the position of the target value within the interval $[l, r]$. + +The time complexity is $O(\log M)$, where $M$ is the position of the target value. The space complexity is $O(1)$. @@ -81,20 +87,18 @@ tags: class Solution: - def search(self, reader, target): - """ - :type reader: ArrayReader - :type target: int - :rtype: int - """ - left, right = 0, 20000 - while left < right: - mid = (left + right) >> 1 + def search(self, reader: "ArrayReader", target: int) -> int: + r = 1 + while reader.get(r) < target: + r <<= 1 + l = r >> 1 + while l < r: + mid = (l + r) >> 1 if reader.get(mid) >= target: - right = mid + r = mid else: - left = mid + 1 - return left if reader.get(left) == target else -1 + l = mid + 1 + return l if reader.get(l) == target else -1 ``` #### Java @@ -110,16 +114,20 @@ class Solution: class Solution { public int search(ArrayReader reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } } ``` @@ -139,16 +147,20 @@ class Solution { class Solution { public: int search(const ArrayReader& reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } }; ``` @@ -166,22 +178,55 @@ public: */ func search(reader ArrayReader, target int) int { - left, right := 0, 20000 - for left < right { - mid := (left + right) >> 1 + r := 1 + for reader.get(r) < target { + r <<= 1 + } + l := r >> 1 + for l < r { + mid := (l + r) >> 1 if reader.get(mid) >= target { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - if reader.get(left) == target { - return left + if reader.get(l) == target { + return l } return -1 } ``` +#### TypeScript + +```ts +/** + * class ArrayReader { + * // This is the ArrayReader's API interface. + * // You should not implement it, or speculate about its implementation + * get(index: number): number {}; + * }; + */ + +function search(reader: ArrayReader, target: number): number { + let r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + let l = r >> 1; + while (l < r) { + const mid = (l + r) >> 1; + if (reader.get(mid) >= target) { + r = mid; + } else { + l = mid + 1; + } + } + return reader.get(l) === target ? l : -1; +} +``` + diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.cpp b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.cpp index c69022b5e869c..2fb02b4611f37 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.cpp +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.cpp @@ -10,15 +10,19 @@ class Solution { public: int search(const ArrayReader& reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } }; \ No newline at end of file diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.go b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.go index 892f77a58731c..d29bf330ee706 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.go +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.go @@ -8,17 +8,21 @@ */ func search(reader ArrayReader, target int) int { - left, right := 0, 20000 - for left < right { - mid := (left + right) >> 1 + r := 1 + for reader.get(r) < target { + r <<= 1 + } + l := r >> 1 + for l < r { + mid := (l + r) >> 1 if reader.get(mid) >= target { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - if reader.get(left) == target { - return left + if reader.get(l) == target { + return l } return -1 } \ No newline at end of file diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.java b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.java index 140bd1130c12b..e9692e79f0e43 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.java +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.java @@ -8,15 +8,19 @@ class Solution { public int search(ArrayReader reader, int target) { - int left = 0, right = 20000; - while (left < right) { - int mid = left + right >> 1; + int r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + int l = r >> 1; + while (l < r) { + int mid = (l + r) >> 1; if (reader.get(mid) >= target) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return reader.get(left) == target ? left : -1; + return reader.get(l) == target ? l : -1; } } \ No newline at end of file diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.py b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.py index 14c71b9326046..97203c2ff0c75 100644 --- a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.py +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.py @@ -7,17 +7,15 @@ class Solution: - def search(self, reader, target): - """ - :type reader: ArrayReader - :type target: int - :rtype: int - """ - left, right = 0, 20000 - while left < right: - mid = (left + right) >> 1 + def search(self, reader: "ArrayReader", target: int) -> int: + r = 1 + while reader.get(r) < target: + r <<= 1 + l = r >> 1 + while l < r: + mid = (l + r) >> 1 if reader.get(mid) >= target: - right = mid + r = mid else: - left = mid + 1 - return left if reader.get(left) == target else -1 + l = mid + 1 + return l if reader.get(l) == target else -1 diff --git a/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.ts b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.ts new file mode 100644 index 0000000000000..8085d6e3859f7 --- /dev/null +++ b/solution/0700-0799/0702.Search in a Sorted Array of Unknown Size/Solution.ts @@ -0,0 +1,24 @@ +/** + * class ArrayReader { + * // This is the ArrayReader's API interface. + * // You should not implement it, or speculate about its implementation + * get(index: number): number {}; + * }; + */ + +function search(reader: ArrayReader, target: number): number { + let r = 1; + while (reader.get(r) < target) { + r <<= 1; + } + let l = r >> 1; + while (l < r) { + const mid = (l + r) >> 1; + if (reader.get(mid) >= target) { + r = mid; + } else { + l = mid + 1; + } + } + return reader.get(l) === target ? l : -1; +} diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/README.md b/solution/0700-0799/0703.Kth Largest Element in a Stream/README.md index 15c9606146997..689934a897b33 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/README.md +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/README.md @@ -68,7 +68,17 @@ kthLargest.add(4); // return 8 -### 方法一 +### 方法一:优先队列(小根堆) + +我们维护一个优先队列(小根堆)$\textit{minQ}$。 + +初始化时,我们将数组 $\textit{nums}$ 中的元素依次加入 $\textit{minQ}$,并保持 $\textit{minQ}$ 的大小不超过 $k$。时间复杂度 $O(n \times \log k)$。 + +每次加入一个新元素时,如果 $\textit{minQ}$ 的大小超过了 $k$,我们就将堆顶元素弹出,保证 $\textit{minQ}$ 的大小为 $k$。时间复杂度 $O(\log k)$。 + +这样,$\textit{minQ}$ 中的元素就是数组 $\textit{nums}$ 中最大的 $k$ 个元素,堆顶元素就是第 $k$ 大的元素。 + +空间复杂度 $O(k)$。 @@ -76,17 +86,18 @@ kthLargest.add(4); // return 8 ```python class KthLargest: + def __init__(self, k: int, nums: List[int]): - self.q = [] - self.size = k - for num in nums: - self.add(num) + self.k = k + self.min_q = [] + for x in nums: + self.add(x) def add(self, val: int) -> int: - heappush(self.q, val) - if len(self.q) > self.size: - heappop(self.q) - return self.q[0] + heappush(self.min_q, val) + if len(self.min_q) > self.k: + heappop(self.min_q) + return self.min_q[0] # Your KthLargest object will be instantiated and called as such: @@ -98,23 +109,23 @@ class KthLargest: ```java class KthLargest { - private PriorityQueue q; - private int size; + private PriorityQueue minQ; + private int k; public KthLargest(int k, int[] nums) { - q = new PriorityQueue<>(k); - size = k; - for (int num : nums) { - add(num); + this.k = k; + minQ = new PriorityQueue<>(k); + for (int x : nums) { + add(x); } } public int add(int val) { - q.offer(val); - if (q.size() > size) { - q.poll(); + minQ.offer(val); + if (minQ.size() > k) { + minQ.poll(); } - return q.peek(); + return minQ.peek(); } } @@ -130,19 +141,24 @@ class KthLargest { ```cpp class KthLargest { public: - priority_queue, greater> q; - int size; - KthLargest(int k, vector& nums) { - size = k; - for (int num : nums) add(num); + this->k = k; + for (int x : nums) { + add(x); + } } int add(int val) { - q.push(val); - if (q.size() > size) q.pop(); - return q.top(); + minQ.push(val); + if (minQ.size() > k) { + minQ.pop(); + } + return minQ.top(); } + +private: + int k; + priority_queue, greater> minQ; }; /** @@ -156,71 +172,39 @@ public: ```go type KthLargest struct { - h *IntHeap - k int + k int + minQ hp } func Constructor(k int, nums []int) KthLargest { - h := &IntHeap{} - heap.Init(h) - for _, v := range nums { - heap.Push(h, v) - } - - for h.Len() > k { - heap.Pop(h) - } - - return KthLargest{ - h: h, - k: k, + minQ := hp{} + this := KthLargest{k, minQ} + for _, x := range nums { + this.Add(x) } + return this } func (this *KthLargest) Add(val int) int { - heap.Push(this.h, val) - for this.h.Len() > this.k { - heap.Pop(this.h) - } - - return this.h.Top() -} - -func connectSticks(sticks []int) int { - h := IntHeap(sticks) - heap.Init(&h) - res := 0 - for h.Len() > 1 { - val := heap.Pop(&h).(int) - val += heap.Pop(&h).(int) - res += val - heap.Push(&h, val) + heap.Push(&this.minQ, val) + if this.minQ.Len() > this.k { + heap.Pop(&this.minQ) } - return res + return this.minQ.IntSlice[0] } -type IntHeap []int +type hp struct{ sort.IntSlice } -func (h IntHeap) Len() int { return len(h) } -func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } -func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h *IntHeap) Push(x any) { - *h = append(*h, x.(int)) -} -func (h *IntHeap) Pop() any { - old := *h +func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] } +func (h *hp) Pop() interface{} { + old := h.IntSlice n := len(old) x := old[n-1] - *h = old[0 : n-1] + h.IntSlice = old[0 : n-1] return x } - -func (h *IntHeap) Top() int { - if (*h).Len() == 0 { - return 0 - } - - return (*h)[0] +func (h *hp) Push(x interface{}) { + h.IntSlice = append(h.IntSlice, x.(int)) } /** @@ -230,115 +214,26 @@ func (h *IntHeap) Top() int { */ ``` -#### JavaScript - -```js -/** - * @param {number} k - * @param {number[]} nums - */ -var KthLargest = function (k, nums) { - this.k = k; - this.heap = new MinHeap(); - for (let num of nums) { - this.add(num); - } -}; - -/** - * @param {number} val - * @return {number} - */ -KthLargest.prototype.add = function (val) { - this.heap.offer(val); - if (this.heap.size() > this.k) { - this.heap.poll(); - } - return this.heap.peek(); -}; - -class MinHeap { - constructor(data = []) { - this.data = data; - this.comparator = (a, b) => a - b; - this.heapify(); - } - - heapify() { - if (this.size() < 2) return; - for (let i = 1; i < this.size(); i++) { - this.bubbleUp(i); - } - } - - peek() { - if (this.size() === 0) return null; - return this.data[0]; - } - - offer(value) { - this.data.push(value); - this.bubbleUp(this.size() - 1); - } +#### TypeScript - poll() { - if (this.size() === 0) { - return null; - } - const result = this.data[0]; - const last = this.data.pop(); - if (this.size() !== 0) { - this.data[0] = last; - this.bubbleDown(0); - } - return result; - } +```ts +class KthLargest { + #k: number = 0; + #minQ = new MinPriorityQueue(); - bubbleUp(index) { - while (index > 0) { - const parentIndex = (index - 1) >> 1; - if (this.comparator(this.data[index], this.data[parentIndex]) < 0) { - this.swap(index, parentIndex); - index = parentIndex; - } else { - break; - } + constructor(k: number, nums: number[]) { + this.#k = k; + for (const x of nums) { + this.add(x); } } - bubbleDown(index) { - const lastIndex = this.size() - 1; - while (true) { - const leftIndex = index * 2 + 1; - const rightIndex = index * 2 + 2; - let findIndex = index; - if ( - leftIndex <= lastIndex && - this.comparator(this.data[leftIndex], this.data[findIndex]) < 0 - ) { - findIndex = leftIndex; - } - if ( - rightIndex <= lastIndex && - this.comparator(this.data[rightIndex], this.data[findIndex]) < 0 - ) { - findIndex = rightIndex; - } - if (index !== findIndex) { - this.swap(index, findIndex); - index = findIndex; - } else { - break; - } + add(val: number): number { + this.#minQ.enqueue(val); + if (this.#minQ.size() > this.#k) { + this.#minQ.dequeue(); } - } - - swap(index1, index2) { - [this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]]; - } - - size() { - return this.data.length; + return this.#minQ.front().element; } } @@ -349,31 +244,32 @@ class MinHeap { */ ``` -#### TypeScript - -```ts -class KthLargest { - #pq = new MinPriorityQueue(); - #k = 0; +#### JavaScript - constructor(k: number, nums: number[]) { - this.#k = k; - for (const x of nums) { - this.#pq.enqueue(x); - if (this.#pq.size() > k) { - this.#pq.dequeue(); - } - } +```js +/** + * @param {number} k + * @param {number[]} nums + */ +var KthLargest = function (k, nums) { + this.k = k; + this.minQ = new MinPriorityQueue(); + for (const x of nums) { + this.add(x); } +}; - add(val: number): number { - this.#pq.enqueue(val); - if (this.#pq.size() > this.#k) { - this.#pq.dequeue(); - } - return this.#pq.front().element; +/** + * @param {number} val + * @return {number} + */ +KthLargest.prototype.add = function (val) { + this.minQ.enqueue(val); + if (this.minQ.size() > this.k) { + this.minQ.dequeue(); } -} + return this.minQ.front().element; +}; /** * Your KthLargest object will be instantiated and called as such: diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/README_EN.md b/solution/0700-0799/0703.Kth Largest Element in a Stream/README_EN.md index 254d1a356e5a1..2419ceb69eebe 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/README_EN.md +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/README_EN.md @@ -67,7 +67,17 @@ kthLargest.add(4); // return 8 -### Solution 1 +### Solution 1: Priority Queue (Min Heap) + +We maintain a priority queue (min heap) $\textit{minQ}$. + +Initially, we add the elements of the array $\textit{nums}$ to $\textit{minQ}$ one by one, ensuring that the size of $\textit{minQ}$ does not exceed $k$. The time complexity is $O(n \times \log k)$. + +Each time a new element is added, if the size of $\textit{minQ}$ exceeds $k$, we pop the top element of the heap to ensure that the size of $\textit{minQ}$ is $k$. The time complexity is $O(\log k)$. + +In this way, the elements in $\textit{minQ}$ are the largest $k$ elements in the array $\textit{nums}$, and the top element of the heap is the $k^{th}$ largest element. + +The space complexity is $O(k)$. @@ -75,17 +85,18 @@ kthLargest.add(4); // return 8 ```python class KthLargest: + def __init__(self, k: int, nums: List[int]): - self.q = [] - self.size = k - for num in nums: - self.add(num) + self.k = k + self.min_q = [] + for x in nums: + self.add(x) def add(self, val: int) -> int: - heappush(self.q, val) - if len(self.q) > self.size: - heappop(self.q) - return self.q[0] + heappush(self.min_q, val) + if len(self.min_q) > self.k: + heappop(self.min_q) + return self.min_q[0] # Your KthLargest object will be instantiated and called as such: @@ -97,23 +108,23 @@ class KthLargest: ```java class KthLargest { - private PriorityQueue q; - private int size; + private PriorityQueue minQ; + private int k; public KthLargest(int k, int[] nums) { - q = new PriorityQueue<>(k); - size = k; - for (int num : nums) { - add(num); + this.k = k; + minQ = new PriorityQueue<>(k); + for (int x : nums) { + add(x); } } public int add(int val) { - q.offer(val); - if (q.size() > size) { - q.poll(); + minQ.offer(val); + if (minQ.size() > k) { + minQ.poll(); } - return q.peek(); + return minQ.peek(); } } @@ -129,19 +140,24 @@ class KthLargest { ```cpp class KthLargest { public: - priority_queue, greater> q; - int size; - KthLargest(int k, vector& nums) { - size = k; - for (int num : nums) add(num); + this->k = k; + for (int x : nums) { + add(x); + } } int add(int val) { - q.push(val); - if (q.size() > size) q.pop(); - return q.top(); + minQ.push(val); + if (minQ.size() > k) { + minQ.pop(); + } + return minQ.top(); } + +private: + int k; + priority_queue, greater> minQ; }; /** @@ -155,71 +171,39 @@ public: ```go type KthLargest struct { - h *IntHeap - k int + k int + minQ hp } func Constructor(k int, nums []int) KthLargest { - h := &IntHeap{} - heap.Init(h) - for _, v := range nums { - heap.Push(h, v) - } - - for h.Len() > k { - heap.Pop(h) - } - - return KthLargest{ - h: h, - k: k, + minQ := hp{} + this := KthLargest{k, minQ} + for _, x := range nums { + this.Add(x) } + return this } func (this *KthLargest) Add(val int) int { - heap.Push(this.h, val) - for this.h.Len() > this.k { - heap.Pop(this.h) - } - - return this.h.Top() -} - -func connectSticks(sticks []int) int { - h := IntHeap(sticks) - heap.Init(&h) - res := 0 - for h.Len() > 1 { - val := heap.Pop(&h).(int) - val += heap.Pop(&h).(int) - res += val - heap.Push(&h, val) + heap.Push(&this.minQ, val) + if this.minQ.Len() > this.k { + heap.Pop(&this.minQ) } - return res + return this.minQ.IntSlice[0] } -type IntHeap []int +type hp struct{ sort.IntSlice } -func (h IntHeap) Len() int { return len(h) } -func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } -func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h *IntHeap) Push(x any) { - *h = append(*h, x.(int)) -} -func (h *IntHeap) Pop() any { - old := *h +func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] } +func (h *hp) Pop() interface{} { + old := h.IntSlice n := len(old) x := old[n-1] - *h = old[0 : n-1] + h.IntSlice = old[0 : n-1] return x } - -func (h *IntHeap) Top() int { - if (*h).Len() == 0 { - return 0 - } - - return (*h)[0] +func (h *hp) Push(x interface{}) { + h.IntSlice = append(h.IntSlice, x.(int)) } /** @@ -229,115 +213,26 @@ func (h *IntHeap) Top() int { */ ``` -#### JavaScript - -```js -/** - * @param {number} k - * @param {number[]} nums - */ -var KthLargest = function (k, nums) { - this.k = k; - this.heap = new MinHeap(); - for (let num of nums) { - this.add(num); - } -}; - -/** - * @param {number} val - * @return {number} - */ -KthLargest.prototype.add = function (val) { - this.heap.offer(val); - if (this.heap.size() > this.k) { - this.heap.poll(); - } - return this.heap.peek(); -}; - -class MinHeap { - constructor(data = []) { - this.data = data; - this.comparator = (a, b) => a - b; - this.heapify(); - } - - heapify() { - if (this.size() < 2) return; - for (let i = 1; i < this.size(); i++) { - this.bubbleUp(i); - } - } - - peek() { - if (this.size() === 0) return null; - return this.data[0]; - } - - offer(value) { - this.data.push(value); - this.bubbleUp(this.size() - 1); - } +#### TypeScript - poll() { - if (this.size() === 0) { - return null; - } - const result = this.data[0]; - const last = this.data.pop(); - if (this.size() !== 0) { - this.data[0] = last; - this.bubbleDown(0); - } - return result; - } +```ts +class KthLargest { + #k: number = 0; + #minQ = new MinPriorityQueue(); - bubbleUp(index) { - while (index > 0) { - const parentIndex = (index - 1) >> 1; - if (this.comparator(this.data[index], this.data[parentIndex]) < 0) { - this.swap(index, parentIndex); - index = parentIndex; - } else { - break; - } + constructor(k: number, nums: number[]) { + this.#k = k; + for (const x of nums) { + this.add(x); } } - bubbleDown(index) { - const lastIndex = this.size() - 1; - while (true) { - const leftIndex = index * 2 + 1; - const rightIndex = index * 2 + 2; - let findIndex = index; - if ( - leftIndex <= lastIndex && - this.comparator(this.data[leftIndex], this.data[findIndex]) < 0 - ) { - findIndex = leftIndex; - } - if ( - rightIndex <= lastIndex && - this.comparator(this.data[rightIndex], this.data[findIndex]) < 0 - ) { - findIndex = rightIndex; - } - if (index !== findIndex) { - this.swap(index, findIndex); - index = findIndex; - } else { - break; - } + add(val: number): number { + this.#minQ.enqueue(val); + if (this.#minQ.size() > this.#k) { + this.#minQ.dequeue(); } - } - - swap(index1, index2) { - [this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]]; - } - - size() { - return this.data.length; + return this.#minQ.front().element; } } @@ -348,31 +243,32 @@ class MinHeap { */ ``` -#### TypeScript - -```ts -class KthLargest { - #pq = new MinPriorityQueue(); - #k = 0; +#### JavaScript - constructor(k: number, nums: number[]) { - this.#k = k; - for (const x of nums) { - this.#pq.enqueue(x); - if (this.#pq.size() > k) { - this.#pq.dequeue(); - } - } +```js +/** + * @param {number} k + * @param {number[]} nums + */ +var KthLargest = function (k, nums) { + this.k = k; + this.minQ = new MinPriorityQueue(); + for (const x of nums) { + this.add(x); } +}; - add(val: number): number { - this.#pq.enqueue(val); - if (this.#pq.size() > this.#k) { - this.#pq.dequeue(); - } - return this.#pq.front().element; +/** + * @param {number} val + * @return {number} + */ +KthLargest.prototype.add = function (val) { + this.minQ.enqueue(val); + if (this.minQ.size() > this.k) { + this.minQ.dequeue(); } -} + return this.minQ.front().element; +}; /** * Your KthLargest object will be instantiated and called as such: diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.cpp b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.cpp index b1e5e3e44425a..727473886cfee 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.cpp +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.cpp @@ -1,18 +1,23 @@ class KthLargest { public: - priority_queue, greater> q; - int size; - KthLargest(int k, vector& nums) { - size = k; - for (int num : nums) add(num); + this->k = k; + for (int x : nums) { + add(x); + } } int add(int val) { - q.push(val); - if (q.size() > size) q.pop(); - return q.top(); + minQ.push(val); + if (minQ.size() > k) { + minQ.pop(); + } + return minQ.top(); } + +private: + int k; + priority_queue, greater> minQ; }; /** diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.go b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.go index f36066247883d..7f24fce7bb3dc 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.go +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.go @@ -1,69 +1,37 @@ type KthLargest struct { - h *IntHeap - k int + k int + minQ hp } func Constructor(k int, nums []int) KthLargest { - h := &IntHeap{} - heap.Init(h) - for _, v := range nums { - heap.Push(h, v) - } - - for h.Len() > k { - heap.Pop(h) - } - - return KthLargest{ - h: h, - k: k, + minQ := hp{} + this := KthLargest{k, minQ} + for _, x := range nums { + this.Add(x) } + return this } func (this *KthLargest) Add(val int) int { - heap.Push(this.h, val) - for this.h.Len() > this.k { - heap.Pop(this.h) - } - - return this.h.Top() -} - -func connectSticks(sticks []int) int { - h := IntHeap(sticks) - heap.Init(&h) - res := 0 - for h.Len() > 1 { - val := heap.Pop(&h).(int) - val += heap.Pop(&h).(int) - res += val - heap.Push(&h, val) + heap.Push(&this.minQ, val) + if this.minQ.Len() > this.k { + heap.Pop(&this.minQ) } - return res + return this.minQ.IntSlice[0] } -type IntHeap []int +type hp struct{ sort.IntSlice } -func (h IntHeap) Len() int { return len(h) } -func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } -func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h *IntHeap) Push(x any) { - *h = append(*h, x.(int)) -} -func (h *IntHeap) Pop() any { - old := *h +func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] } +func (h *hp) Pop() interface{} { + old := h.IntSlice n := len(old) x := old[n-1] - *h = old[0 : n-1] + h.IntSlice = old[0 : n-1] return x } - -func (h *IntHeap) Top() int { - if (*h).Len() == 0 { - return 0 - } - - return (*h)[0] +func (h *hp) Push(x interface{}) { + h.IntSlice = append(h.IntSlice, x.(int)) } /** diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.java b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.java index 07a18ac03d082..6337527c3d3db 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.java +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.java @@ -1,21 +1,21 @@ class KthLargest { - private PriorityQueue q; - private int size; + private PriorityQueue minQ; + private int k; public KthLargest(int k, int[] nums) { - q = new PriorityQueue<>(k); - size = k; - for (int num : nums) { - add(num); + this.k = k; + minQ = new PriorityQueue<>(k); + for (int x : nums) { + add(x); } } public int add(int val) { - q.offer(val); - if (q.size() > size) { - q.poll(); + minQ.offer(val); + if (minQ.size() > k) { + minQ.poll(); } - return q.peek(); + return minQ.peek(); } } diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.js b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.js index b1df75769ccbb..0bd6296eae0fe 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.js +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.js @@ -4,9 +4,9 @@ */ var KthLargest = function (k, nums) { this.k = k; - this.heap = new MinHeap(); - for (let num of nums) { - this.add(num); + this.minQ = new MinPriorityQueue(); + for (const x of nums) { + this.add(x); } }; @@ -15,98 +15,13 @@ var KthLargest = function (k, nums) { * @return {number} */ KthLargest.prototype.add = function (val) { - this.heap.offer(val); - if (this.heap.size() > this.k) { - this.heap.poll(); + this.minQ.enqueue(val); + if (this.minQ.size() > this.k) { + this.minQ.dequeue(); } - return this.heap.peek(); + return this.minQ.front().element; }; -class MinHeap { - constructor(data = []) { - this.data = data; - this.comparator = (a, b) => a - b; - this.heapify(); - } - - heapify() { - if (this.size() < 2) return; - for (let i = 1; i < this.size(); i++) { - this.bubbleUp(i); - } - } - - peek() { - if (this.size() === 0) return null; - return this.data[0]; - } - - offer(value) { - this.data.push(value); - this.bubbleUp(this.size() - 1); - } - - poll() { - if (this.size() === 0) { - return null; - } - const result = this.data[0]; - const last = this.data.pop(); - if (this.size() !== 0) { - this.data[0] = last; - this.bubbleDown(0); - } - return result; - } - - bubbleUp(index) { - while (index > 0) { - const parentIndex = (index - 1) >> 1; - if (this.comparator(this.data[index], this.data[parentIndex]) < 0) { - this.swap(index, parentIndex); - index = parentIndex; - } else { - break; - } - } - } - - bubbleDown(index) { - const lastIndex = this.size() - 1; - while (true) { - const leftIndex = index * 2 + 1; - const rightIndex = index * 2 + 2; - let findIndex = index; - if ( - leftIndex <= lastIndex && - this.comparator(this.data[leftIndex], this.data[findIndex]) < 0 - ) { - findIndex = leftIndex; - } - if ( - rightIndex <= lastIndex && - this.comparator(this.data[rightIndex], this.data[findIndex]) < 0 - ) { - findIndex = rightIndex; - } - if (index !== findIndex) { - this.swap(index, findIndex); - index = findIndex; - } else { - break; - } - } - } - - swap(index1, index2) { - [this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]]; - } - - size() { - return this.data.length; - } -} - /** * Your KthLargest object will be instantiated and called as such: * var obj = new KthLargest(k, nums) diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.py b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.py index d42d92e2bc727..bca67d5b35024 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.py +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.py @@ -1,15 +1,16 @@ class KthLargest: + def __init__(self, k: int, nums: List[int]): - self.q = [] - self.size = k - for num in nums: - self.add(num) + self.k = k + self.min_q = [] + for x in nums: + self.add(x) def add(self, val: int) -> int: - heappush(self.q, val) - if len(self.q) > self.size: - heappop(self.q) - return self.q[0] + heappush(self.min_q, val) + if len(self.min_q) > self.k: + heappop(self.min_q) + return self.min_q[0] # Your KthLargest object will be instantiated and called as such: diff --git a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.ts b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.ts index 31a43e43c589c..6a41d4ae78ca8 100644 --- a/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.ts +++ b/solution/0700-0799/0703.Kth Largest Element in a Stream/Solution.ts @@ -1,23 +1,20 @@ class KthLargest { - #pq = new MinPriorityQueue(); - #k = 0; + #k: number = 0; + #minQ = new MinPriorityQueue(); constructor(k: number, nums: number[]) { this.#k = k; for (const x of nums) { - this.#pq.enqueue(x); - if (this.#pq.size() > k) { - this.#pq.dequeue(); - } + this.add(x); } } add(val: number): number { - this.#pq.enqueue(val); - if (this.#pq.size() > this.#k) { - this.#pq.dequeue(); + this.#minQ.enqueue(val); + if (this.#minQ.size() > this.#k) { + this.#minQ.dequeue(); } - return this.#pq.front().element; + return this.#minQ.front().element; } } diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md b/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md index 53061bd1d0435..ef0363c065522 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/README.md @@ -85,14 +85,13 @@ class Solution: ```java class Solution { - private static final Set VOWELS - = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); - public boolean halvesAreAlike(String s) { - int cnt = 0, n = s.length() >> 1; + Set vowels = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); + int n = s.length() >> 1; + int cnt = 0; for (int i = 0; i < n; ++i) { - cnt += VOWELS.contains(s.charAt(i)) ? 1 : 0; - cnt -= VOWELS.contains(s.charAt(i + n)) ? 1 : 0; + cnt += vowels.contains(s.charAt(i)) ? 1 : 0; + cnt -= vowels.contains(s.charAt(i + n)) ? 1 : 0; } return cnt == 0; } @@ -141,38 +140,36 @@ func halvesAreAlike(s string) bool { ```ts function halvesAreAlike(s: string): boolean { - const set = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']); + const vowels = new Set('aeiouAEIOU'.split('')); + let cnt = 0; const n = s.length >> 1; - let count = 0; - for (let i = 0; i < n; i++) { - set.has(s[i]) && count++; - set.has(s[n + i]) && count--; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]) ? 1 : 0; + cnt -= vowels.has(s[n + i]) ? 1 : 0; } - return count === 0; + return cnt === 0; } ``` #### Rust ```rust -use std::collections::HashSet; impl Solution { pub fn halves_are_alike(s: String) -> bool { - let set: HashSet<&u8> = [b'a', b'e', b'i', b'o', b'u', b'A', b'E', b'I', b'O', b'U'] - .into_iter() - .collect(); - let s = s.as_bytes(); - let n = s.len() >> 1; - let mut count = 0; + let n = s.len() / 2; + let vowels: std::collections::HashSet = "aeiouAEIOU".chars().collect(); + let mut cnt = 0; + for i in 0..n { - if set.contains(&s[i]) { - count += 1; + if vowels.contains(&s.chars().nth(i).unwrap()) { + cnt += 1; } - if set.contains(&s[n + i]) { - count -= 1; + if vowels.contains(&s.chars().nth(i + n).unwrap()) { + cnt -= 1; } } - count == 0 + + cnt == 0 } } ``` @@ -185,11 +182,12 @@ impl Solution { * @return {boolean} */ var halvesAreAlike = function (s) { - const str = 'aeiouAEIOU'; + const vowels = new Set('aeiouAEIOU'.split('')); let cnt = 0; - for (let i = 0; i < s.length / 2; i++) { - if (str.indexOf(s[i]) > -1) cnt++; - if (str.indexOf(s[s.length - 1 - i]) > -1) cnt--; + const n = s.length >> 1; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]); + cnt -= vowels.has(s[n + i]); } return cnt === 0; }; @@ -204,15 +202,19 @@ class Solution { * @return Boolean */ function halvesAreAlike($s) { + $n = strlen($s) / 2; + $vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']; $cnt = 0; - for ($i = 0; $i < strlen($s) / 2; $i++) { - if (strpos('aeiouAEIOU', $s[$i]) !== false) { + + for ($i = 0; $i < $n; $i++) { + if (in_array($s[$i], $vowels)) { $cnt++; } - if (strpos('aeiouAEIOU', $s[strlen($s) / 2 + $i]) !== false) { + if (in_array($s[$i + $n], $vowels)) { $cnt--; } } + return $cnt == 0; } } diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md b/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md index ebf39582eca22..8cb3eed662e24 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/README_EN.md @@ -83,14 +83,13 @@ class Solution: ```java class Solution { - private static final Set VOWELS - = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); - public boolean halvesAreAlike(String s) { - int cnt = 0, n = s.length() >> 1; + Set vowels = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); + int n = s.length() >> 1; + int cnt = 0; for (int i = 0; i < n; ++i) { - cnt += VOWELS.contains(s.charAt(i)) ? 1 : 0; - cnt -= VOWELS.contains(s.charAt(i + n)) ? 1 : 0; + cnt += vowels.contains(s.charAt(i)) ? 1 : 0; + cnt -= vowels.contains(s.charAt(i + n)) ? 1 : 0; } return cnt == 0; } @@ -139,38 +138,36 @@ func halvesAreAlike(s string) bool { ```ts function halvesAreAlike(s: string): boolean { - const set = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']); + const vowels = new Set('aeiouAEIOU'.split('')); + let cnt = 0; const n = s.length >> 1; - let count = 0; - for (let i = 0; i < n; i++) { - set.has(s[i]) && count++; - set.has(s[n + i]) && count--; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]) ? 1 : 0; + cnt -= vowels.has(s[n + i]) ? 1 : 0; } - return count === 0; + return cnt === 0; } ``` #### Rust ```rust -use std::collections::HashSet; impl Solution { pub fn halves_are_alike(s: String) -> bool { - let set: HashSet<&u8> = [b'a', b'e', b'i', b'o', b'u', b'A', b'E', b'I', b'O', b'U'] - .into_iter() - .collect(); - let s = s.as_bytes(); - let n = s.len() >> 1; - let mut count = 0; + let n = s.len() / 2; + let vowels: std::collections::HashSet = "aeiouAEIOU".chars().collect(); + let mut cnt = 0; + for i in 0..n { - if set.contains(&s[i]) { - count += 1; + if vowels.contains(&s.chars().nth(i).unwrap()) { + cnt += 1; } - if set.contains(&s[n + i]) { - count -= 1; + if vowels.contains(&s.chars().nth(i + n).unwrap()) { + cnt -= 1; } } - count == 0 + + cnt == 0 } } ``` @@ -183,11 +180,12 @@ impl Solution { * @return {boolean} */ var halvesAreAlike = function (s) { - const str = 'aeiouAEIOU'; + const vowels = new Set('aeiouAEIOU'.split('')); let cnt = 0; - for (let i = 0; i < s.length / 2; i++) { - if (str.indexOf(s[i]) > -1) cnt++; - if (str.indexOf(s[s.length - 1 - i]) > -1) cnt--; + const n = s.length >> 1; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]); + cnt -= vowels.has(s[n + i]); } return cnt === 0; }; @@ -202,15 +200,19 @@ class Solution { * @return Boolean */ function halvesAreAlike($s) { + $n = strlen($s) / 2; + $vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']; $cnt = 0; - for ($i = 0; $i < strlen($s) / 2; $i++) { - if (strpos('aeiouAEIOU', $s[$i]) !== false) { + + for ($i = 0; $i < $n; $i++) { + if (in_array($s[$i], $vowels)) { $cnt++; } - if (strpos('aeiouAEIOU', $s[strlen($s) / 2 + $i]) !== false) { + if (in_array($s[$i + $n], $vowels)) { $cnt--; } } + return $cnt == 0; } } diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.java b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.java index f8028348bd99f..786c3372f6700 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.java +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.java @@ -1,12 +1,11 @@ class Solution { - private static final Set VOWELS - = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); - public boolean halvesAreAlike(String s) { - int cnt = 0, n = s.length() >> 1; + Set vowels = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); + int n = s.length() >> 1; + int cnt = 0; for (int i = 0; i < n; ++i) { - cnt += VOWELS.contains(s.charAt(i)) ? 1 : 0; - cnt -= VOWELS.contains(s.charAt(i + n)) ? 1 : 0; + cnt += vowels.contains(s.charAt(i)) ? 1 : 0; + cnt -= vowels.contains(s.charAt(i + n)) ? 1 : 0; } return cnt == 0; } diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.js b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.js index e51956882ad44..338c474a02234 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.js +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.js @@ -3,11 +3,12 @@ * @return {boolean} */ var halvesAreAlike = function (s) { - const str = 'aeiouAEIOU'; + const vowels = new Set('aeiouAEIOU'.split('')); let cnt = 0; - for (let i = 0; i < s.length / 2; i++) { - if (str.indexOf(s[i]) > -1) cnt++; - if (str.indexOf(s[s.length - 1 - i]) > -1) cnt--; + const n = s.length >> 1; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]); + cnt -= vowels.has(s[n + i]); } return cnt === 0; }; diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.php b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.php index 7669dc689bf48..5f008f81001ee 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.php +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.php @@ -4,15 +4,19 @@ class Solution { * @return Boolean */ function halvesAreAlike($s) { + $n = strlen($s) / 2; + $vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']; $cnt = 0; - for ($i = 0; $i < strlen($s) / 2; $i++) { - if (strpos('aeiouAEIOU', $s[$i]) !== false) { + + for ($i = 0; $i < $n; $i++) { + if (in_array($s[$i], $vowels)) { $cnt++; } - if (strpos('aeiouAEIOU', $s[strlen($s) / 2 + $i]) !== false) { + if (in_array($s[$i + $n], $vowels)) { $cnt--; } } + return $cnt == 0; } -} +} \ No newline at end of file diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.rs b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.rs index ab7f6a9151ac2..2fba8fff0c1e5 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.rs +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.rs @@ -1,20 +1,18 @@ -use std::collections::HashSet; impl Solution { pub fn halves_are_alike(s: String) -> bool { - let set: HashSet<&u8> = [b'a', b'e', b'i', b'o', b'u', b'A', b'E', b'I', b'O', b'U'] - .into_iter() - .collect(); - let s = s.as_bytes(); - let n = s.len() >> 1; - let mut count = 0; + let n = s.len() / 2; + let vowels: std::collections::HashSet = "aeiouAEIOU".chars().collect(); + let mut cnt = 0; + for i in 0..n { - if set.contains(&s[i]) { - count += 1; + if vowels.contains(&s.chars().nth(i).unwrap()) { + cnt += 1; } - if set.contains(&s[n + i]) { - count -= 1; + if vowels.contains(&s.chars().nth(i + n).unwrap()) { + cnt -= 1; } } - count == 0 + + cnt == 0 } } diff --git a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.ts b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.ts index dbae99a435fcd..b98fb9d2f4050 100644 --- a/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.ts +++ b/solution/1700-1799/1704.Determine if String Halves Are Alike/Solution.ts @@ -1,10 +1,10 @@ function halvesAreAlike(s: string): boolean { - const set = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']); + const vowels = new Set('aeiouAEIOU'.split('')); + let cnt = 0; const n = s.length >> 1; - let count = 0; - for (let i = 0; i < n; i++) { - set.has(s[i]) && count++; - set.has(s[n + i]) && count--; + for (let i = 0; i < n; ++i) { + cnt += vowels.has(s[i]) ? 1 : 0; + cnt -= vowels.has(s[n + i]) ? 1 : 0; } - return count === 0; + return cnt === 0; } diff --git a/solution/1700-1799/1705.Maximum Number of Eaten Apples/README.md b/solution/1700-1799/1705.Maximum Number of Eaten Apples/README.md index 5736d7cce86de..ff94fcbb95525 100644 --- a/solution/1700-1799/1705.Maximum Number of Eaten Apples/README.md +++ b/solution/1700-1799/1705.Maximum Number of Eaten Apples/README.md @@ -73,7 +73,7 @@ tags: 因此,我们可以用优先队列(小根堆)存储苹果的腐烂时间以及对应苹果的数量,每次从优先队列中取出腐烂时间最小的苹果,然后将其数量减一,若减一后苹果的数量不为零,则将其重新放入优先队列中。若苹果已经腐烂,则从优先队列中弹出。 -时间复杂度 $O(n\times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `apples` 或 `days` 的长度。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `apples` 或 `days` 的长度。