Skip to content

[pull] main from doocs:main #201

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 3 commits into from
Mar 25, 2023
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
46 changes: 45 additions & 1 deletion lcp/LCP 11. 期望个数统计/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,66 @@

<!-- 这里可写通用的实现逻辑 -->

**方法一:哈希表**

根据题目描述,我们可以得到如下结论:

如果有 $n$ 个人的能力值相同,每个人有 $n$ 种不同的位置,那么每个人在原位的概率是 $\frac{1}{n}$,那么合起来的期望就是 $1$。

因此,我们只需要统计不同的能力值的个数,即为答案。

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

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def expectNumber(self, scores: List[int]) -> int:
return len(set(scores))
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int expectNumber(int[] scores) {
Set<Integer> s = new HashSet<>();
for (int x : scores) {
s.add(x);
}
return s.size();
}
}
```

### **C++**

```cpp
class Solution {
public:
int expectNumber(vector<int>& scores) {
unordered_set<int> s(scores.begin(), scores.end());
return s.size();
}
};
```

### **Go**

```go
func expectNumber(scores []int) int {
s := map[int]struct{}{}
for _, x := range scores {
s[x] = struct{}{}
}
return len(s)
}
```

### **...**
Expand Down
7 changes: 7 additions & 0 deletions lcp/LCP 11. 期望个数统计/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution {
public:
int expectNumber(vector<int>& scores) {
unordered_set<int> s(scores.begin(), scores.end());
return s.size();
}
};
7 changes: 7 additions & 0 deletions lcp/LCP 11. 期望个数统计/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
func expectNumber(scores []int) int {
s := map[int]struct{}{}
for _, x := range scores {
s[x] = struct{}{}
}
return len(s)
}
6 changes: 3 additions & 3 deletions lcp/LCP 11. 期望个数统计/Solution.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
class Solution {
public int expectNumber(int[] scores) {
Set<Integer> s = new HashSet<>();
for (int v : scores) {
s.add(v);
for (int x : scores) {
s.add(x);
}
return s.size();
}
}
}
126 changes: 125 additions & 1 deletion lcp/LCP 12. 小张刷题计划/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,146 @@

<!-- 这里可写通用的实现逻辑 -->

**方法一:贪心 + 二分查找**

我们可以将题意转换为,将题目最多分成 $m$ 组,每一组去掉最大值后不超过 $T$ ,求最小的满足条件的 $T$。

我们定义二分查找的左边界 $left=0$,右边界 $right=\sum_{i=0}^{n-1}time[i]$,二分查找的目标值为 $T$。

我们定义函数 $check(T)$,表示是否存在一种分组方案,使得每一组去掉最大值后不超过 $T$,并且分组数不超过 $m$。

我们可以用贪心的方法来判断是否存在这样的分组方案。我们从左到右遍历题目,将题目耗时加入当前总耗时 $s$,并更新当前分组的最大值 $mx$。如果当前总耗时 $s$ 减去当前分组的最大值 $mx$ 大于 $T$,则将当前题目作为新的分组的第一题,更新 $s$ 和 $mx$。继续遍历题目,直到遍历完所有题目。如果分组数不超过 $m$,则说明存在这样的分组方案,返回 $true$,否则返回 $false$。

时间复杂度 $O(n \times \log S)$,空间复杂度 $O(1)$。其中 $n$ 和 $S$ 分别为题目数量和题目总耗时。

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def minTime(self, time: List[int], m: int) -> int:
def check(t):
s = mx = 0
d = 1
for x in time:
s += x
mx = max(mx, x)
if s - mx > t:
d += 1
s = mx = x
return d <= m

return bisect_left(range(sum(time)), True, key=check)
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int minTime(int[] time, int m) {
int left = 0, right = 0;
for (int x : time) {
right += x;
}
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid, time, m)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}

private boolean check(int t, int[] time, int m) {
int s = 0, mx = 0;
int d = 1;
for (int x : time) {
s += x;
mx = Math.max(mx, x);
if (s - mx > t) {
s = x;
mx = x;
++d;
}
}
return d <= m;
}
}
```

### **C++**

```cpp
class Solution {
public:
int minTime(vector<int>& time, int m) {
int left = 0, right = 0;
for (int x : time) {
right += x;
}
auto check = [&](int t) -> bool {
int s = 0, mx = 0;
int d = 1;
for (int x : time) {
s += x;
mx = max(mx, x);
if (s - mx > t) {
s = x;
mx = x;
++d;
}
}
return d <= m;
};
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};
```

### **Go**

```go
func minTime(time []int, m int) int {
right := 0
for _, x := range time {
right += x
}
return sort.Search(right, func(t int) bool {
s, mx := 0, 0
d := 1
for _, x := range time {
s += x
mx = max(mx, x)
if s-mx > t {
s, mx = x, x
d++
}
}
return d <= m
})
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

### **...**
Expand Down
32 changes: 32 additions & 0 deletions lcp/LCP 12. 小张刷题计划/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Solution {
public:
int minTime(vector<int>& time, int m) {
int left = 0, right = 0;
for (int x : time) {
right += x;
}
auto check = [&](int t) -> bool {
int s = 0, mx = 0;
int d = 1;
for (int x : time) {
s += x;
mx = max(mx, x);
if (s - mx > t) {
s = x;
mx = x;
++d;
}
}
return d <= m;
};
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};
26 changes: 26 additions & 0 deletions lcp/LCP 12. 小张刷题计划/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
func minTime(time []int, m int) int {
right := 0
for _, x := range time {
right += x
}
return sort.Search(right, func(t int) bool {
s, mx := 0, 0
d := 1
for _, x := range time {
s += x
mx = max(mx, x)
if s-mx > t {
s, mx = x, x
d++
}
}
return d <= m
})
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
32 changes: 32 additions & 0 deletions lcp/LCP 12. 小张刷题计划/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Solution {
public int minTime(int[] time, int m) {
int left = 0, right = 0;
for (int x : time) {
right += x;
}
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid, time, m)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}

private boolean check(int t, int[] time, int m) {
int s = 0, mx = 0;
int d = 1;
for (int x : time) {
s += x;
mx = Math.max(mx, x);
if (s - mx > t) {
s = x;
mx = x;
++d;
}
}
return d <= m;
}
}
14 changes: 14 additions & 0 deletions lcp/LCP 12. 小张刷题计划/Solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution:
def minTime(self, time: List[int], m: int) -> int:
def check(t):
s = mx = 0
d = 1
for x in time:
s += x
mx = max(mx, x)
if s - mx > t:
d += 1
s = mx = x
return d <= m

return bisect_left(range(sum(time)), True, key=check)
Loading