diff --git a/lcci/16.10.Living People/README.md b/lcci/16.10.Living People/README.md
index 211a2e9157429..b2c1bc119ae7a 100644
--- a/lcci/16.10.Living People/README.md
+++ b/lcci/16.10.Living People/README.md
@@ -5,6 +5,7 @@
## 题目描述
+
给定N个人的出生年份和死亡年份,第i
个人的出生年份为birth[i]
,死亡年份为death[i]
,实现一个方法以计算生存人数最多的年份。
你可以假设所有人都出生于1900年至2000年(含1900和2000)之间。如果一个人在某一年的任意时期都处于生存状态,那么他们应该被纳入那一年的统计中。例如,生于1908年、死于1909年的人应当被列入1908年和1909年的计数。
如果有多个年份生存人数相同且均为最大值,输出其中最小的年份。
@@ -24,13 +25,15 @@ death = {1948, 1951, 2000}
-不在乎某个区间,而是某一年的最多存活人数。
+**方法一:差分数组**
+
+题目实际上是对一个连续的区间进行加减操作,然后求最大值。这种情况下可以使用差分数组来解决。
-可以使用哈希表来统计每年的存活人数,当 `birth[i] >= year && year <= death[i]`,该年份的存活人数加一。
+由于题目中的年份范围是固定的,所以可以使用一个长度为 $102$ 的数组来表示 $1900$ 年到 $2000$ 年的人口变化情况。数组中的每个元素表示该年份的人口变化,正数表示出生人数,负数表示死亡人数。
-> 只有 `birth` 和 `death` 当中的出现过的年份才是有效年份,或者说,可能成为返回值的年份。
+遍历每个人的出生年份和死亡年份,对应的年份的人口变化加一和减一。然后遍历差分数组,求出差分数组的前缀和的最大值,最大值对应的年份即为答案。
-题目当中已说明年份范围是 `1900 ~ 2000`,对此也可以使用数组进行计数(`year - 1900`)。
+时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 是出生年份和死亡年份的长度,而 $C$ 是年份的范围。
@@ -41,19 +44,19 @@ death = {1948, 1951, 2000}
```python
class Solution:
def maxAliveYear(self, birth: List[int], death: List[int]) -> int:
- years = [0] * 101
- for i in range(len(birth)):
- start = birth[i] - 1900
- end = death[i] - 1900
- for j in range(start, end + 1):
- years[j] += 1
- max_v = years[0]
- res = 0
- for i in range(1, 101):
- if years[i] > max_v:
- max_v = years[i]
- res = i
- return 1900 + res
+ base = 1900
+ d = [0] * 102
+ for a, b in zip(birth, death):
+ d[a - base] += 1
+ d[b + 1 - base] -= 1
+ s = mx = 0
+ ans = 0
+ for i, x in enumerate(d):
+ s += x
+ if mx < s:
+ mx = s
+ ans = base + i
+ return ans
```
### **Java**
@@ -63,25 +66,77 @@ class Solution:
```java
class Solution {
public int maxAliveYear(int[] birth, int[] death) {
- int[] years = new int[101];
- int n = birth.length;
- for (int i = 0; i < n; ++i) {
- int start = birth[i] - 1900;
- int end = death[i] - 1900;
- for (int j = start; j <= end; ++j) {
- ++years[j];
+ int base = 1900;
+ int[] d = new int[102];
+ for (int i = 0; i < birth.length; ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- int max = years[0];
- int res = 0;
- for (int i = 1; i < 101; ++i) {
- if (years[i] > max) {
- max = years[i];
- res = i;
+ return ans;
+ }
+}
+```
+
+### **C++**
+
+```cpp
+class Solution {
+public:
+ int maxAliveYear(vector& birth, vector& death) {
+ int base = 1900;
+ int d[102]{};
+ for (int i = 0; i < birth.size(); ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < 102; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- return 1900 + res;
+ return ans;
}
+};
+```
+
+### **Go**
+
+```go
+func maxAliveYear(birth []int, death []int) (ans int) {
+ base := 1900
+ d := [102]int{}
+ for i, a := range birth {
+ a -= base
+ b := death[i] - base
+ d[a]++
+ d[b+1]--
+ }
+ mx, s := 0, 0
+ for i, x := range d {
+ s += x
+ if mx < s {
+ mx = s
+ ans = base + i
+ }
+ }
+ return
}
```
@@ -89,32 +144,23 @@ class Solution {
```ts
function maxAliveYear(birth: number[], death: number[]): number {
- const n = birth.length;
- const counter = new Map();
- for (let i = 0; i < n; i++) {
- counter.set(birth[i], 0);
- counter.set(death[i], 0);
+ const base = 1900;
+ const d: number[] = Array(102).fill(0);
+ for (let i = 0; i < birth.length; ++i) {
+ const [a, b] = [birth[i] - base, death[i] - base];
+ ++d[a];
+ --d[b + 1];
}
- for (let i = 0; i < n; i++) {
- const start = birth[i];
- const end = death[i];
- for (const key of counter.keys()) {
- if (key >= start && key <= end) {
- counter.set(key, (counter.get(key) ?? 0) + 1);
- }
- }
- }
- let res = 0;
- let max = 0;
- for (const [key, val] of counter) {
- if (val === max) {
- res = Math.min(res, key);
- } else if (val > max) {
- res = key;
- max = Math.max(max, val);
+ let [s, mx] = [0, 0];
+ let ans = 0;
+ for (let i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- return res;
+ return ans;
}
```
@@ -124,22 +170,23 @@ function maxAliveYear(birth: number[], death: number[]): number {
impl Solution {
pub fn max_alive_year(birth: Vec, death: Vec) -> i32 {
let n = birth.len();
- let mut counter = vec![0; 101];
+ let mut d = vec![0; 102];
+ let base = 1900;
for i in 0..n {
- let (start, end) = (birth[i] - 1900, death[i] - 1900);
- for j in start..=end {
- counter[j as usize] += 1;
- }
+ d[(birth[i] - base) as usize] += 1;
+ d[(death[i] - base + 1) as usize] -= 1;
}
- let mut res = 0;
- let mut max = 0;
- for (i, count) in counter.iter().enumerate() {
- if *count > max {
- res = i;
- max = *count;
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut s = 0;
+ for i in 0..102 {
+ s += d[i];
+ if mx < s {
+ mx = s;
+ ans = base + i as i32;
}
}
- (res + 1900) as i32
+ ans
}
}
```
diff --git a/lcci/16.10.Living People/README_EN.md b/lcci/16.10.Living People/README_EN.md
index 6e1af1be7d688..6523c8b611343 100644
--- a/lcci/16.10.Living People/README_EN.md
+++ b/lcci/16.10.Living People/README_EN.md
@@ -31,6 +31,16 @@ death = {1948, 1951, 2000}
## Solutions
+**Solution 1: Difference Array**
+
+The problem is actually about performing addition and subtraction operations on a continuous interval, and then finding the maximum value. This can be solved using a difference array.
+
+Since the year range in the problem is fixed, we can use an array of length $102$ to represent the population changes from 1900 to 2000. Each element in the array represents the population change in that year, with positive numbers indicating the number of births and negative numbers indicating the number of deaths.
+
+We traverse the birth and death years of each person, and add one and subtract one from the corresponding year's population change, respectively. Then we traverse the difference array, and find the maximum value of the prefix sum of the difference array. The year corresponding to the maximum value is the answer.
+
+The time complexity is $O(n)$, and the space complexity is $O(C)$. Here, $n$ is the length of the birth and death years, and $C$ is the range of years.
+
### **Python3**
@@ -38,19 +48,19 @@ death = {1948, 1951, 2000}
```python
class Solution:
def maxAliveYear(self, birth: List[int], death: List[int]) -> int:
- years = [0] * 101
- for i in range(len(birth)):
- start = birth[i] - 1900
- end = death[i] - 1900
- for j in range(start, end + 1):
- years[j] += 1
- max_v = years[0]
- res = 0
- for i in range(1, 101):
- if years[i] > max_v:
- max_v = years[i]
- res = i
- return 1900 + res
+ base = 1900
+ d = [0] * 102
+ for a, b in zip(birth, death):
+ d[a - base] += 1
+ d[b + 1 - base] -= 1
+ s = mx = 0
+ ans = 0
+ for i, x in enumerate(d):
+ s += x
+ if mx < s:
+ mx = s
+ ans = base + i
+ return ans
```
### **Java**
@@ -58,25 +68,77 @@ class Solution:
```java
class Solution {
public int maxAliveYear(int[] birth, int[] death) {
- int[] years = new int[101];
- int n = birth.length;
- for (int i = 0; i < n; ++i) {
- int start = birth[i] - 1900;
- int end = death[i] - 1900;
- for (int j = start; j <= end; ++j) {
- ++years[j];
+ int base = 1900;
+ int[] d = new int[102];
+ for (int i = 0; i < birth.length; ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- int max = years[0];
- int res = 0;
- for (int i = 1; i < 101; ++i) {
- if (years[i] > max) {
- max = years[i];
- res = i;
+ return ans;
+ }
+}
+```
+
+### **C++**
+
+```cpp
+class Solution {
+public:
+ int maxAliveYear(vector& birth, vector& death) {
+ int base = 1900;
+ int d[102]{};
+ for (int i = 0; i < birth.size(); ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < 102; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- return 1900 + res;
+ return ans;
}
+};
+```
+
+### **Go**
+
+```go
+func maxAliveYear(birth []int, death []int) (ans int) {
+ base := 1900
+ d := [102]int{}
+ for i, a := range birth {
+ a -= base
+ b := death[i] - base
+ d[a]++
+ d[b+1]--
+ }
+ mx, s := 0, 0
+ for i, x := range d {
+ s += x
+ if mx < s {
+ mx = s
+ ans = base + i
+ }
+ }
+ return
}
```
@@ -84,32 +146,23 @@ class Solution {
```ts
function maxAliveYear(birth: number[], death: number[]): number {
- const n = birth.length;
- const counter = new Map();
- for (let i = 0; i < n; i++) {
- counter.set(birth[i], 0);
- counter.set(death[i], 0);
+ const base = 1900;
+ const d: number[] = Array(102).fill(0);
+ for (let i = 0; i < birth.length; ++i) {
+ const [a, b] = [birth[i] - base, death[i] - base];
+ ++d[a];
+ --d[b + 1];
}
- for (let i = 0; i < n; i++) {
- const start = birth[i];
- const end = death[i];
- for (const key of counter.keys()) {
- if (key >= start && key <= end) {
- counter.set(key, (counter.get(key) ?? 0) + 1);
- }
- }
- }
- let res = 0;
- let max = 0;
- for (const [key, val] of counter) {
- if (val === max) {
- res = Math.min(res, key);
- } else if (val > max) {
- res = key;
- max = Math.max(max, val);
+ let [s, mx] = [0, 0];
+ let ans = 0;
+ for (let i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- return res;
+ return ans;
}
```
@@ -119,22 +172,23 @@ function maxAliveYear(birth: number[], death: number[]): number {
impl Solution {
pub fn max_alive_year(birth: Vec, death: Vec) -> i32 {
let n = birth.len();
- let mut counter = vec![0; 101];
+ let mut d = vec![0; 102];
+ let base = 1900;
for i in 0..n {
- let (start, end) = (birth[i] - 1900, death[i] - 1900);
- for j in start..=end {
- counter[j as usize] += 1;
- }
+ d[(birth[i] - base) as usize] += 1;
+ d[(death[i] - base + 1) as usize] -= 1;
}
- let mut res = 0;
- let mut max = 0;
- for (i, count) in counter.iter().enumerate() {
- if *count > max {
- res = i;
- max = *count;
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut s = 0;
+ for i in 0..102 {
+ s += d[i];
+ if mx < s {
+ mx = s;
+ ans = base + i as i32;
}
}
- (res + 1900) as i32
+ ans
}
}
```
diff --git a/lcci/16.10.Living People/Solution.cpp b/lcci/16.10.Living People/Solution.cpp
new file mode 100644
index 0000000000000..4631e89718cfb
--- /dev/null
+++ b/lcci/16.10.Living People/Solution.cpp
@@ -0,0 +1,23 @@
+class Solution {
+public:
+ int maxAliveYear(vector& birth, vector& death) {
+ int base = 1900;
+ int d[102]{};
+ for (int i = 0; i < birth.size(); ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < 102; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
+ }
+ }
+ return ans;
+ }
+};
\ No newline at end of file
diff --git a/lcci/16.10.Living People/Solution.go b/lcci/16.10.Living People/Solution.go
new file mode 100644
index 0000000000000..0563862cf2e8e
--- /dev/null
+++ b/lcci/16.10.Living People/Solution.go
@@ -0,0 +1,19 @@
+func maxAliveYear(birth []int, death []int) (ans int) {
+ base := 1900
+ d := [102]int{}
+ for i, a := range birth {
+ a -= base
+ b := death[i] - base
+ d[a]++
+ d[b+1]--
+ }
+ mx, s := 0, 0
+ for i, x := range d {
+ s += x
+ if mx < s {
+ mx = s
+ ans = base + i
+ }
+ }
+ return
+}
\ No newline at end of file
diff --git a/lcci/16.10.Living People/Solution.java b/lcci/16.10.Living People/Solution.java
index f19dd8696bb57..6b442114cbc11 100644
--- a/lcci/16.10.Living People/Solution.java
+++ b/lcci/16.10.Living People/Solution.java
@@ -1,22 +1,22 @@
-class Solution {
- public int maxAliveYear(int[] birth, int[] death) {
- int[] years = new int[101];
- int n = birth.length;
- for (int i = 0; i < n; ++i) {
- int start = birth[i] - 1900;
- int end = death[i] - 1900;
- for (int j = start; j <= end; ++j) {
- ++years[j];
- }
- }
- int max = years[0];
- int res = 0;
- for (int i = 1; i < 101; ++i) {
- if (years[i] > max) {
- max = years[i];
- res = i;
- }
- }
- return 1900 + res;
- }
+class Solution {
+ public int maxAliveYear(int[] birth, int[] death) {
+ int base = 1900;
+ int[] d = new int[102];
+ for (int i = 0; i < birth.length; ++i) {
+ int a = birth[i] - base;
+ int b = death[i] - base;
+ ++d[a];
+ --d[b + 1];
+ }
+ int s = 0, mx = 0;
+ int ans = 0;
+ for (int i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
+ }
+ }
+ return ans;
+ }
}
\ No newline at end of file
diff --git a/lcci/16.10.Living People/Solution.py b/lcci/16.10.Living People/Solution.py
index 6600280f9acba..be2b910ba7ed5 100644
--- a/lcci/16.10.Living People/Solution.py
+++ b/lcci/16.10.Living People/Solution.py
@@ -1,15 +1,15 @@
-class Solution:
- def maxAliveYear(self, birth: List[int], death: List[int]) -> int:
- years = [0] * 101
- for i in range(len(birth)):
- start = birth[i] - 1900
- end = death[i] - 1900
- for j in range(start, end + 1):
- years[j] += 1
- max_v = years[0]
- res = 0
- for i in range(1, 101):
- if years[i] > max_v:
- max_v = years[i]
- res = i
- return 1900 + res
+class Solution:
+ def maxAliveYear(self, birth: List[int], death: List[int]) -> int:
+ base = 1900
+ d = [0] * 102
+ for a, b in zip(birth, death):
+ d[a - base] += 1
+ d[b + 1 - base] -= 1
+ s = mx = 0
+ ans = 0
+ for i, x in enumerate(d):
+ s += x
+ if mx < s:
+ mx = s
+ ans = base + i
+ return ans
diff --git a/lcci/16.10.Living People/Solution.rs b/lcci/16.10.Living People/Solution.rs
index 68e83122683f8..e9023a5fd3496 100644
--- a/lcci/16.10.Living People/Solution.rs
+++ b/lcci/16.10.Living People/Solution.rs
@@ -1,21 +1,22 @@
-impl Solution {
- pub fn max_alive_year(birth: Vec, death: Vec) -> i32 {
- let n = birth.len();
- let mut counter = vec![0; 101];
- for i in 0..n {
- let (start, end) = (birth[i] - 1900, death[i] - 1900);
- for j in start..=end {
- counter[j as usize] += 1;
- }
- }
- let mut res = 0;
- let mut max = 0;
- for (i, count) in counter.iter().enumerate() {
- if *count > max {
- res = i;
- max = *count;
- }
- }
- (res + 1900) as i32
- }
-}
+impl Solution {
+ pub fn max_alive_year(birth: Vec, death: Vec) -> i32 {
+ let n = birth.len();
+ let mut d = vec![0; 102];
+ let base = 1900;
+ for i in 0..n {
+ d[(birth[i] - base) as usize] += 1;
+ d[(death[i] - base + 1) as usize] -= 1;
+ }
+ let mut ans = 0;
+ let mut mx = 0;
+ let mut s = 0;
+ for i in 0..102 {
+ s += d[i];
+ if mx < s {
+ mx = s;
+ ans = base + i as i32;
+ }
+ }
+ ans
+ }
+}
\ No newline at end of file
diff --git a/lcci/16.10.Living People/Solution.ts b/lcci/16.10.Living People/Solution.ts
index 5024db193a5b9..c9b0aa4daaa88 100644
--- a/lcci/16.10.Living People/Solution.ts
+++ b/lcci/16.10.Living People/Solution.ts
@@ -1,28 +1,19 @@
function maxAliveYear(birth: number[], death: number[]): number {
- const n = birth.length;
- const counter = new Map();
- for (let i = 0; i < n; i++) {
- counter.set(birth[i], 0);
- counter.set(death[i], 0);
+ const base = 1900;
+ const d: number[] = Array(102).fill(0);
+ for (let i = 0; i < birth.length; ++i) {
+ const [a, b] = [birth[i] - base, death[i] - base];
+ ++d[a];
+ --d[b + 1];
}
- for (let i = 0; i < n; i++) {
- const start = birth[i];
- const end = death[i];
- for (const key of counter.keys()) {
- if (key >= start && key <= end) {
- counter.set(key, (counter.get(key) ?? 0) + 1);
- }
+ let [s, mx] = [0, 0];
+ let ans = 0;
+ for (let i = 0; i < d.length; ++i) {
+ s += d[i];
+ if (mx < s) {
+ mx = s;
+ ans = base + i;
}
}
- let res = 0;
- let max = 0;
- for (const [key, val] of counter) {
- if (val === max) {
- res = Math.min(res, key);
- } else if (val > max) {
- res = key;
- max = Math.max(max, val);
- }
- }
- return res;
+ return ans;
}
diff --git a/lcci/16.11.Diving Board/README.md b/lcci/16.11.Diving Board/README.md
index 469058997e4f9..2af794e3f19e7 100644
--- a/lcci/16.11.Diving Board/README.md
+++ b/lcci/16.11.Diving Board/README.md
@@ -99,6 +99,24 @@ func divingBoard(shorter int, longer int, k int) []int {
}
```
+### **TypeScript**
+
+```ts
+function divingBoard(shorter: number, longer: number, k: number): number[] {
+ if (k === 0) {
+ return [];
+ }
+ if (longer === shorter) {
+ return [longer * k];
+ }
+ const ans: number[] = [k + 1];
+ for (let i = 0; i <= k; ++i) {
+ ans[i] = longer * i + shorter * (k - i);
+ }
+ return ans;
+}
+```
+
### **...**
```
diff --git a/lcci/16.11.Diving Board/README_EN.md b/lcci/16.11.Diving Board/README_EN.md
index eb0ed96fb05ed..40525feff230f 100644
--- a/lcci/16.11.Diving Board/README_EN.md
+++ b/lcci/16.11.Diving Board/README_EN.md
@@ -104,6 +104,24 @@ func divingBoard(shorter int, longer int, k int) []int {
}
```
+### **TypeScript**
+
+```ts
+function divingBoard(shorter: number, longer: number, k: number): number[] {
+ if (k === 0) {
+ return [];
+ }
+ if (longer === shorter) {
+ return [longer * k];
+ }
+ const ans: number[] = [k + 1];
+ for (let i = 0; i <= k; ++i) {
+ ans[i] = longer * i + shorter * (k - i);
+ }
+ return ans;
+}
+```
+
### **...**
```
diff --git a/lcci/16.11.Diving Board/Solution.ts b/lcci/16.11.Diving Board/Solution.ts
new file mode 100644
index 0000000000000..59b74c586759f
--- /dev/null
+++ b/lcci/16.11.Diving Board/Solution.ts
@@ -0,0 +1,13 @@
+function divingBoard(shorter: number, longer: number, k: number): number[] {
+ if (k === 0) {
+ return [];
+ }
+ if (longer === shorter) {
+ return [longer * k];
+ }
+ const ans: number[] = [k + 1];
+ for (let i = 0; i <= k; ++i) {
+ ans[i] = longer * i + shorter * (k - i);
+ }
+ return ans;
+}