diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README.md b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README.md index eae56f2e9f18d..608bb89531c7d 100644 --- a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README.md +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README.md @@ -86,32 +86,144 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3244.Sh -### 方法一 +### 方法一:贪心 + 记录跳转位置 + +我们定义一个长度为 $n - 1$ 的数组 $\textit{nxt}$,其中 $\textit{nxt}[i]$ 表示从城市 $i$ 可以到达的下一个城市的编号。初始时 $\textit{nxt}[i] = i + 1$。 + +对于每次查询 $[u, v]$,如果此前已经连通了 $u'$ 和 $v'$,且 $u' <= u < v <= v'$,那么我们可以跳过这次查询。否则,我们需要将 $nxt[u]$ 到 $nxt[v - 1]$ 这些城市的下一个城市编号设置为 $0$,并将 $nxt[u]$ 设置为 $v$。 + +在这个过程中,我们维护一个变量 $\textit{cnt}$,表示从城市 $0$ 到城市 $n - 1$ 的最短路径的长度。初始时 $\textit{cnt} = n - 1$。每一次,如果我们将 $[\textit{nxt}[u], \textit{v})$ 这些城市的下一个城市编号设置为 $0$,那么 $\textit{cnt}$ 就会减少 $1$。 + +时间复杂度 $O(n + q)$,空间复杂度 $O(n)$。其中 $n$ 和 $q$ 分别是城市数量和查询数量。 #### Python3 ```python - +class Solution: + def shortestDistanceAfterQueries( + self, n: int, queries: List[List[int]] + ) -> List[int]: + nxt = list(range(1, n)) + ans = [] + cnt = n - 1 + for u, v in queries: + if 0 < nxt[u] < v: + i = nxt[u] + while i < v: + cnt -= 1 + nxt[i], i = 0, nxt[i] + nxt[u] = v + ans.append(cnt) + return ans ``` #### Java ```java - +class Solution { + public int[] shortestDistanceAfterQueries(int n, int[][] queries) { + int[] nxt = new int[n - 1]; + for (int i = 1; i < n; ++i) { + nxt[i - 1] = i; + } + int m = queries.length; + int cnt = n - 1; + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + int u = queries[i][0], v = queries[i][1]; + if (nxt[u] > 0 && nxt[u] < v) { + int j = nxt[u]; + while (j < v) { + --cnt; + int t = nxt[j]; + nxt[j] = 0; + j = t; + } + nxt[u] = v; + } + ans[i] = cnt; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector shortestDistanceAfterQueries(int n, vector>& queries) { + vector nxt(n - 1); + iota(nxt.begin(), nxt.end(), 1); + int cnt = n - 1; + vector ans; + for (const auto& q : queries) { + int u = q[0], v = q[1]; + if (nxt[u] && nxt[u] < v) { + int i = nxt[u]; + while (i < v) { + --cnt; + int t = nxt[i]; + nxt[i] = 0; + i = t; + } + nxt[u] = v; + } + ans.push_back(cnt); + } + return ans; + } +}; ``` #### Go ```go +func shortestDistanceAfterQueries(n int, queries [][]int) (ans []int) { + nxt := make([]int, n-1) + for i := range nxt { + nxt[i] = i + 1 + } + cnt := n - 1 + for _, q := range queries { + u, v := q[0], q[1] + if nxt[u] > 0 && nxt[u] < v { + i := nxt[u] + for i < v { + cnt-- + nxt[i], i = 0, nxt[i] + } + nxt[u] = v + } + ans = append(ans, cnt) + } + return +} +``` +#### TypeScript + +```ts +function shortestDistanceAfterQueries(n: number, queries: number[][]): number[] { + const nxt: number[] = Array.from({ length: n - 1 }, (_, i) => i + 1); + const ans: number[] = []; + let cnt = n - 1; + for (const [u, v] of queries) { + if (nxt[u] && nxt[u] < v) { + let i = nxt[u]; + while (i < v) { + --cnt; + [nxt[i], i] = [0, nxt[i]]; + } + nxt[u] = v; + } + ans.push(cnt); + } + return ans; +} ``` diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README_EN.md b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README_EN.md index 12441d6d0e043..dfb8c9df9ae67 100644 --- a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README_EN.md +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/README_EN.md @@ -84,32 +84,144 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3244.Sh -### Solution 1 +### Solution 1: Greedy + Recording Jump Positions + +We define an array $\textit{nxt}$ of length $n - 1$, where $\textit{nxt}[i]$ represents the next city that can be reached from city $i$. Initially, $\textit{nxt}[i] = i + 1$. + +For each query $[u, v]$, if $u'$ and $v'$ have already been connected before, and $u' \leq u < v \leq v'$, then we can skip this query. Otherwise, we need to set the next city number for cities from $\textit{nxt}[u]$ to $\textit{nxt}[v - 1]$ to $0$, and set $\textit{nxt}[u]$ to $v$. + +During this process, we maintain a variable $\textit{cnt}$, which represents the length of the shortest path from city $0$ to city $n - 1$. Initially, $\textit{cnt} = n - 1$. Each time we set the next city number for cities in $[\textit{nxt}[u], \textit{v})$ to $0$, $\textit{cnt}$ decreases by $1$. + +Time complexity is $O(n + q)$, and space complexity is $O(n)$. Here, $n$ and $q$ are the number of cities and the number of queries, respectively. #### Python3 ```python - +class Solution: + def shortestDistanceAfterQueries( + self, n: int, queries: List[List[int]] + ) -> List[int]: + nxt = list(range(1, n)) + ans = [] + cnt = n - 1 + for u, v in queries: + if 0 < nxt[u] < v: + i = nxt[u] + while i < v: + cnt -= 1 + nxt[i], i = 0, nxt[i] + nxt[u] = v + ans.append(cnt) + return ans ``` #### Java ```java - +class Solution { + public int[] shortestDistanceAfterQueries(int n, int[][] queries) { + int[] nxt = new int[n - 1]; + for (int i = 1; i < n; ++i) { + nxt[i - 1] = i; + } + int m = queries.length; + int cnt = n - 1; + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + int u = queries[i][0], v = queries[i][1]; + if (nxt[u] > 0 && nxt[u] < v) { + int j = nxt[u]; + while (j < v) { + --cnt; + int t = nxt[j]; + nxt[j] = 0; + j = t; + } + nxt[u] = v; + } + ans[i] = cnt; + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector shortestDistanceAfterQueries(int n, vector>& queries) { + vector nxt(n - 1); + iota(nxt.begin(), nxt.end(), 1); + int cnt = n - 1; + vector ans; + for (const auto& q : queries) { + int u = q[0], v = q[1]; + if (nxt[u] && nxt[u] < v) { + int i = nxt[u]; + while (i < v) { + --cnt; + int t = nxt[i]; + nxt[i] = 0; + i = t; + } + nxt[u] = v; + } + ans.push_back(cnt); + } + return ans; + } +}; ``` #### Go ```go +func shortestDistanceAfterQueries(n int, queries [][]int) (ans []int) { + nxt := make([]int, n-1) + for i := range nxt { + nxt[i] = i + 1 + } + cnt := n - 1 + for _, q := range queries { + u, v := q[0], q[1] + if nxt[u] > 0 && nxt[u] < v { + i := nxt[u] + for i < v { + cnt-- + nxt[i], i = 0, nxt[i] + } + nxt[u] = v + } + ans = append(ans, cnt) + } + return +} +``` +#### TypeScript + +```ts +function shortestDistanceAfterQueries(n: number, queries: number[][]): number[] { + const nxt: number[] = Array.from({ length: n - 1 }, (_, i) => i + 1); + const ans: number[] = []; + let cnt = n - 1; + for (const [u, v] of queries) { + if (nxt[u] && nxt[u] < v) { + let i = nxt[u]; + while (i < v) { + --cnt; + [nxt[i], i] = [0, nxt[i]]; + } + nxt[u] = v; + } + ans.push(cnt); + } + return ans; +} ``` diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.cpp b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.cpp new file mode 100644 index 0000000000000..e73154187daa2 --- /dev/null +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.cpp @@ -0,0 +1,24 @@ +class Solution { +public: + vector shortestDistanceAfterQueries(int n, vector>& queries) { + vector nxt(n - 1); + iota(nxt.begin(), nxt.end(), 1); + int cnt = n - 1; + vector ans; + for (const auto& q : queries) { + int u = q[0], v = q[1]; + if (nxt[u] && nxt[u] < v) { + int i = nxt[u]; + while (i < v) { + --cnt; + int t = nxt[i]; + nxt[i] = 0; + i = t; + } + nxt[u] = v; + } + ans.push_back(cnt); + } + return ans; + } +}; diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.go b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.go new file mode 100644 index 0000000000000..b3c3be50b9d9b --- /dev/null +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.go @@ -0,0 +1,20 @@ +func shortestDistanceAfterQueries(n int, queries [][]int) (ans []int) { + nxt := make([]int, n-1) + for i := range nxt { + nxt[i] = i + 1 + } + cnt := n - 1 + for _, q := range queries { + u, v := q[0], q[1] + if nxt[u] > 0 && nxt[u] < v { + i := nxt[u] + for i < v { + cnt-- + nxt[i], i = 0, nxt[i] + } + nxt[u] = v + } + ans = append(ans, cnt) + } + return +} diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.java b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.java new file mode 100644 index 0000000000000..ec5ff2e6127c5 --- /dev/null +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.java @@ -0,0 +1,26 @@ +class Solution { + public int[] shortestDistanceAfterQueries(int n, int[][] queries) { + int[] nxt = new int[n - 1]; + for (int i = 1; i < n; ++i) { + nxt[i - 1] = i; + } + int m = queries.length; + int cnt = n - 1; + int[] ans = new int[m]; + for (int i = 0; i < m; ++i) { + int u = queries[i][0], v = queries[i][1]; + if (nxt[u] > 0 && nxt[u] < v) { + int j = nxt[u]; + while (j < v) { + --cnt; + int t = nxt[j]; + nxt[j] = 0; + j = t; + } + nxt[u] = v; + } + ans[i] = cnt; + } + return ans; + } +} diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.py b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.py new file mode 100644 index 0000000000000..6182b7f8214db --- /dev/null +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.py @@ -0,0 +1,16 @@ +class Solution: + def shortestDistanceAfterQueries( + self, n: int, queries: List[List[int]] + ) -> List[int]: + nxt = list(range(1, n)) + ans = [] + cnt = n - 1 + for u, v in queries: + if 0 < nxt[u] < v: + i = nxt[u] + while i < v: + cnt -= 1 + nxt[i], i = 0, nxt[i] + nxt[u] = v + ans.append(cnt) + return ans diff --git a/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.ts b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.ts new file mode 100644 index 0000000000000..6b5cad8cf9205 --- /dev/null +++ b/solution/3200-3299/3244.Shortest Distance After Road Addition Queries II/Solution.ts @@ -0,0 +1,17 @@ +function shortestDistanceAfterQueries(n: number, queries: number[][]): number[] { + const nxt: number[] = Array.from({ length: n - 1 }, (_, i) => i + 1); + const ans: number[] = []; + let cnt = n - 1; + for (const [u, v] of queries) { + if (nxt[u] && nxt[u] < v) { + let i = nxt[u]; + while (i < v) { + --cnt; + [nxt[i], i] = [0, nxt[i]]; + } + nxt[u] = v; + } + ans.push(cnt); + } + return ans; +}