目标
给你一个下标从 0 开始的 m * n 整数矩阵 grid 。矩阵中某一列的宽度是这一列数字的最大 字符串长度 。
- 比方说,如果 grid = [[-10], [3], [12]] ,那么唯一一列的宽度是 3 ,因为 -10 的字符串长度为 3 。
请你返回一个大小为 n 的整数数组 ans ,其中 ans[i] 是第 i 列的宽度。
一个有 len 个数位的整数 x ,如果是非负数,那么 字符串长度 为 len ,否则为 len + 1 。
示例 1:
输入:grid = [[1],[22],[333]]
输出:[3]
解释:第 0 列中,333 字符串长度为 3 。
示例 2:
输入:grid = [[-15,1,3],[15,7,12],[5,6,-2]]
输出:[3,1,2]
解释:
第 0 列中,只有 -15 字符串长度为 3 。
第 1 列中,所有整数的字符串长度都是 1 。
第 2 列中,12 和 -2 的字符串长度都为 2 。
说明:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 100
-10^9 <= grid[r][c] <= 10^9
思路
这个题核心就是如何计算数字的长度。我们可以枚举 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE
,分别与这些值比较,Integer.stringSize就是如此实现的。对于负数需要将长度加1 int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
。
也可以循环除以10直到0来计算长度。一个优化的点是不必求每一个数的长度,只需要求出最大值 max 与 最小值 min的长度即可。网友还提供了一个小技巧可以减少对较小值的长度计算。选取 max/10
和 -min
中的较大值来计算长度 l
,取 l+1。解释如下:如果 min > 0
那么 -min < 0
,我们取到 max/10
的长度,所以长度为 l+1
。如果 min < 0
,并且 -min > max/10
,我们取到 -min
,长度需要加上负号,即 l+1
。这里需要解释一下 -min < max && -min > max/10
的情况,这时 max 的长度与 -min 的长度加1 是相同的。而如果 min < 0
,且 -min < max/10
,取 max/10
长度减小了1,所以取 l+1
。
代码
/**
* @date 2024-04-27 18:39
*/
public class FindColumnWidth2639 {
int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE};
int stringSize(int x) {
int j;
if (x < 0) {
x = -x;
j = 2;
} else {
j = 1;
}
for (int i = 0; ; i++) {
if (x <= sizeTable[i]) {
return i + j;
}
}
}
public int[] findColumnWidth(int[][] grid) {
int n = grid[0].length;
int[] res = new int[n];
int[] negative = new int[n];
for (int[] ints : grid) {
for (int i = 0; i < n; i++) {
if (ints[i] < negative[i]) {
negative[i] = ints[i];
} else if (ints[i] > res[i]) {
res[i] = ints[i];
}
}
}
for (int i = 0; i < n; i++) {
res[i] = Math.max(stringSize(res[i]), stringSize(negative[i]));
}
return res;
}
}