- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题如下:对于数字N,当每个数字可以使用N次时,我需要找出可以计数的最大值。
例如,如果N = 5,则最大值为12,因为此时数字1已被使用5次。
我最初的方法是简单地遍历所有数字,并统计到目前为止每个数字已使用了多少次。当N很大时,这显然是非常低效的,因此我正在寻找有关实现此目标的更智能(更有效)方式的建议。
public class Counter {
private static Hashtable<Integer, Integer> numbers;
public static void main(String[] args){
Counter c = new Counter();
c.run(9);
}
public Counter() {
numbers = new Hashtable<Integer, Integer>();
numbers.put(0, 0);
numbers.put(1, 0);
numbers.put(2, 0);
numbers.put(3, 0);
numbers.put(4, 0);
numbers.put(5, 0);
numbers.put(6, 0);
numbers.put(7, 0);
numbers.put(8, 0);
numbers.put(9, 0);
}
public static void run(int maxRepeat) {
int keeper = 0;
for(int maxFound = 0; maxFound <= maxRepeat; maxFound++) {
keeper++;
for (int i = 0; i < Integer.toString(keeper).length(); i++) {
int a = Integer.toString(keeper).charAt(i);
//here update the tally for appropriate digit and check if max repeats is reached
}
}
System.out.println(keeper);
}
}
最佳答案
对于初学者,不要使用Counter
支持Hashtable
,而应使用int[]
。当您确切知道地图必须包含多少个元素时,尤其是当键是数字时,数组就是完美的选择。
话虽如此,我认为最有效的加速可能来自更好的数学,而不是更好的算法。经过一些试验(或者很明显),您会注意到1始终是给定次数使用的第一个数字。因此,给定N
,如果您可以找到第一个使用1位数N+1
的数字,那么您知道答案就是在此之前的数字。这样一来,您就可以解决问题,而不必实际计算那么高。
现在,让我们看看使用多少个1来计数各种数字。在本篇文章中,当我们尝试计算要使用多少个1表示一个数字时,我将使用n
来指定一个数字,而大写N
指定使用多少个1表示某个数字。
一位数字
以一位数字开头:
1: 1
2: 1
...
9: 1
0: 0
X
所需的1的数量为
X > 0 ? 1 : 0
。让我们定义一个数学函数
f(n)
,它将表示“计数到
n
所需的1的数量”。然后
f(X) = X > 0 ? 1 : 0
1X
形式的数字,
10: 2
11: 4
12: 5
...
19: 12
1X
要求数字1等于
f(9)
(最多9个)加上X
(如果是1X
,则从11-包括X > 0
的前几位开始)加上X
,需要许多1 f(1X) = f(9) + 1 + X + f(X)
21: 13
31: 14
...
91: 20
YX
计数到两位数字
Y > 1
所需的1的数量为
f(19)
(最多19个)加上f(9) * (Y - 2)
(从数字20中的1到包含(Y-1)9
的数字-就像Y = 5
,我的意思是20-49中的1,来自21、31、41)加上X
,需要许多1 Y > 1
,
f(YX) = f(19) + f(9) * (Y - 2) + f(X)
= f(9) + 1 + 9 + f(9) + f(9) * (Y - 2) + f(X)
= 10 + f(9) * Y + f(X)
1YX
形式的任何三位数(现在
Y
可以是任何数字),从计数到该数字的总1等于
f(99)
(最多99个)加上10 * Y + X
(从101- 1YX
的前两位开始)加上YX
最多需要1个数字f(1YX) = f(99) + 1 + YX + f(YX)
f(1X)
的并行。继续逻辑到更多数字,以1开头的数字的模式为
f(1[m-digits]) = f(10^m - 1) + 1 + [m-digits] + f([m-digits])
[m-digits]
表示长度为
m
的数字序列。
ZYX
(即
Z > 1
),要计数到它们的位数为1
f(199)
(从计数到199)加上f(99) * (Z - 2)
(从200到(Z-1)99
中的1表示)加上YX
,需要许多1 f(ZYX) = f(199) + f(99) * (Z - 2) + f(YX)
= f(99) + 1 + 99 + f(99) + f(99) * (Z - 2) + f(YX)
= 100 + f(99) * Z + f(YX)
f(Z[m-digits]) = 10^m + f(10^m - 1) * Z + f([m-digits])
Z
1-9的适当情况,并且该方法正确无误当
Z == 0
时:
f(Z[m-digits]) = f(10^m - 1) * Z + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
10^m - 1
形式的数字,例如99、999等,您可以直接评估该函数:
f(10^m - 1) = m * 10^(m-1)
10^(m-1)
数字中使用
m
次数-例如,当计数到999时,百位使用100 1,十位使用100 1,百位使用100用1代替。所以这变成
f(Z[m-digits]) = Z * m * 10^(m-1) + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
f(n)
,即达到
n
所需的1的数量。它的时间复杂度是
n
的对数。
f("")
定义为0。但这将为您节省一些调用,以便处理单个数字以及
10^m - 1
形式的数字。省略一些参数验证的方法如下:
private static Pattern nines = Pattern.compile("9+");
/** Return 10^m for m=0,1,...,18 */
private long pow10(int m) {
// implement with either pow(10, m) or a switch statement
}
public long f(String n) {
int Z = Integer.parseInt(n.substring(0, 1));
int nlen = n.length();
if (nlen == 1) {
return Z > 0 ? 1 : 0;
}
if (nines.matcher(n).matches()) {
return nlen * pow10(nlen - 1);
}
String m_digits = n.substring(1);
int m = nlen - 1;
return Z * m * pow10(m - 1) + f_impl(m_digits)
+ (Z > 1 ? pow10(m) : Z * (Long.parseLong(m_digits) + 1));
}
n
的次数,而您想知道在给定数字
n
的情况下可以达到的
N
(即1)。因此,正如我在开头提到的那样,您正在寻找第一个
n
的
f(n+1) > N
。
n = 0
开始计数,看看何时超过
N
。
public long howHigh(long N) {
long n = 0;
while (f(n+1) <= N) { n++; }
return n;
}
f
的全部目的是您不必测试每个数字。您可以大幅度地跳起来,直到找到
n
这样的
f(n+1) > N
,然后使用跳转来缩小搜索范围。我推荐的一种相当简单的方法是
exponential search在结果上设置上限,然后进行二进制搜索以缩小范围:
public long howHigh(long N) {
long upper = 1;
while (f(upper + 1) <= N) {
upper *= 2;
}
long lower = upper / 2, mid = -1;
while (lower < upper) {
mid = (lower + upper) / 2;
if (f(mid + 1) > N) {
upper = mid;
}
else {
lower = mid + 1;
}
}
return lower;
}
f
的实现是O(log(n)),指数+二进制搜索也是O(log(n)),因此最终算法应该类似于O(log ^ 2(n)),我认为N和n之间的关系足够线性,因此您也可以将其视为O(log ^ 2(N))。如果您在日志空间中搜索并明智地缓存该函数的计算值,则有可能将其降低到大约O(log(N))。确定上限后,可能会显着提高速度的一个变体会停留在
interpolation search轮中,但是正确编码很棘手。完全优化搜索算法可能是另一个问题。
关于java - 从1开始,我最多可以使用N次,可以数到多少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41581426/
看来我又被一个简单的正则表达式卡住了。 我想要什么: 1 到 999 之间的数字 可选:逗号、符号 如果输入逗号,最少1位小数,最多3位小数点应该是presebt。 Allowed: 100 999,
我需要从两列中获取最大值并将其发送到第三列。这些列的大小都是统一的,但有时大小会有所不同,但它们都将从同一个单元格开始。例如: 5 8 - 6 2 - 6 5 - 带有破折号的列需要找到其他两个之间的
我在我的网站上有一张包含用户排名列的表格,排名是一个数字,我想选择排名最高的 3 个用户,所以我查看并搜索了我认为最好的查询是那:Link (正确答案的第二个查询),但我不明白查询,如果有人能一步一步
我正在尝试制作一个点击计数器,我想收集 24 小时内的总点击次数。无论最终用户位于哪个时区,这 24 小时都应该是固定值。在 24 小时内,数据库应更新为 +1 次点击计数,一旦达到 24 小时时间范
我有一个在典型共享主机上运行的 PHP + MySQL Web 应用程序,我想知道调用最多的查询是什么以及消耗的资源量是多少。这样,我将专注于最昂贵的查询以优化资源或检测优化不佳的查询。 例如: qu
这是我“尝试”从用户输入的数字中找到最大 2 个值的代码: #include using namespace std; void maximum2(int a, int& max1,int& max
我需要编写一个 Python 函数,从具有最多“o”字符的字符串中返回单词。例如,get_most_ooo_word(['aa ao ooo']) 应该返回 ['ooo'] 和 get_most_oo
我正在寻找一种哈希算法,以创建尽可能接近字符串的唯一哈希值 (max len = 255),从而生成一个长整数 (DWORD)。 我意识到26^255 >> 2^32,但也知道英语的单词数远少于2^3
我得到了一个仅由 's','t','u','v' 作为字符组成的字符串 T。我想找到长度为 |T| 的字符串数它最多与 T 不同 n 个位置。而且每个这样的字符串在三个不同的位置不能有相同的字符,这些
我有一群“专家”(大约 300 人)可以胜任一项工作。而且我有很多工作必须完成,比如说大约 500 个。我也有信息,一个专家能做某项工作有多“好”。这将导致一个 300 x 500 的矩阵来保存权重。
我正在尝试解决这个问题,虽然我可以使用蛮力解决它,但是以下优化算法为我提供了一些测试用例的错误结果。我尝试了但无法找到代码的问题,任何人都可以帮助我。 问题:给定一个字符串 S 和整数 K,找到整数
我需要一个混合长度的正则表达式验证,总长度为 6 个字符,其中 4-6 个大写/数字字符和 0-2 个空格。 我试过 ^[A-Z0-9]{4,6}+[\s]{0,2}$ 但它导致最大长度为 8 个字符
我有一个数组 {-1,2,3,4,-3,-2,1,5} 现在我想找到给定数组的最小连续总和子数组,最多 K 次交换。 在上面的数组中,最小连续和是-5,子数组是{-3,-2} 对于 K=1 我应该如何
我们有一个简单的表格如下: ------------------------------------------------------------------------ | Name |
如果哈希不能超过 4 个字符,并且这 4 个字符只能是小写字母或数字,那么创建 String 哈希的最佳方法是什么? 我要散列的字符串有 1-255 个字符。我知道在没有冲突的情况下创建 4-char
我希望使用 Multipeer Connectivity 框架,并感谢任何关于如何最好地进行的经验之谈。 我需要在“教练”设备和最多 45 个“玩家”设备之间建立连接。他们都在同一个空间,但无法预测
给定一个数组 a,什么是实现其组合直到第 n 的最佳方法?例如: a = %i[a b c] n = 2 # Expected => [[], [:a], [:b], [:c], [:a, b], [
这个问题在这里已经有了答案: Formatting floats without trailing zeros (21 个回答) 关闭8年前。 我想格式化最多包含 2 个小数位的 float 列表。但
我无法使用以下形式的命令登录到远程 docker 注册表: docker login –u my-username –p my-password registry.myclient.com 我得到的错
所以这是我的代码:服务器.java import java.io.*; import java.net.*; import java.util.*; class Server implements R
我是一名优秀的程序员,十分优秀!