diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md index 99647ecbac9fb..d687e51498635 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md @@ -55,70 +55,13 @@ source 和 target 间的汉明距离是 2 ,二者有 2 处元素不同,在 -并查集。 +**方法一:并查集 + 哈希表** -模板 1——朴素并查集: - -```python -# 初始化,p存储每个点的父节点 -p = list(range(n)) - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - # 路径压缩 - p[x] = find(p[x]) - return p[x] - - -# 合并a和b所在的两个集合 -p[find(a)] = find(b) -``` - -模板 2——维护 size 的并查集: - -```python -# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量 -p = list(range(n)) -size = [1] * n - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - # 路径压缩 - p[x] = find(p[x]) - return p[x] +我们可以将每个下标看作一个节点,每个下标对应的元素看作节点的值,那么给定的 `allowedSwaps` 中的每个元素 `[a_i, b_i]` 就表示下标 `a_i` 和 `b_i` 之间存在一条边。因此,我们可以使用并查集来维护这些连通分量。 +在得到每个连通分量之后,我们再用二维哈希表 $cnt$ 分别统计每个连通分量中每个元素出现的次数,最后对于数组 `target` 中的每个元素,如果其在对应的连通分量中出现的次数大于 0,则将其出现次数减 1,否则将答案加 1。 -# 合并a和b所在的两个集合 -if find(a) != find(b): - size[find(b)] += size[find(a)] - p[find(a)] = find(b) -``` - -模板 3——维护到祖宗节点距离的并查集: - -```python -# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离 -p = list(range(n)) -d = [0] * n - - -# 返回x的祖宗节点 -def find(x): - if p[x] != x: - t = find(p[x]) - d[x] += d[p[x]] - p[x] = t - return p[x] - - -# 合并a和b所在的两个集合 -p[find(a)] = find(b) -d[find(a)] = distance -``` +时间复杂度 $O(n \times \log n)$ 或 $O(n \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度,而 $\alpha$ 是阿克曼函数的反函数。 @@ -131,27 +74,25 @@ class Solution: def minimumHammingDistance( self, source: List[int], target: List[int], allowedSwaps: List[List[int]] ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans ``` ### **Java** @@ -165,28 +106,26 @@ class Solution { public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { int n = source.length; p = new int[n]; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; i++) { p[i] = i; } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); } - Map> mp = new HashMap<>(); + Map> cnt = new HashMap<>(); for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); } - int res = 0; + int ans = 0; for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; } } - return res; + return ans; } private int find(int x) { @@ -203,28 +142,27 @@ class Solution { ```cpp class Solution { public: - vector p; - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; + ++cnt[find(i)][source[i]]; } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; } }; ``` @@ -232,40 +170,79 @@ public: ### **Go** ```go -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) + } + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } - mp[find(i)][source[i]]++ + cnt[j][x]++ } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ } } - return res + return } +``` -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) - } - return p[x] +### **TypeScript** + +```ts +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md index 50d27fafc732f..6be207e77fa02 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md @@ -53,7 +53,13 @@ The Hamming distance of source and target is 2 as they differ in 2 positions: in ## Solutions -Union find. +**Solution 1: Union-Find + Hash Table** + +We can consider each index as a node, and the element corresponding to each index as the value of the node. Then each element `[a_i, b_i]` in the given `allowedSwaps` represents an edge between index `a_i` and `b_i`. Therefore, we can use a union-find set to maintain these connected components. + +After obtaining each connected component, we use a two-dimensional hash table $cnt$ to count the number of occurrences of each element in each connected component. Finally, for each element in the array `target`, if its occurrence count in the corresponding connected component is greater than 0, we decrease its count by 1, otherwise, we increase the answer by 1. + +The time complexity is $O(n \times \log n)$ or $O(n \times \alpha(n))$, and the space complexity is $O(n)$. Here, $n$ is the length of the array, and $\alpha$ is the inverse Ackermann function. @@ -64,27 +70,25 @@ class Solution: def minimumHammingDistance( self, source: List[int], target: List[int], allowedSwaps: List[List[int]] ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans ``` ### **Java** @@ -96,28 +100,26 @@ class Solution { public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { int n = source.length; p = new int[n]; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; i++) { p[i] = i; } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); } - Map> mp = new HashMap<>(); + Map> cnt = new HashMap<>(); for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); } - int res = 0; + int ans = 0; for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; } } - return res; + return ans; } private int find(int x) { @@ -134,28 +136,27 @@ class Solution { ```cpp class Solution { public: - vector p; - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; + ++cnt[find(i)][source[i]]; } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; } }; ``` @@ -163,40 +164,79 @@ public: ### **Go** ```go -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) + } + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } - mp[find(i)][source[i]]++ + cnt[j][x]++ } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ } } - return res + return } +``` -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) - } - return p[x] +### **TypeScript** + +```ts +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp index 1fc9aeb7ad077..9f06ac04c126a 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.cpp @@ -1,26 +1,25 @@ -class Solution { -public: - vector p; - - int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { - int n = source.size(); - p.resize(n); - for (int i = 0; i < n; ++i) p[i] = i; - for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]); - unordered_map> mp; - for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]]; - int res = 0; - for (int i = 0; i < n; ++i) { - if (mp[find(i)][target[i]] > 0) - --mp[find(i)][target[i]]; - else - ++res; - } - return res; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; - } +class Solution { +public: + int minimumHammingDistance(vector& source, vector& target, vector>& allowedSwaps) { + int n = source.size(); + vector p(n); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return x == p[x] ? x : p[x] = find(p[x]); + }; + for (auto& a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + unordered_map> cnt; + for (int i = 0; i < n; ++i) { + ++cnt[find(i)][source[i]]; + } + int ans = 0; + for (int i = 0; i < n; ++i) { + if (--cnt[find(i)][target[i]] < 0) { + ++ans; + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go index 0e6a2a7a417cd..162a8bf95de26 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.go @@ -1,35 +1,33 @@ -var p []int - -func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int { +func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) (ans int) { n := len(source) - p = make([]int, n) - for i := 0; i < n; i++ { + p := make([]int, n) + for i := range p { p[i] = i } - for _, e := range allowedSwaps { - p[find(e[0])] = find(e[1]) - } - mp := make(map[int]map[int]int) - for i := 0; i < n; i++ { - if mp[find(i)] == nil { - mp[find(i)] = make(map[int]int) + var find func(int) int + find = func(x int) int { + if p[x] != x { + p[x] = find(p[x]) } - mp[find(i)][source[i]]++ + return p[x] + } + for _, a := range allowedSwaps { + p[find(a[0])] = find(a[1]) } - res := 0 - for i := 0; i < n; i++ { - if mp[find(i)][target[i]] > 0 { - mp[find(i)][target[i]]-- - } else { - res++ + cnt := map[int]map[int]int{} + for i, x := range source { + j := find(i) + if cnt[j] == nil { + cnt[j] = map[int]int{} } + cnt[j][x]++ } - return res -} - -func find(x int) int { - if p[x] != x { - p[x] = find(p[x]) + for i, x := range target { + j := find(i) + cnt[j][x]-- + if cnt[j][x] < 0 { + ans++ + } } - return p[x] + return } \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java index cc54b3d824d96..b33f5b0b1ae4e 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.java @@ -1,37 +1,35 @@ -class Solution { - private int[] p; - - public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { - int n = source.length; - p = new int[n]; - for (int i = 0; i < n; ++i) { - p[i] = i; - } - for (int[] e : allowedSwaps) { - p[find(e[0])] = find(e[1]); - } - Map> mp = new HashMap<>(); - for (int i = 0; i < n; ++i) { - int root = find(i); - mp.computeIfAbsent(root, k -> new HashMap<>()) - .put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1); - } - int res = 0; - for (int i = 0; i < n; ++i) { - int root = find(i); - if (mp.get(root).getOrDefault(target[i], 0) > 0) { - mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1); - } else { - ++res; - } - } - return res; - } - - private int find(int x) { - if (p[x] != x) { - p[x] = find(p[x]); - } - return p[x]; - } +class Solution { + private int[] p; + + public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) { + int n = source.length; + p = new int[n]; + for (int i = 0; i < n; i++) { + p[i] = i; + } + for (int[] a : allowedSwaps) { + p[find(a[0])] = find(a[1]); + } + Map> cnt = new HashMap<>(); + for (int i = 0; i < n; ++i) { + int j = find(i); + cnt.computeIfAbsent(j, k -> new HashMap<>()).merge(source[i], 1, Integer::sum); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + int j = find(i); + Map t = cnt.get(j); + if (t.merge(target[i], -1, Integer::sum) < 0) { + ++ans; + } + } + return ans; + } + + private int find(int x) { + if (p[x] != x) { + p[x] = find(p[x]); + } + return p[x]; + } } \ No newline at end of file diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py index b3b8b6ba01741..c64fba92b2783 100644 --- a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.py @@ -1,25 +1,23 @@ -class Solution: - def minimumHammingDistance( - self, source: List[int], target: List[int], allowedSwaps: List[List[int]] - ) -> int: - n = len(source) - p = list(range(n)) - - def find(x): - if p[x] != x: - p[x] = find(p[x]) - return p[x] - - for i, j in allowedSwaps: - p[find(i)] = find(j) - - mp = defaultdict(Counter) - for i in range(n): - mp[find(i)][source[i]] += 1 - res = 0 - for i in range(n): - if mp[find(i)][target[i]] > 0: - mp[find(i)][target[i]] -= 1 - else: - res += 1 - return res +class Solution: + def minimumHammingDistance( + self, source: List[int], target: List[int], allowedSwaps: List[List[int]] + ) -> int: + def find(x: int) -> int: + if p[x] != x: + p[x] = find(p[x]) + return p[x] + + n = len(source) + p = list(range(n)) + for a, b in allowedSwaps: + p[find(a)] = find(b) + cnt = defaultdict(Counter) + for i, x in enumerate(source): + j = find(i) + cnt[j][x] += 1 + ans = 0 + for i, x in enumerate(target): + j = find(i) + cnt[j][x] -= 1 + ans += cnt[j][x] < 0 + return ans diff --git a/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts new file mode 100644 index 0000000000000..9ff03dcf9cc46 --- /dev/null +++ b/solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/Solution.ts @@ -0,0 +1,36 @@ +function minimumHammingDistance( + source: number[], + target: number[], + allowedSwaps: number[][], +): number { + const n = source.length; + const p: number[] = Array.from({ length: n }, (_, i) => i); + const find = (x: number): number => { + if (p[x] !== x) { + p[x] = find(p[x]); + } + return p[x]; + }; + for (const [a, b] of allowedSwaps) { + p[find(a)] = find(b); + } + const cnt: Map> = new Map(); + for (let i = 0; i < n; ++i) { + const j = find(i); + if (!cnt.has(j)) { + cnt.set(j, new Map()); + } + const m = cnt.get(j)!; + m.set(source[i], (m.get(source[i]) ?? 0) + 1); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + const j = find(i); + const m = cnt.get(j)!; + m.set(target[i], (m.get(target[i]) ?? 0) - 1); + if (m.get(target[i])! < 0) { + ++ans; + } + } + return ans; +} diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md index e1eefa2c804dd..6f428b5f85ef8 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README.md @@ -47,6 +47,16 @@ +**方法一:一次遍历** + +我们定义一个变量 $ans$ 来记录当前最大边长的正方形的个数,定义另一个变量 $mx$ 来记录当前最大的边长。 + +遍历数组 $rectangles$,对于每个矩形 $[l, w]$,我们取 $x = \min(l, w)$,如果 $mx < x$,说明我们找到了一个更大的边长,此时我们将 $mx$ 更新为 $x$,并将 $ans$ 更新为 $1$;如果 $mx = x$,说明我们找到了一个和当前最大边长相同的边长,此时我们将 $ans$ 增加 $1$。 + +最后返回 $ans$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 为数组 $rectangles$ 的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -58,10 +68,11 @@ class Solution: def countGoodRectangles(self, rectangles: List[List[int]]) -> int: ans = mx = 0 for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: ans += 1 return ans ``` @@ -74,12 +85,12 @@ class Solution: class Solution { public int countGoodRectangles(int[][] rectangles) { int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) { + } else if (mx == x) { ++ans; } } @@ -88,25 +99,6 @@ class Solution { } ``` -### **TypeSript** - -```ts -function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; - ans = 1; - } - } - return ans; -} -``` - ### **C++** ```cpp @@ -114,13 +106,14 @@ class Solution { public: int countGoodRectangles(vector>& rectangles) { int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) + } else if (mx == x) { ++ans; + } } return ans; } @@ -130,20 +123,36 @@ public: ### **Go** ```go -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function countGoodRectangles(rectangles: number[][]): number { + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx === x) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md index 8537f74de2f28..076da9d7f7269 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/README_EN.md @@ -41,6 +41,16 @@ The largest possible square is of length 5, and you can get it out of 3 rectangl ## Solutions +**Solution 1: Single Pass** + +We define a variable $ans$ to record the count of squares with the current maximum side length, and another variable $mx$ to record the current maximum side length. + +We traverse the array $rectangles$. For each rectangle $[l, w]$, we take $x = \min(l, w)$. If $mx < x$, it means we have found a larger side length, so we update $mx$ to $x$ and update $ans$ to $1$. If $mx = x$, it means we have found a side length equal to the current maximum side length, so we increase $ans$ by $1$. + +Finally, we return $ans$. + +The time complexity is $O(n)$, where $n$ is the length of the array $rectangles$. The space complexity is $O(1)$. + ### **Python3** @@ -50,10 +60,11 @@ class Solution: def countGoodRectangles(self, rectangles: List[List[int]]) -> int: ans = mx = 0 for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: ans += 1 return ans ``` @@ -64,12 +75,12 @@ class Solution: class Solution { public int countGoodRectangles(int[][] rectangles) { int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) { + } else if (mx == x) { ++ans; } } @@ -78,25 +89,6 @@ class Solution { } ``` -### **TypeScript** - -```ts -function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; - ans = 1; - } - } - return ans; -} -``` - ### **C++** ```cpp @@ -104,13 +96,14 @@ class Solution { public: int countGoodRectangles(vector>& rectangles) { int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; ans = 1; - } else if (mx == t) + } else if (mx == x) { ++ans; + } } return ans; } @@ -120,20 +113,36 @@ public: ### **Go** ```go -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function countGoodRectangles(rectangles: number[][]): number { + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx === x) { + ++ans; + } + } + return ans; } ``` diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp index 8644b9b962724..167ee2325e5b9 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.cpp @@ -1,15 +1,16 @@ -class Solution { -public: - int countGoodRectangles(vector>& rectangles) { - int ans = 0, mx = 0; - for (auto& r : rectangles) { - int t = min(r[0], r[1]); - if (mx < t) { - mx = t; - ans = 1; - } else if (mx == t) - ++ans; - } - return ans; - } +class Solution { +public: + int countGoodRectangles(vector>& rectangles) { + int ans = 0, mx = 0; + for (auto& e : rectangles) { + int x = min(e[0], e[1]); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx == x) { + ++ans; + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go index c65572904e834..13cbea30b0d00 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.go @@ -1,15 +1,13 @@ -func countGoodRectangles(rectangles [][]int) int { - ans, mx := 0, 0 - for _, r := range rectangles { - t := r[0] - if t > r[1] { - t = r[1] - } - if mx < t { - mx, ans = t, 1 - } else if mx == t { +func countGoodRectangles(rectangles [][]int) (ans int) { + mx := 0 + for _, e := range rectangles { + x := min(e[0], e[1]) + if mx < x { + mx = x + ans = 1 + } else if mx == x { ans++ } } - return ans + return } \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java index e066b57fb7431..eda3cedcc5ee7 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.java @@ -1,15 +1,15 @@ -class Solution { - public int countGoodRectangles(int[][] rectangles) { - int ans = 0, mx = 0; - for (int[] r : rectangles) { - int t = Math.min(r[0], r[1]); - if (mx < t) { - mx = t; - ans = 1; - } else if (mx == t) { - ++ans; - } - } - return ans; - } +class Solution { + public int countGoodRectangles(int[][] rectangles) { + int ans = 0, mx = 0; + for (var e : rectangles) { + int x = Math.min(e[0], e[1]); + if (mx < x) { + mx = x; + ans = 1; + } else if (mx == x) { + ++ans; + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py index 8a1ee4eb1b232..bf0b05847b281 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.py @@ -1,10 +1,11 @@ -class Solution: - def countGoodRectangles(self, rectangles: List[List[int]]) -> int: - ans = mx = 0 - for l, w in rectangles: - t = min(l, w) - if mx < t: - mx, ans = t, 1 - elif mx == t: - ans += 1 - return ans +class Solution: + def countGoodRectangles(self, rectangles: List[List[int]]) -> int: + ans = mx = 0 + for l, w in rectangles: + x = min(l, w) + if mx < x: + ans = 1 + mx = x + elif mx == x: + ans += 1 + return ans diff --git a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts index f5111a630c851..46ee5dcbbd6f5 100644 --- a/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts +++ b/solution/1700-1799/1725.Number Of Rectangles That Can Form The Largest Square/Solution.ts @@ -1,13 +1,12 @@ function countGoodRectangles(rectangles: number[][]): number { - let maxLen = 0, - ans = 0; - for (let [l, w] of rectangles) { - let k = Math.min(l, w); - if (k == maxLen) { - ans++; - } else if (k > maxLen) { - maxLen = k; + let [ans, mx] = [0, 0]; + for (const [l, w] of rectangles) { + const x = Math.min(l, w); + if (mx < x) { + mx = x; ans = 1; + } else if (mx === x) { + ++ans; } } return ans;