diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/README.md b/solution/2800-2899/2848.Points That Intersect With Cars/README.md index 91b4505bda382..5d5aa7485ac7d 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/README.md +++ b/solution/2800-2899/2848.Points That Intersect With Cars/README.md @@ -60,9 +60,13 @@ tags: ### 方法一:差分数组 -我们创建一个长度为 $110$ 的差分数组 $d$,然后遍历给定的数组,对于每个区间 $[a, b]$,我们令 $d[a]$ 增加 $1$,$d[b + 1]$ 减少 $1$。最后我们遍历差分数组 $d$,求每个位置的前缀和 $s$,如果 $s > 0$,则说明该位置被覆盖,我们将答案增加 $1$。 +根据题目描述,我们需要给每个区间 $[\textit{start}_i, \textit{end}_i]$ 增加一个车辆,我们可以使用差分数组来实现。 -时间复杂度 $O(n)$,空间复杂度 $O(M)$。其中 $n$ 是给定数组的长度,而 $M$ 是数组中元素的最大值。 +我们定义一个长度为 $102$ 的数组 $d$,对于每个区间 $[\textit{start}_i, \textit{end}_i]$,我们将 $d[\textit{start}_i]$ 加 $1$,将 $d[\textit{end}_i + 1]$ 减 $1$。 + +最后,我们对 $d$ 进行前缀和运算,统计前缀和大于 $0$ 的个数即可。 + +时间复杂度 $O(n + m)$,空间复杂度 $O(m)$,其中 $n$ 是给定数组的长度,而 $m$ 是数组中的最大值,本题中 $m \leq 102$。 @@ -71,10 +75,11 @@ tags: ```python class Solution: def numberOfPoints(self, nums: List[List[int]]) -> int: - d = [0] * 110 - for a, b in nums: - d[a] += 1 - d[b + 1] -= 1 + m = 102 + d = [0] * m + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 return sum(s > 0 for s in accumulate(d)) ``` @@ -83,16 +88,17 @@ class Solution: ```java class Solution { public int numberOfPoints(List> nums) { - int[] d = new int[110]; + int[] d = new int[102]; for (var e : nums) { - d[e.get(0)]++; - d[e.get(1) + 1]--; + int start = e.get(0), end = e.get(1); + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { s += x; if (s > 0) { - ans++; + ++ans; } } return ans; @@ -106,10 +112,11 @@ class Solution { class Solution { public: int numberOfPoints(vector>& nums) { - int d[110]{}; - for (auto& e : nums) { - d[e[0]]++; - d[e[1] + 1]--; + int d[102]{}; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { @@ -125,10 +132,11 @@ public: ```go func numberOfPoints(nums [][]int) (ans int) { - d := [110]int{} + d := [102]int{} for _, e := range nums { - d[e[0]]++ - d[e[1]+1]-- + start, end := e[0], e[1] + d[start]++ + d[end+1]-- } s := 0 for _, x := range d { @@ -145,18 +153,147 @@ func numberOfPoints(nums [][]int) (ans int) { ```ts function numberOfPoints(nums: number[][]): number { - const d: number[] = Array(110).fill(0); - for (const [a, b] of nums) { - d[a]++; - d[b + 1]--; + const d: number[] = Array(102).fill(0); + for (const [start, end] of nums) { + ++d[start]; + --d[end + 1]; } let ans = 0; let s = 0; for (const x of d) { s += x; + ans += s > 0 ? 1 : 0; + } + return ans; +} +``` + + + + + + + +### 方法二:哈希表 + 差分 + 排序 + +如果题目的区间范围较大,我们可以使用哈希表来存储区间的起点和终点,然后对哈希表的键进行排序,再进行前缀和统计。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为给定数组的长度。 + + + +#### Python3 + +```python +class Solution: + def numberOfPoints(self, nums: List[List[int]]) -> int: + d = defaultdict(int) + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 + ans = s = last = 0 + for cur, v in sorted(d.items()): + if s > 0: + ans += cur - last + s += v + last = cur + return ans +``` + +#### Java + +```java +class Solution { + public int numberOfPoints(List> nums) { + TreeMap d = new TreeMap<>(); + for (var e : nums) { + int start = e.get(0), end = e.get(1); + d.merge(start, 1, Integer::sum); + d.merge(end + 1, -1, Integer::sum); + } + int ans = 0, s = 0, last = 0; + for (var e : d.entrySet()) { + int cur = e.getKey(), v = e.getValue(); + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int numberOfPoints(vector>& nums) { + map d; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; + } + int ans = 0, s = 0, last = 0; + for (const auto& [cur, v] : d) { + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +}; +``` + +#### Go + +```go +func numberOfPoints(nums [][]int) (ans int) { + d := map[int]int{} + for _, e := range nums { + start, end := e[0], e[1] + d[start]++ + d[end+1]-- + } + keys := []int{} + for k := range d { + keys = append(keys, k) + } + s, last := 0, 0 + sort.Ints(keys) + for _, cur := range keys { + if s > 0 { + ans += cur - last + } + s += d[cur] + last = cur + } + return +} +``` + +#### TypeScript + +```ts +function numberOfPoints(nums: number[][]): number { + const d = new Map(); + for (const [start, end] of nums) { + d.set(start, (d.get(start) || 0) + 1); + d.set(end + 1, (d.get(end + 1) || 0) - 1); + } + const keys = [...d.keys()].sort((a, b) => a - b); + let [ans, s, last] = [0, 0, 0]; + for (const cur of keys) { if (s > 0) { - ans++; + ans += cur - last; } + s += d.get(cur)!; + last = cur; } return ans; } diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/README_EN.md b/solution/2800-2899/2848.Points That Intersect With Cars/README_EN.md index 99356bce138a6..1af69e8c74ab0 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/README_EN.md +++ b/solution/2800-2899/2848.Points That Intersect With Cars/README_EN.md @@ -58,9 +58,13 @@ tags: ### Solution 1: Difference Array -We create a difference array $d$ of length $110$, then traverse the given array. For each interval $[a, b]$, we increase $d[a]$ by $1$ and decrease $d[b + 1]$ by $1$. Finally, we traverse the difference array $d$, calculate the prefix sum $s$ at each position. If $s > 0$, it means that the position is covered, and we increase the answer by $1$. +According to the problem description, we need to add one vehicle to each interval $[\textit{start}_i, \textit{end}_i]$. We can use a difference array to achieve this. -The time complexity is $O(n)$, and the space complexity is $O(M)$. Here, $n$ is the length of the given array, and $M$ is the maximum value in the array. +We define an array $d$ of length 102. For each interval $[\textit{start}_i, \textit{end}_i]$, we increment $d[\textit{start}_i]$ by 1 and decrement $d[\textit{end}_i + 1]$ by 1. + +Finally, we perform a prefix sum operation on $d$ and count the number of elements in the prefix sum that are greater than 0. + +The time complexity is $O(n + m)$, and the space complexity is $O(m)$, where $n$ is the length of the given array, and $m$ is the maximum value in the array. In this problem, $m \leq 102$. @@ -69,10 +73,11 @@ The time complexity is $O(n)$, and the space complexity is $O(M)$. Here, $n$ is ```python class Solution: def numberOfPoints(self, nums: List[List[int]]) -> int: - d = [0] * 110 - for a, b in nums: - d[a] += 1 - d[b + 1] -= 1 + m = 102 + d = [0] * m + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 return sum(s > 0 for s in accumulate(d)) ``` @@ -81,16 +86,17 @@ class Solution: ```java class Solution { public int numberOfPoints(List> nums) { - int[] d = new int[110]; + int[] d = new int[102]; for (var e : nums) { - d[e.get(0)]++; - d[e.get(1) + 1]--; + int start = e.get(0), end = e.get(1); + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { s += x; if (s > 0) { - ans++; + ++ans; } } return ans; @@ -104,10 +110,11 @@ class Solution { class Solution { public: int numberOfPoints(vector>& nums) { - int d[110]{}; - for (auto& e : nums) { - d[e[0]]++; - d[e[1] + 1]--; + int d[102]{}; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { @@ -123,10 +130,11 @@ public: ```go func numberOfPoints(nums [][]int) (ans int) { - d := [110]int{} + d := [102]int{} for _, e := range nums { - d[e[0]]++ - d[e[1]+1]-- + start, end := e[0], e[1] + d[start]++ + d[end+1]-- } s := 0 for _, x := range d { @@ -143,18 +151,147 @@ func numberOfPoints(nums [][]int) (ans int) { ```ts function numberOfPoints(nums: number[][]): number { - const d: number[] = Array(110).fill(0); - for (const [a, b] of nums) { - d[a]++; - d[b + 1]--; + const d: number[] = Array(102).fill(0); + for (const [start, end] of nums) { + ++d[start]; + --d[end + 1]; } let ans = 0; let s = 0; for (const x of d) { s += x; + ans += s > 0 ? 1 : 0; + } + return ans; +} +``` + + + + + + + +### Solution 2: Hash Table + Difference Array + Sorting + +If the range of intervals in the problem is large, we can use a hash table to store the start and end points of the intervals. Then, we sort the keys of the hash table and perform prefix sum statistics. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the given array. + + + +#### Python3 + +```python +class Solution: + def numberOfPoints(self, nums: List[List[int]]) -> int: + d = defaultdict(int) + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 + ans = s = last = 0 + for cur, v in sorted(d.items()): + if s > 0: + ans += cur - last + s += v + last = cur + return ans +``` + +#### Java + +```java +class Solution { + public int numberOfPoints(List> nums) { + TreeMap d = new TreeMap<>(); + for (var e : nums) { + int start = e.get(0), end = e.get(1); + d.merge(start, 1, Integer::sum); + d.merge(end + 1, -1, Integer::sum); + } + int ans = 0, s = 0, last = 0; + for (var e : d.entrySet()) { + int cur = e.getKey(), v = e.getValue(); + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int numberOfPoints(vector>& nums) { + map d; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; + } + int ans = 0, s = 0, last = 0; + for (const auto& [cur, v] : d) { + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +}; +``` + +#### Go + +```go +func numberOfPoints(nums [][]int) (ans int) { + d := map[int]int{} + for _, e := range nums { + start, end := e[0], e[1] + d[start]++ + d[end+1]-- + } + keys := []int{} + for k := range d { + keys = append(keys, k) + } + s, last := 0, 0 + sort.Ints(keys) + for _, cur := range keys { + if s > 0 { + ans += cur - last + } + s += d[cur] + last = cur + } + return +} +``` + +#### TypeScript + +```ts +function numberOfPoints(nums: number[][]): number { + const d = new Map(); + for (const [start, end] of nums) { + d.set(start, (d.get(start) || 0) + 1); + d.set(end + 1, (d.get(end + 1) || 0) - 1); + } + const keys = [...d.keys()].sort((a, b) => a - b); + let [ans, s, last] = [0, 0, 0]; + for (const cur of keys) { if (s > 0) { - ans++; + ans += cur - last; } + s += d.get(cur)!; + last = cur; } return ans; } diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.cpp b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.cpp index e2297454176b9..bf10f4c7c0294 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.cpp +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.cpp @@ -1,10 +1,11 @@ class Solution { public: int numberOfPoints(vector>& nums) { - int d[110]{}; - for (auto& e : nums) { - d[e[0]]++; - d[e[1] + 1]--; + int d[102]{}; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { @@ -13,4 +14,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.go b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.go index 7c606d431d4ba..479135c438406 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.go +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.go @@ -1,8 +1,9 @@ func numberOfPoints(nums [][]int) (ans int) { - d := [110]int{} + d := [102]int{} for _, e := range nums { - d[e[0]]++ - d[e[1]+1]-- + start, end := e[0], e[1] + d[start]++ + d[end+1]-- } s := 0 for _, x := range d { @@ -12,4 +13,4 @@ func numberOfPoints(nums [][]int) (ans int) { } } return -} \ No newline at end of file +} diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.java b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.java index 8e1c6e41f5126..0bce3930d0c07 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.java +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.java @@ -1,17 +1,18 @@ class Solution { public int numberOfPoints(List> nums) { - int[] d = new int[110]; + int[] d = new int[102]; for (var e : nums) { - d[e.get(0)]++; - d[e.get(1) + 1]--; + int start = e.get(0), end = e.get(1); + ++d[start]; + --d[end + 1]; } int ans = 0, s = 0; for (int x : d) { s += x; if (s > 0) { - ans++; + ++ans; } } return ans; } -} \ No newline at end of file +} diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.py b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.py index 787cef40ed9f6..760271e28241a 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.py +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.py @@ -1,7 +1,8 @@ class Solution: def numberOfPoints(self, nums: List[List[int]]) -> int: - d = [0] * 110 - for a, b in nums: - d[a] += 1 - d[b + 1] -= 1 + m = 102 + d = [0] * m + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 return sum(s > 0 for s in accumulate(d)) diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.ts b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.ts index 2fdd2449e89dc..76e59d38e19ba 100644 --- a/solution/2800-2899/2848.Points That Intersect With Cars/Solution.ts +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution.ts @@ -1,16 +1,14 @@ function numberOfPoints(nums: number[][]): number { - const d: number[] = Array(110).fill(0); - for (const [a, b] of nums) { - d[a]++; - d[b + 1]--; + const d: number[] = Array(102).fill(0); + for (const [start, end] of nums) { + ++d[start]; + --d[end + 1]; } let ans = 0; let s = 0; for (const x of d) { s += x; - if (s > 0) { - ans++; - } + ans += s > 0 ? 1 : 0; } return ans; } diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.cpp b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.cpp new file mode 100644 index 0000000000000..8ab3f59803a29 --- /dev/null +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + int numberOfPoints(vector>& nums) { + map d; + for (const auto& e : nums) { + int start = e[0], end = e[1]; + ++d[start]; + --d[end + 1]; + } + int ans = 0, s = 0, last = 0; + for (const auto& [cur, v] : d) { + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +}; diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.go b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.go new file mode 100644 index 0000000000000..1b84b0f19ce88 --- /dev/null +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.go @@ -0,0 +1,22 @@ +func numberOfPoints(nums [][]int) (ans int) { + d := map[int]int{} + for _, e := range nums { + start, end := e[0], e[1] + d[start]++ + d[end+1]-- + } + keys := []int{} + for k := range d { + keys = append(keys, k) + } + s, last := 0, 0 + sort.Ints(keys) + for _, cur := range keys { + if s > 0 { + ans += cur - last + } + s += d[cur] + last = cur + } + return +} diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.java b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.java new file mode 100644 index 0000000000000..b85b730db61bd --- /dev/null +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.java @@ -0,0 +1,20 @@ +class Solution { + public int numberOfPoints(List> nums) { + TreeMap d = new TreeMap<>(); + for (var e : nums) { + int start = e.get(0), end = e.get(1); + d.merge(start, 1, Integer::sum); + d.merge(end + 1, -1, Integer::sum); + } + int ans = 0, s = 0, last = 0; + for (var e : d.entrySet()) { + int cur = e.getKey(), v = e.getValue(); + if (s > 0) { + ans += cur - last; + } + s += v; + last = cur; + } + return ans; + } +} diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.py b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.py new file mode 100644 index 0000000000000..8b6468f085ab7 --- /dev/null +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.py @@ -0,0 +1,13 @@ +class Solution: + def numberOfPoints(self, nums: List[List[int]]) -> int: + d = defaultdict(int) + for start, end in nums: + d[start] += 1 + d[end + 1] -= 1 + ans = s = last = 0 + for cur, v in sorted(d.items()): + if s > 0: + ans += cur - last + s += v + last = cur + return ans diff --git a/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.ts b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.ts new file mode 100644 index 0000000000000..6047911f5b4d0 --- /dev/null +++ b/solution/2800-2899/2848.Points That Intersect With Cars/Solution2.ts @@ -0,0 +1,17 @@ +function numberOfPoints(nums: number[][]): number { + const d = new Map(); + for (const [start, end] of nums) { + d.set(start, (d.get(start) || 0) + 1); + d.set(end + 1, (d.get(end + 1) || 0) - 1); + } + const keys = [...d.keys()].sort((a, b) => a - b); + let [ans, s, last] = [0, 0, 0]; + for (const cur of keys) { + if (s > 0) { + ans += cur - last; + } + s += d.get(cur)!; + last = cur; + } + return ans; +}