Skip to content

[pull] main from doocs:main #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions solution/0700-0799/0705.Design HashSet/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ myHashSet.contains(2); // return False, (already removed)</pre>

<!-- solution:start -->

### Solution 1
### Solution 1: Static Array Implementation

Directly create an array of size $1000001$, initially with each element set to `false`, indicating that the element does not exist in the hash set.

When adding an element to the hash set, set the corresponding position in the array to `true`; when deleting an element, set the corresponding position in the array to `false`; when checking if an element exists, directly return the value at the corresponding position in the array.

The time complexity of the above operations is $O(1)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -227,7 +233,9 @@ class MyHashSet {

<!-- solution:start -->

### Solution 2
### Solution 2: Array of Linked Lists

We can also create an array of size $SIZE=1000$, where each position in the array is a linked list.

<!-- tabs:start -->

Expand Down
171 changes: 93 additions & 78 deletions solution/0700-0799/0713.Subarray Product Less Than K/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,11 @@ tags:

我们可以用双指针维护一个滑动窗口,窗口内所有元素的乘积小于 $k$。

初始时,左右指针都指向下标 0,然后不断地右移右指针,将元素加入窗口,此时判断窗口内所有元素的乘积是否大于等于 $k$,如果大于等于 $k$,则不断地左移左指针,将元素移出窗口,直到窗口内所有元素的乘积小于 $k$。然后我们记录此时的窗口大小,即为以右指针为右端点的满足条件的子数组个数,将其加入答案
定义两个指针 $l$ 和 $r$ 分别指向滑动窗口的左右边界,初始时 $l = r = 0$。我们用一个变量 $p$ 记录窗口内所有元素的乘积,初始时 $p = 1$

当右指针移动到数组末尾时,即可得到答案
每次,我们将 $r$ 右移一位,将 $r$ 指向的元素 $x$ 加入窗口,更新 $p = p \times x$。然后,如果 $p \geq k$,我们循环地将 $l$ 右移一位,并更新 $p = p \div \text{nums}[l]$,直到 $p < k$ 或者 $l \gt r$ 为止。这样,以 $r$ 结尾的、乘积小于 $k$ 的连续子数组的个数即为 $r - l + 1$。然后我们将答案加上这个数量,并继续移动 $r$,直到 $r$ 到达数组的末尾

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。

以下是双指针的常用算法模板:

```java
for (int i = 0, j = 0; i < n; ++i) {
while (j < i && check(j, i)) {
++j;
}
// 具体问题的逻辑
}
```
时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -82,13 +71,14 @@ for (int i = 0, j = 0; i < n; ++i) {
```python
class Solution:
def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
ans, s, j = 0, 1, 0
for i, v in enumerate(nums):
s *= v
while j <= i and s >= k:
s //= nums[j]
j += 1
ans += i - j + 1
ans = l = 0
p = 1
for r, x in enumerate(nums):
p *= x
while l <= r and p >= k:
p //= nums[l]
l += 1
ans += r - l + 1
return ans
```

Expand All @@ -97,13 +87,14 @@ class Solution:
```java
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int ans = 0;
for (int i = 0, j = 0, s = 1; i < nums.length; ++i) {
s *= nums[i];
while (j <= i && s >= k) {
s /= nums[j++];
int ans = 0, l = 0;
int p = 1;
for (int r = 0; r < nums.length; ++r) {
p *= nums[r];
while (l <= r && p >= k) {
p /= nums[l++];
}
ans += i - j + 1;
ans += r - l + 1;
}
return ans;
}
Expand All @@ -116,11 +107,14 @@ class Solution {
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
int ans = 0;
for (int i = 0, j = 0, s = 1; i < nums.size(); ++i) {
s *= nums[i];
while (j <= i && s >= k) s /= nums[j++];
ans += i - j + 1;
int ans = 0, l = 0;
int p = 1;
for (int r = 0; r < nums.size(); ++r) {
p *= nums[r];
while (l <= r && p >= k) {
p /= nums[l++];
}
ans += r - l + 1;
}
return ans;
}
Expand All @@ -130,30 +124,32 @@ public:
#### Go

```go
func numSubarrayProductLessThanK(nums []int, k int) int {
ans := 0
for i, j, s := 0, 0, 1; i < len(nums); i++ {
s *= nums[i]
for ; j <= i && s >= k; j++ {
s /= nums[j]
}
ans += i - j + 1
}
return ans
func numSubarrayProductLessThanK(nums []int, k int) (ans int) {
l, p := 0, 1
for r, x := range nums {
p *= x
for l <= r && p >= k {
p /= nums[l]
l++
}
ans += r - l + 1
}
return
}
```

#### TypeScript

```ts
function numSubarrayProductLessThanK(nums: number[], k: number): number {
let ans = 0;
for (let i = 0, j = 0, s = 1; i < nums.length; ++i) {
s *= nums[i];
while (j <= i && s >= k) {
s /= nums[j++];
const n = nums.length;
let [ans, l, p] = [0, 0, 1];
for (let r = 0; r < n; ++r) {
p *= nums[r];
while (l <= r && p >= k) {
p /= nums[l++];
}
ans += i - j + 1;
ans += r - l + 1;
}
return ans;
}
Expand All @@ -164,22 +160,20 @@ function numSubarrayProductLessThanK(nums: number[], k: number): number {
```rust
impl Solution {
pub fn num_subarray_product_less_than_k(nums: Vec<i32>, k: i32) -> i32 {
if k <= 1 {
return 0;
let mut ans = 0;
let mut l = 0;
let mut p = 1;

for (r, &x) in nums.iter().enumerate() {
p *= x;
while l <= r && p >= k {
p /= nums[l];
l += 1;
}
ans += (r - l + 1) as i32;
}

let mut res = 0;
let mut product = 1;
let mut i = 0;
nums.iter().enumerate().for_each(|(j, v)| {
product *= v;
while product >= k {
product /= nums[i];
i += 1;
}
res += j - i + 1;
});
res as i32
ans
}
}
```
Expand All @@ -194,14 +188,13 @@ impl Solution {
*/
var numSubarrayProductLessThanK = function (nums, k) {
const n = nums.length;
let ans = 0;
let s = 1;
for (let i = 0, j = 0; i < n; ++i) {
s *= nums[i];
while (j <= i && s >= k) {
s = Math.floor(s / nums[j++]);
let [ans, l, p] = [0, 0, 1];
for (let r = 0; r < n; ++r) {
p *= nums[r];
while (l <= r && p >= k) {
p /= nums[l++];
}
ans += i - j + 1;
ans += r - l + 1;
}
return ans;
};
Expand All @@ -212,17 +205,39 @@ var numSubarrayProductLessThanK = function (nums, k) {
```kotlin
class Solution {
fun numSubarrayProductLessThanK(nums: IntArray, k: Int): Int {
var left = 0
var count = 0
var product = 1
nums.forEachIndexed { right, num ->
product *= num
while (product >= k && left <= right) {
product /= nums[left++]
var ans = 0
var l = 0
var p = 1

for (r in nums.indices) {
p *= nums[r]
while (l <= r && p >= k) {
p /= nums[l]
l++
}
ans += r - l + 1
}

return ans
}
}
```

#### C#

```cs
public class Solution {
public int NumSubarrayProductLessThanK(int[] nums, int k) {
int ans = 0, l = 0;
int p = 1;
for (int r = 0; r < nums.Length; ++r) {
p *= nums[r];
while (l <= r && p >= k) {
p /= nums[l++];
}
count += right - left + 1
ans += r - l + 1;
}
return count
return ans;
}
}
```
Expand Down
Loading