From a6549a32da77febcc987561d0e4d74f5564c32cf Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sun, 14 Jul 2024 00:38:42 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problems: No.0807,2170 * No.0807.Max Increase to Keep City Skyline * No.2170.Minimum Operations to Make the Array Alternating --- .../README.md | 90 ++++---- .../README_EN.md | 90 ++++---- .../Solution.cpp | 19 +- .../Solution.go | 24 +- .../Solution.java | 10 +- .../Solution.py | 10 +- .../Solution.ts | 19 +- .../README.md | 215 +++++++++--------- .../README_EN.md | 215 +++++++++--------- .../Solution.cpp | 46 ++-- .../Solution.go | 39 ++-- .../Solution.java | 54 ++--- .../Solution.py | 21 +- .../Solution.ts | 45 ++-- 14 files changed, 443 insertions(+), 454 deletions(-) diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/README.md b/solution/0800-0899/0807.Max Increase to Keep City Skyline/README.md index e645612b1518e..694dd93284e8b 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/README.md +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/README.md @@ -67,7 +67,13 @@ gridNew = [ [8, 4, 8, 7], -### 方法一 +### 方法一:贪心 + +根据题目描述,我们可以将每个单元格 $(i, j)$ 的值增加至第 $i$ 行的最大值和第 $j$ 列的最大值中的较小值,这样可以保证不影响天际线,即每个单元格增加的高度为 $\min(\text{rowMax}[i], \text{colMax}[j]) - \text{grid}[i][j]$。 + +因此,我们可以先遍历一次矩阵,分别计算出每行和每列的最大值,记录在数组 $\text{rowMax}$ 和 $\text{colMax}$ 中,然后再遍历一次矩阵,计算出答案即可。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为矩阵 $\text{grid}$ 的边长。 @@ -76,12 +82,12 @@ gridNew = [ [8, 4, 8, 7], ```python class Solution: def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int: - rmx = [max(row) for row in grid] - cmx = [max(col) for col in zip(*grid)] + row_max = [max(row) for row in grid] + col_max = [max(col) for col in zip(*grid)] return sum( - (min(rmx[i], cmx[j]) - grid[i][j]) - for i in range(len(grid)) - for j in range(len(grid[0])) + min(row_max[i], col_max[j]) - x + for i, row in enumerate(grid) + for j, x in enumerate(row) ) ``` @@ -91,18 +97,18 @@ class Solution: class Solution { public int maxIncreaseKeepingSkyline(int[][] grid) { int m = grid.length, n = grid[0].length; - int[] rmx = new int[m]; - int[] cmx = new int[n]; + int[] rowMax = new int[m]; + int[] colMax = new int[n]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = Math.max(rmx[i], grid[i][j]); - cmx[j] = Math.max(cmx[j], grid[i][j]); + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - ans += Math.min(rmx[i], cmx[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; @@ -116,19 +122,22 @@ class Solution { class Solution { public: int maxIncreaseKeepingSkyline(vector>& grid) { - int m = grid.size(), n = grid[0].size(); - vector rmx(m, 0); - vector cmx(n, 0); + int m = grid.size(); + int n = grid[0].size(); + vector rowMax(m); + vector colMax(n); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = max(rmx[i], grid[i][j]); - cmx[j] = max(cmx[j], grid[i][j]); + rowMax[i] = max(rowMax[i], grid[i][j]); + colMax[j] = max(colMax[j], grid[i][j]); } } int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - ans += min(rmx[i], cmx[j]) - grid[i][j]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + ans += min(rowMax[i], colMax[j]) - grid[i][j]; + } + } return ans; } }; @@ -137,23 +146,21 @@ public: #### Go ```go -func maxIncreaseKeepingSkyline(grid [][]int) int { - m, n := len(grid), len(grid[0]) - rmx := make([]int, m) - cmx := make([]int, n) - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - rmx[i] = max(rmx[i], grid[i][j]) - cmx[j] = max(cmx[j], grid[i][j]) +func maxIncreaseKeepingSkyline(grid [][]int) (ans int) { + rowMax := make([]int, len(grid)) + colMax := make([]int, len(grid[0])) + for i, row := range grid { + for j, x := range row { + rowMax[i] = max(rowMax[i], x) + colMax[j] = max(colMax[j], x) } } - ans := 0 - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - ans += min(rmx[i], cmx[j]) - grid[i][j] + for i, row := range grid { + for j, x := range row { + ans += min(rowMax[i], colMax[j]) - x } } - return ans + return } ``` @@ -161,21 +168,20 @@ func maxIncreaseKeepingSkyline(grid [][]int) int { ```ts function maxIncreaseKeepingSkyline(grid: number[][]): number { - let rows = grid.map(arr => Math.max(...arr)), - cols = []; - let m = grid.length, - n = grid[0].length; - for (let j = 0; j < n; ++j) { - cols[j] = grid[0][j]; - for (let i = 1; i < m; ++i) { - cols[j] = Math.max(cols[j], grid[i][j]); + const m = grid.length; + const n = grid[0].length; + const rowMax = Array(m).fill(0); + const colMax = Array(n).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } - let ans = 0; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - ans += Math.min(rows[i], cols[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/README_EN.md b/solution/0800-0899/0807.Max Increase to Keep City Skyline/README_EN.md index 4c57474d8e768..8e7d66a40dac4 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/README_EN.md +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/README_EN.md @@ -65,7 +65,13 @@ gridNew = [ [8, 4, 8, 7], -### Solution 1 +### Solution 1: Greedy + +According to the problem description, we can increase the value of each cell $(i, j)$ to the smaller value between the maximum value of the $i$-th row and the $j$-th column, ensuring it does not affect the skyline. Thus, the height added to each cell is $\min(\text{rowMax}[i], \text{colMax}[j]) - \text{grid}[i][j]$. + +Therefore, we can first traverse the matrix once to calculate the maximum value of each row and column, storing them in the arrays $\text{rowMax}$ and $\text{colMax}$, respectively. Then, we traverse the matrix again to compute the answer. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$, where $n$ is the side length of the matrix $\text{grid}$. @@ -74,12 +80,12 @@ gridNew = [ [8, 4, 8, 7], ```python class Solution: def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int: - rmx = [max(row) for row in grid] - cmx = [max(col) for col in zip(*grid)] + row_max = [max(row) for row in grid] + col_max = [max(col) for col in zip(*grid)] return sum( - (min(rmx[i], cmx[j]) - grid[i][j]) - for i in range(len(grid)) - for j in range(len(grid[0])) + min(row_max[i], col_max[j]) - x + for i, row in enumerate(grid) + for j, x in enumerate(row) ) ``` @@ -89,18 +95,18 @@ class Solution: class Solution { public int maxIncreaseKeepingSkyline(int[][] grid) { int m = grid.length, n = grid[0].length; - int[] rmx = new int[m]; - int[] cmx = new int[n]; + int[] rowMax = new int[m]; + int[] colMax = new int[n]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = Math.max(rmx[i], grid[i][j]); - cmx[j] = Math.max(cmx[j], grid[i][j]); + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - ans += Math.min(rmx[i], cmx[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; @@ -114,19 +120,22 @@ class Solution { class Solution { public: int maxIncreaseKeepingSkyline(vector>& grid) { - int m = grid.size(), n = grid[0].size(); - vector rmx(m, 0); - vector cmx(n, 0); + int m = grid.size(); + int n = grid[0].size(); + vector rowMax(m); + vector colMax(n); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = max(rmx[i], grid[i][j]); - cmx[j] = max(cmx[j], grid[i][j]); + rowMax[i] = max(rowMax[i], grid[i][j]); + colMax[j] = max(colMax[j], grid[i][j]); } } int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - ans += min(rmx[i], cmx[j]) - grid[i][j]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + ans += min(rowMax[i], colMax[j]) - grid[i][j]; + } + } return ans; } }; @@ -135,23 +144,21 @@ public: #### Go ```go -func maxIncreaseKeepingSkyline(grid [][]int) int { - m, n := len(grid), len(grid[0]) - rmx := make([]int, m) - cmx := make([]int, n) - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - rmx[i] = max(rmx[i], grid[i][j]) - cmx[j] = max(cmx[j], grid[i][j]) +func maxIncreaseKeepingSkyline(grid [][]int) (ans int) { + rowMax := make([]int, len(grid)) + colMax := make([]int, len(grid[0])) + for i, row := range grid { + for j, x := range row { + rowMax[i] = max(rowMax[i], x) + colMax[j] = max(colMax[j], x) } } - ans := 0 - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - ans += min(rmx[i], cmx[j]) - grid[i][j] + for i, row := range grid { + for j, x := range row { + ans += min(rowMax[i], colMax[j]) - x } } - return ans + return } ``` @@ -159,21 +166,20 @@ func maxIncreaseKeepingSkyline(grid [][]int) int { ```ts function maxIncreaseKeepingSkyline(grid: number[][]): number { - let rows = grid.map(arr => Math.max(...arr)), - cols = []; - let m = grid.length, - n = grid[0].length; - for (let j = 0; j < n; ++j) { - cols[j] = grid[0][j]; - for (let i = 1; i < m; ++i) { - cols[j] = Math.max(cols[j], grid[i][j]); + const m = grid.length; + const n = grid[0].length; + const rowMax = Array(m).fill(0); + const colMax = Array(n).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } - let ans = 0; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - ans += Math.min(rows[i], cols[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.cpp b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.cpp index 28ac200e70e13..ba93af3791b67 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.cpp +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.cpp @@ -1,19 +1,22 @@ class Solution { public: int maxIncreaseKeepingSkyline(vector>& grid) { - int m = grid.size(), n = grid[0].size(); - vector rmx(m, 0); - vector cmx(n, 0); + int m = grid.size(); + int n = grid[0].size(); + vector rowMax(m); + vector colMax(n); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = max(rmx[i], grid[i][j]); - cmx[j] = max(cmx[j], grid[i][j]); + rowMax[i] = max(rowMax[i], grid[i][j]); + colMax[j] = max(colMax[j], grid[i][j]); } } int ans = 0; - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - ans += min(rmx[i], cmx[j]) - grid[i][j]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + ans += min(rowMax[i], colMax[j]) - grid[i][j]; + } + } return ans; } }; \ No newline at end of file diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.go b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.go index fcd587663e508..1e9ac311d1005 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.go +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.go @@ -1,18 +1,16 @@ -func maxIncreaseKeepingSkyline(grid [][]int) int { - m, n := len(grid), len(grid[0]) - rmx := make([]int, m) - cmx := make([]int, n) - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - rmx[i] = max(rmx[i], grid[i][j]) - cmx[j] = max(cmx[j], grid[i][j]) +func maxIncreaseKeepingSkyline(grid [][]int) (ans int) { + rowMax := make([]int, len(grid)) + colMax := make([]int, len(grid[0])) + for i, row := range grid { + for j, x := range row { + rowMax[i] = max(rowMax[i], x) + colMax[j] = max(colMax[j], x) } } - ans := 0 - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - ans += min(rmx[i], cmx[j]) - grid[i][j] + for i, row := range grid { + for j, x := range row { + ans += min(rowMax[i], colMax[j]) - x } } - return ans + return } \ No newline at end of file diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.java b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.java index c059b5d7ca90f..e3056b78457f2 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.java +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.java @@ -1,18 +1,18 @@ class Solution { public int maxIncreaseKeepingSkyline(int[][] grid) { int m = grid.length, n = grid[0].length; - int[] rmx = new int[m]; - int[] cmx = new int[n]; + int[] rowMax = new int[m]; + int[] colMax = new int[n]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - rmx[i] = Math.max(rmx[i], grid[i][j]); - cmx[j] = Math.max(cmx[j], grid[i][j]); + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { - ans += Math.min(rmx[i], cmx[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.py b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.py index ddd43b34f0a17..f3946d503561c 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.py +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.py @@ -1,9 +1,9 @@ class Solution: def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int: - rmx = [max(row) for row in grid] - cmx = [max(col) for col in zip(*grid)] + row_max = [max(row) for row in grid] + col_max = [max(col) for col in zip(*grid)] return sum( - (min(rmx[i], cmx[j]) - grid[i][j]) - for i in range(len(grid)) - for j in range(len(grid[0])) + min(row_max[i], col_max[j]) - x + for i, row in enumerate(grid) + for j, x in enumerate(row) ) diff --git a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.ts b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.ts index 98f9e60a6fdc0..b6081f99fdbd2 100644 --- a/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.ts +++ b/solution/0800-0899/0807.Max Increase to Keep City Skyline/Solution.ts @@ -1,19 +1,18 @@ function maxIncreaseKeepingSkyline(grid: number[][]): number { - let rows = grid.map(arr => Math.max(...arr)), - cols = []; - let m = grid.length, - n = grid[0].length; - for (let j = 0; j < n; ++j) { - cols[j] = grid[0][j]; - for (let i = 1; i < m; ++i) { - cols[j] = Math.max(cols[j], grid[i][j]); + const m = grid.length; + const n = grid[0].length; + const rowMax = Array(m).fill(0); + const colMax = Array(n).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + rowMax[i] = Math.max(rowMax[i], grid[i][j]); + colMax[j] = Math.max(colMax[j], grid[i][j]); } } - let ans = 0; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - ans += Math.min(rows[i], cols[j]) - grid[i][j]; + ans += Math.min(rowMax[i], colMax[j]) - grid[i][j]; } } return ans; diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md index 2aaac511eef60..b33059ec388cf 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md @@ -72,7 +72,15 @@ tags: -### 方法一 +### 方法一:维护奇偶位置的计数 + +根据题目描述,我们可以知道,如果数组 $\textit{nums}$ 是一个交替数组,那么数组中的奇数位置和偶数位置的元素一定是不同的,且奇数位置的元素相同,偶数位置的元素也相同。 + +要使得数组 $\textit{nums}$ 变成交替数组的操作数最少,我们可以通过统计奇数位置和偶数位置的元素的出现次数,找到偶数位置出现次数最多的两个元素 $a_0$ 和 $a_2$,以及对应的出现次数 $a_1$ 和 $a_3$;再找到奇数位置出现次数最多的两个元素 $b_0$ 和 $b_2$,以及对应的出现次数 $b_1$ 和 $b_3$。 + +如果 $a_0 \neq b_0$,那么我们可以将数组 $\textit{nums}$ 中偶数位置的元素全部变成 $a_0$,奇数位置的元素全部变成 $b_0$,这样操作数为 $n - (a_1 + b_1)$;如果 $a_0 = b_0$,那么我们可以将数组 $\textit{nums}$ 中偶数位置的元素全部变成 $a_0$,奇数位置的元素全部变成 $b_2$,或者将数组 $\textit{nums}$ 中偶数位置的元素全部变成 $a_2$,奇数位置的元素全部变成 $b_0$,这样操作数为 $n - \max(a_1 + b_3, a_3 + b_1)$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。 @@ -81,62 +89,53 @@ tags: ```python class Solution: def minimumOperations(self, nums: List[int]) -> int: - def get(i): - c = Counter(nums[i::2]).most_common(2) - if not c: - return [(0, 0), (0, 0)] - if len(c) == 1: - return [c[0], (0, 0)] - return c - + def f(i: int) -> Tuple[int, int, int, int]: + k1 = k2 = 0 + cnt = Counter(nums[i::2]) + for k, v in cnt.items(): + if cnt[k1] < v: + k2, k1 = k1, k + elif cnt[k2] < v: + k2 = k + return k1, cnt[k1], k2, cnt[k2] + + a, b = f(0), f(1) n = len(nums) - return min(n - (n1 + n2) for a, n1 in get(0) for b, n2 in get(1) if a != b) + if a[0] != b[0]: + return n - (a[1] + b[1]) + return n - max(a[1] + b[3], a[3] + b[1]) ``` #### Java ```java class Solution { - private int[] nums; - private int n; - public int minimumOperations(int[] nums) { - this.nums = nums; - n = nums.length; - int ans = Integer.MAX_VALUE; - for (int[] e1 : get(0)) { - for (int[] e2 : get(1)) { - if (e1[0] != e2[0]) { - ans = Math.min(ans, n - (e1[1] + e2[1])); - } - } + int[] a = f(nums, 0); + int[] b = f(nums, 1); + int n = nums.length; + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return ans; + return n - Math.max(a[1] + b[3], a[3] + b[1]); } - private int[][] get(int i) { - Map freq = new HashMap<>(); - for (; i < n; i += 2) { - freq.put(nums[i], freq.getOrDefault(nums[i], 0) + 1); + private int[] f(int[] nums, int i) { + int k1 = 0, k2 = 0; + Map cnt = new HashMap<>(); + for (; i < nums.length; i += 2) { + cnt.merge(nums[i], 1, Integer::sum); } - int a = 0; - int n1 = 0; - int b = 0; - int n2 = 0; - for (Map.Entry e : freq.entrySet()) { - int k = e.getKey(); - int v = e.getValue(); - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + for (var e : cnt.entrySet()) { + int k = e.getKey(), v = e.getValue(); + if (cnt.getOrDefault(k1, 0) < v) { + k2 = k1; + k1 = k; + } else if (cnt.getOrDefault(k2, 0) < v) { + k2 = k; } } - return new int[][] {{a, n1}, {b, n2}}; + return new int[] {k1, cnt.getOrDefault(k1, 0), k2, cnt.getOrDefault(k2, 0)}; } } ``` @@ -144,36 +143,32 @@ class Solution { #### C++ ```cpp -typedef pair PII; - class Solution { public: int minimumOperations(vector& nums) { - int ans = INT_MAX; - int n = nums.size(); - for (auto& [a, n1] : get(0, nums)) - for (auto& [b, n2] : get(1, nums)) - if (a != b) - ans = min(ans, n - (n1 + n2)); - return ans; - } - - vector get(int i, vector& nums) { - unordered_map freq; - for (; i < nums.size(); i += 2) ++freq[nums[i]]; - int a = 0, n1 = 0, b = 0, n2 = 0; - for (auto& [k, v] : freq) { - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + auto f = [&](int i) -> vector { + int k1 = 0, k2 = 0; + unordered_map cnt; + for (; i < nums.size(); i += 2) { + cnt[nums[i]]++; } + for (auto& [k, v] : cnt) { + if (!k1 || cnt[k1] < v) { + k2 = k1; + k1 = k; + } else if (!k2 || cnt[k2] < v) { + k2 = k; + } + } + return {k1, !k1 ? 0 : cnt[k1], k2, !k2 ? 0 : cnt[k2]}; + }; + vector a = f(0); + vector b = f(1); + int n = nums.size(); + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return {{a, n1}, {b, n2}}; + return n - max(a[1] + b[3], a[3] + b[1]); } }; ``` @@ -182,31 +177,30 @@ public: ```go func minimumOperations(nums []int) int { - n := len(nums) - get := func(i int) [][]int { - freq := make(map[int]int) - for ; i < n; i += 2 { - freq[nums[i]]++ + f := func(i int) [4]int { + cnt := make(map[int]int) + for ; i < len(nums); i += 2 { + cnt[nums[i]]++ } - a, n1, b, n2 := 0, 0, 0, 0 - for k, v := range freq { - if v > n1 { - b, n2, a, n1 = a, n1, k, v - } else if v > n2 { - b, n2 = k, v + + k1, k2 := 0, 0 + for k, v := range cnt { + if cnt[k1] < v { + k2, k1 = k1, k + } else if cnt[k2] < v { + k2 = k } } - return [][]int{{a, n1}, {b, n2}} + return [4]int{k1, cnt[k1], k2, cnt[k2]} } - ans := 100000 - for _, e1 := range get(0) { - for _, e2 := range get(1) { - if e1[0] != e2[0] && ans > (n-(e1[1]+e2[1])) { - ans = n - (e1[1] + e2[1]) - } - } + + a := f(0) + b := f(1) + n := len(nums) + if a[0] != b[0] { + return n - (a[1] + b[1]) } - return ans + return n - max(a[1]+b[3], a[3]+b[1]) } ``` @@ -214,30 +208,31 @@ func minimumOperations(nums []int) int { ```ts function minimumOperations(nums: number[]): number { - const n = nums.length, - m = 10 ** 5; - let odd = new Array(m).fill(0); - let even = new Array(m).fill(0); - for (let i = 0; i < n; i++) { - let cur = nums[i]; - if (i & 1) { - odd[cur] = (odd[cur] || 0) + 1; - } else { - even[cur] = (even[cur] || 0) + 1; + const f = (i: number): [number, number, number, number] => { + const cnt: Map = new Map(); + for (; i < nums.length; i += 2) { + cnt.set(nums[i], (cnt.get(nums[i]) || 0) + 1); } + + let [k1, k2] = [0, 0]; + for (const [k, v] of cnt) { + if ((cnt.get(k1) || 0) < v) { + k2 = k1; + k1 = k; + } else if ((cnt.get(k2) || 0) < v) { + k2 = k; + } + } + return [k1, cnt.get(k1) || 0, k2, cnt.get(k2) || 0]; + }; + + const a = f(0); + const b = f(1); + const n = nums.length; + if (a[0] !== b[0]) { + return n - (a[1] + b[1]); } - let i1 = odd.indexOf(Math.max(...odd)); - let i2 = even.indexOf(Math.max(...even)); - if (i1 != i2) { - return n - odd[i1] - even[i2]; - } else { - let l1 = odd[i1], - l2 = even[i2]; - (odd[i1] = 0), (even[i2] = 0); - let j1 = odd.indexOf(Math.max(...odd)); - let j2 = even.indexOf(Math.max(...even)); - return n - Math.max(l1 + even[j2], l2 + odd[j1]); - } + return n - Math.max(a[1] + b[3], a[3] + b[1]); } ``` diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md index 22556697b8d3f..d723c6d88b43d 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md @@ -71,7 +71,15 @@ Note that the array cannot be converted to [2,2,2,2,2] b -### Solution 1 +### Solution 1: Maintain Count of Odd and Even Positions + +According to the problem description, if an array $\textit{nums}$ is an alternating array, then the elements at odd positions and even positions must be different, and the elements at odd positions are the same, as well as the elements at even positions. + +To minimize the number of operations required to transform the array $\textit{nums}$ into an alternating array, we can count the occurrence of elements at odd and even positions. We find the two elements with the highest occurrence at even positions, $a_0$ and $a_2$, and their corresponding counts $a_1$ and $a_3$; similarly, we find the two elements with the highest occurrence at odd positions, $b_0$ and $b_2$, and their corresponding counts $b_1$ and $b_3$. + +If $a_0 \neq b_0$, then we can change all elements at even positions in the array $\textit{nums}$ to $a_0$ and all elements at odd positions to $b_0$, making the number of operations $n - (a_1 + b_1)$; if $a_0 = b_0$, then we can change all elements at even positions in the array $\textit{nums}$ to $a_0$ and all elements at odd positions to $b_2$, or change all elements at even positions to $a_2$ and all elements at odd positions to $b_0$, making the number of operations $n - \max(a_1 + b_3, a_3 + b_1)$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. @@ -80,62 +88,53 @@ Note that the array cannot be converted to [2,2,2,2,2] b ```python class Solution: def minimumOperations(self, nums: List[int]) -> int: - def get(i): - c = Counter(nums[i::2]).most_common(2) - if not c: - return [(0, 0), (0, 0)] - if len(c) == 1: - return [c[0], (0, 0)] - return c - + def f(i: int) -> Tuple[int, int, int, int]: + k1 = k2 = 0 + cnt = Counter(nums[i::2]) + for k, v in cnt.items(): + if cnt[k1] < v: + k2, k1 = k1, k + elif cnt[k2] < v: + k2 = k + return k1, cnt[k1], k2, cnt[k2] + + a, b = f(0), f(1) n = len(nums) - return min(n - (n1 + n2) for a, n1 in get(0) for b, n2 in get(1) if a != b) + if a[0] != b[0]: + return n - (a[1] + b[1]) + return n - max(a[1] + b[3], a[3] + b[1]) ``` #### Java ```java class Solution { - private int[] nums; - private int n; - public int minimumOperations(int[] nums) { - this.nums = nums; - n = nums.length; - int ans = Integer.MAX_VALUE; - for (int[] e1 : get(0)) { - for (int[] e2 : get(1)) { - if (e1[0] != e2[0]) { - ans = Math.min(ans, n - (e1[1] + e2[1])); - } - } + int[] a = f(nums, 0); + int[] b = f(nums, 1); + int n = nums.length; + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return ans; + return n - Math.max(a[1] + b[3], a[3] + b[1]); } - private int[][] get(int i) { - Map freq = new HashMap<>(); - for (; i < n; i += 2) { - freq.put(nums[i], freq.getOrDefault(nums[i], 0) + 1); + private int[] f(int[] nums, int i) { + int k1 = 0, k2 = 0; + Map cnt = new HashMap<>(); + for (; i < nums.length; i += 2) { + cnt.merge(nums[i], 1, Integer::sum); } - int a = 0; - int n1 = 0; - int b = 0; - int n2 = 0; - for (Map.Entry e : freq.entrySet()) { - int k = e.getKey(); - int v = e.getValue(); - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + for (var e : cnt.entrySet()) { + int k = e.getKey(), v = e.getValue(); + if (cnt.getOrDefault(k1, 0) < v) { + k2 = k1; + k1 = k; + } else if (cnt.getOrDefault(k2, 0) < v) { + k2 = k; } } - return new int[][] {{a, n1}, {b, n2}}; + return new int[] {k1, cnt.getOrDefault(k1, 0), k2, cnt.getOrDefault(k2, 0)}; } } ``` @@ -143,36 +142,32 @@ class Solution { #### C++ ```cpp -typedef pair PII; - class Solution { public: int minimumOperations(vector& nums) { - int ans = INT_MAX; - int n = nums.size(); - for (auto& [a, n1] : get(0, nums)) - for (auto& [b, n2] : get(1, nums)) - if (a != b) - ans = min(ans, n - (n1 + n2)); - return ans; - } - - vector get(int i, vector& nums) { - unordered_map freq; - for (; i < nums.size(); i += 2) ++freq[nums[i]]; - int a = 0, n1 = 0, b = 0, n2 = 0; - for (auto& [k, v] : freq) { - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + auto f = [&](int i) -> vector { + int k1 = 0, k2 = 0; + unordered_map cnt; + for (; i < nums.size(); i += 2) { + cnt[nums[i]]++; } + for (auto& [k, v] : cnt) { + if (!k1 || cnt[k1] < v) { + k2 = k1; + k1 = k; + } else if (!k2 || cnt[k2] < v) { + k2 = k; + } + } + return {k1, !k1 ? 0 : cnt[k1], k2, !k2 ? 0 : cnt[k2]}; + }; + vector a = f(0); + vector b = f(1); + int n = nums.size(); + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return {{a, n1}, {b, n2}}; + return n - max(a[1] + b[3], a[3] + b[1]); } }; ``` @@ -181,31 +176,30 @@ public: ```go func minimumOperations(nums []int) int { - n := len(nums) - get := func(i int) [][]int { - freq := make(map[int]int) - for ; i < n; i += 2 { - freq[nums[i]]++ + f := func(i int) [4]int { + cnt := make(map[int]int) + for ; i < len(nums); i += 2 { + cnt[nums[i]]++ } - a, n1, b, n2 := 0, 0, 0, 0 - for k, v := range freq { - if v > n1 { - b, n2, a, n1 = a, n1, k, v - } else if v > n2 { - b, n2 = k, v + + k1, k2 := 0, 0 + for k, v := range cnt { + if cnt[k1] < v { + k2, k1 = k1, k + } else if cnt[k2] < v { + k2 = k } } - return [][]int{{a, n1}, {b, n2}} + return [4]int{k1, cnt[k1], k2, cnt[k2]} } - ans := 100000 - for _, e1 := range get(0) { - for _, e2 := range get(1) { - if e1[0] != e2[0] && ans > (n-(e1[1]+e2[1])) { - ans = n - (e1[1] + e2[1]) - } - } + + a := f(0) + b := f(1) + n := len(nums) + if a[0] != b[0] { + return n - (a[1] + b[1]) } - return ans + return n - max(a[1]+b[3], a[3]+b[1]) } ``` @@ -213,30 +207,31 @@ func minimumOperations(nums []int) int { ```ts function minimumOperations(nums: number[]): number { - const n = nums.length, - m = 10 ** 5; - let odd = new Array(m).fill(0); - let even = new Array(m).fill(0); - for (let i = 0; i < n; i++) { - let cur = nums[i]; - if (i & 1) { - odd[cur] = (odd[cur] || 0) + 1; - } else { - even[cur] = (even[cur] || 0) + 1; + const f = (i: number): [number, number, number, number] => { + const cnt: Map = new Map(); + for (; i < nums.length; i += 2) { + cnt.set(nums[i], (cnt.get(nums[i]) || 0) + 1); } + + let [k1, k2] = [0, 0]; + for (const [k, v] of cnt) { + if ((cnt.get(k1) || 0) < v) { + k2 = k1; + k1 = k; + } else if ((cnt.get(k2) || 0) < v) { + k2 = k; + } + } + return [k1, cnt.get(k1) || 0, k2, cnt.get(k2) || 0]; + }; + + const a = f(0); + const b = f(1); + const n = nums.length; + if (a[0] !== b[0]) { + return n - (a[1] + b[1]); } - let i1 = odd.indexOf(Math.max(...odd)); - let i2 = even.indexOf(Math.max(...even)); - if (i1 != i2) { - return n - odd[i1] - even[i2]; - } else { - let l1 = odd[i1], - l2 = even[i2]; - (odd[i1] = 0), (even[i2] = 0); - let j1 = odd.indexOf(Math.max(...odd)); - let j2 = even.indexOf(Math.max(...even)); - return n - Math.max(l1 + even[j2], l2 + odd[j1]); - } + return n - Math.max(a[1] + b[3], a[3] + b[1]); } ``` diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.cpp b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.cpp index 3cc8284ca355d..7cca4b3eb3d49 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.cpp +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.cpp @@ -1,32 +1,28 @@ -typedef pair PII; - class Solution { public: int minimumOperations(vector& nums) { - int ans = INT_MAX; - int n = nums.size(); - for (auto& [a, n1] : get(0, nums)) - for (auto& [b, n2] : get(1, nums)) - if (a != b) - ans = min(ans, n - (n1 + n2)); - return ans; - } - - vector get(int i, vector& nums) { - unordered_map freq; - for (; i < nums.size(); i += 2) ++freq[nums[i]]; - int a = 0, n1 = 0, b = 0, n2 = 0; - for (auto& [k, v] : freq) { - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + auto f = [&](int i) -> vector { + int k1 = 0, k2 = 0; + unordered_map cnt; + for (; i < nums.size(); i += 2) { + cnt[nums[i]]++; } + for (auto& [k, v] : cnt) { + if (!k1 || cnt[k1] < v) { + k2 = k1; + k1 = k; + } else if (!k2 || cnt[k2] < v) { + k2 = k; + } + } + return {k1, !k1 ? 0 : cnt[k1], k2, !k2 ? 0 : cnt[k2]}; + }; + vector a = f(0); + vector b = f(1); + int n = nums.size(); + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return {{a, n1}, {b, n2}}; + return n - max(a[1] + b[3], a[3] + b[1]); } }; \ No newline at end of file diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.go b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.go index e4854ca8f877a..24e71402806b4 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.go +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.go @@ -1,27 +1,26 @@ func minimumOperations(nums []int) int { - n := len(nums) - get := func(i int) [][]int { - freq := make(map[int]int) - for ; i < n; i += 2 { - freq[nums[i]]++ + f := func(i int) [4]int { + cnt := make(map[int]int) + for ; i < len(nums); i += 2 { + cnt[nums[i]]++ } - a, n1, b, n2 := 0, 0, 0, 0 - for k, v := range freq { - if v > n1 { - b, n2, a, n1 = a, n1, k, v - } else if v > n2 { - b, n2 = k, v + + k1, k2 := 0, 0 + for k, v := range cnt { + if cnt[k1] < v { + k2, k1 = k1, k + } else if cnt[k2] < v { + k2 = k } } - return [][]int{{a, n1}, {b, n2}} + return [4]int{k1, cnt[k1], k2, cnt[k2]} } - ans := 100000 - for _, e1 := range get(0) { - for _, e2 := range get(1) { - if e1[0] != e2[0] && ans > (n-(e1[1]+e2[1])) { - ans = n - (e1[1] + e2[1]) - } - } + + a := f(0) + b := f(1) + n := len(nums) + if a[0] != b[0] { + return n - (a[1] + b[1]) } - return ans + return n - max(a[1]+b[3], a[3]+b[1]) } \ No newline at end of file diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java index 8f99d13e9da00..2c8da1f16defa 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java @@ -1,43 +1,29 @@ class Solution { - private int[] nums; - private int n; - public int minimumOperations(int[] nums) { - this.nums = nums; - n = nums.length; - int ans = Integer.MAX_VALUE; - for (int[] e1 : get(0)) { - for (int[] e2 : get(1)) { - if (e1[0] != e2[0]) { - ans = Math.min(ans, n - (e1[1] + e2[1])); - } - } + int[] a = f(nums, 0); + int[] b = f(nums, 1); + int n = nums.length; + if (a[0] != b[0]) { + return n - (a[1] + b[1]); } - return ans; + return n - Math.max(a[1] + b[3], a[3] + b[1]); } - private int[][] get(int i) { - Map freq = new HashMap<>(); - for (; i < n; i += 2) { - freq.put(nums[i], freq.getOrDefault(nums[i], 0) + 1); + private int[] f(int[] nums, int i) { + int k1 = 0, k2 = 0; + Map cnt = new HashMap<>(); + for (; i < nums.length; i += 2) { + cnt.merge(nums[i], 1, Integer::sum); } - int a = 0; - int n1 = 0; - int b = 0; - int n2 = 0; - for (Map.Entry e : freq.entrySet()) { - int k = e.getKey(); - int v = e.getValue(); - if (v > n1) { - b = a; - n2 = n1; - a = k; - n1 = v; - } else if (v > n2) { - b = k; - n2 = v; + for (var e : cnt.entrySet()) { + int k = e.getKey(), v = e.getValue(); + if (cnt.getOrDefault(k1, 0) < v) { + k2 = k1; + k1 = k; + } else if (cnt.getOrDefault(k2, 0) < v) { + k2 = k; } } - return new int[][] {{a, n1}, {b, n2}}; + return new int[] {k1, cnt.getOrDefault(k1, 0), k2, cnt.getOrDefault(k2, 0)}; } -} \ No newline at end of file +} diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.py b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.py index 88de28d05488c..562d8e06529db 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.py +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.py @@ -1,12 +1,17 @@ class Solution: def minimumOperations(self, nums: List[int]) -> int: - def get(i): - c = Counter(nums[i::2]).most_common(2) - if not c: - return [(0, 0), (0, 0)] - if len(c) == 1: - return [c[0], (0, 0)] - return c + def f(i: int) -> Tuple[int, int, int, int]: + k1 = k2 = 0 + cnt = Counter(nums[i::2]) + for k, v in cnt.items(): + if cnt[k1] < v: + k2, k1 = k1, k + elif cnt[k2] < v: + k2 = k + return k1, cnt[k1], k2, cnt[k2] + a, b = f(0), f(1) n = len(nums) - return min(n - (n1 + n2) for a, n1 in get(0) for b, n2 in get(1) if a != b) + if a[0] != b[0]: + return n - (a[1] + b[1]) + return n - max(a[1] + b[3], a[3] + b[1]) diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.ts b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.ts index 15739c5a1f800..ffb31503e1953 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.ts +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.ts @@ -1,26 +1,27 @@ function minimumOperations(nums: number[]): number { - const n = nums.length, - m = 10 ** 5; - let odd = new Array(m).fill(0); - let even = new Array(m).fill(0); - for (let i = 0; i < n; i++) { - let cur = nums[i]; - if (i & 1) { - odd[cur] = (odd[cur] || 0) + 1; - } else { - even[cur] = (even[cur] || 0) + 1; + const f = (i: number): [number, number, number, number] => { + const cnt: Map = new Map(); + for (; i < nums.length; i += 2) { + cnt.set(nums[i], (cnt.get(nums[i]) || 0) + 1); } + + let [k1, k2] = [0, 0]; + for (const [k, v] of cnt) { + if ((cnt.get(k1) || 0) < v) { + k2 = k1; + k1 = k; + } else if ((cnt.get(k2) || 0) < v) { + k2 = k; + } + } + return [k1, cnt.get(k1) || 0, k2, cnt.get(k2) || 0]; + }; + + const a = f(0); + const b = f(1); + const n = nums.length; + if (a[0] !== b[0]) { + return n - (a[1] + b[1]); } - let i1 = odd.indexOf(Math.max(...odd)); - let i2 = even.indexOf(Math.max(...even)); - if (i1 != i2) { - return n - odd[i1] - even[i2]; - } else { - let l1 = odd[i1], - l2 = even[i2]; - (odd[i1] = 0), (even[i2] = 0); - let j1 = odd.indexOf(Math.max(...odd)); - let j2 = even.indexOf(Math.max(...even)); - return n - Math.max(l1 + even[j2], l2 + odd[j1]); - } + return n - Math.max(a[1] + b[3], a[3] + b[1]); } From 7aed8e85f6b96754eb84b1fcd16d0bb717380af6 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sun, 14 Jul 2024 00:42:00 +0800 Subject: [PATCH 2/2] fix: update code --- .../README.md | 2 +- .../README_EN.md | 2 +- .../Solution.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md index b33059ec388cf..caf5c2da7ca23 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README.md @@ -124,7 +124,7 @@ class Solution { int k1 = 0, k2 = 0; Map cnt = new HashMap<>(); for (; i < nums.length; i += 2) { - cnt.merge(nums[i], 1, Integer::sum); + cnt.merge(nums[i], 1, Integer::sum); } for (var e : cnt.entrySet()) { int k = e.getKey(), v = e.getValue(); diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md index d723c6d88b43d..1d4a90f6745de 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/README_EN.md @@ -123,7 +123,7 @@ class Solution { int k1 = 0, k2 = 0; Map cnt = new HashMap<>(); for (; i < nums.length; i += 2) { - cnt.merge(nums[i], 1, Integer::sum); + cnt.merge(nums[i], 1, Integer::sum); } for (var e : cnt.entrySet()) { int k = e.getKey(), v = e.getValue(); diff --git a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java index 2c8da1f16defa..30715e6a1671b 100644 --- a/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java +++ b/solution/2100-2199/2170.Minimum Operations to Make the Array Alternating/Solution.java @@ -13,7 +13,7 @@ private int[] f(int[] nums, int i) { int k1 = 0, k2 = 0; Map cnt = new HashMap<>(); for (; i < nums.length; i += 2) { - cnt.merge(nums[i], 1, Integer::sum); + cnt.merge(nums[i], 1, Integer::sum); } for (var e : cnt.entrySet()) { int k = e.getKey(), v = e.getValue();