又是在力扣被题折磨的一次,反反复复地提交,反反复复的不通过,不过还好了解到了快速幂的思想,这种方式能大幅提高程序的运行速度。
题目:我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (2,3,5 或 7)。
一个 数字字符串 是每一位都由 0 到 9 组成的字符串,且可能包含前导 0.(题目来源:LeetCode)
这道题乍一看似乎挺简单,由于是让我们返回好数字的个数,对于偶数下标来说符合条件的无非就0,2,4,6,8这几个数字,而奇数下标只有1,3,5,7这四个数字。我们只需要计算每一位上符合条件的数字的个数之积,顶多再模上1000000007就是最终答案了。但是真的是这样的吗?
class Solution {
public int countGoodNumbers(long n) {
double result = 0;
if (n % 2 == 0){
result = (Math.pow(4,n/2) * Math.pow(5,n/2)) % 1000000007;
}else {
result = (Math.pow(4,n/2) * Math.pow(5,n/2 + 1)) % 1000000007;
}
return (int) result;
}
}
心想这不就完了吗,很难吗?但是最终结果就是它死活不让我过,卡在了50:

我***,这哪有什么问题,这都不让过?离谱啊...... 思考一番无果我只能去翻翻源码,这一下又让我有了新的收获:

行,那我就换个方法,不用这个pow方法,我自己写一个能得到指数值的方法不就好了吗?
/**
* 说明:这里举个例子,想简单告诉一下大家这种循环计算时会非常耗时间
*/
public class Test {
public static long normalCal(int power, int base) {
long result = 1;
for (int i = 0; i < power; i++) {
result = result * base;
}
return result;
}
public static void main(String[] args) {
long result = normalCal(30,5 );
System.out.println(result);
}
}
这里我们求的是5的30次方,那么就会执行30次循环。不难发现其时间复杂度为O(N),其中N为指数。在我们这段代码中还好,要是我换成5的100次方呢?那么会有以下两个问题:
我们先来初步认识下快速幂,给定一个2的12次方式子让你计算,你拿到这个题后会怎么想呢?
1.快速幂正好是这种思想,在计算机中2的12次方要循环12次,而我们通过将指数减半,底数平方的思想可以减少循环的次数,从而提高性能。就比如上述的2的12次方:我们通过快速幂的思想思考它是这样的:2的12次方 -> 4的6次方 -> 16的3次方 -> 256的1次方 乘以 16。前者循环了12次,而后者只需要循环4次,要是有更高指数计算,则能节省循环的次数也就不言而喻了。
那我们怎么解决因为计算出的值过大而溢出导致出错的问题呢?我们先来了解一下模的运算规律吧:
a). (a+b)%p=(a%p+b%p)%p
b). (a-b)%p=(a%p-b%p)%p
c). (a*b)%p=(a%p * b%p)%p
2.在这里只需要用到第三条结论,我们可以在计算过程中就开始不断取模,而不是等到最终结果出来之后再模运算,这样就能避免最终答案太大导致出错的问题了。
因此在进行幂运算时我们可以这样做:
public long myAns(lon base, long index) {
int k = 1000000007;
long result = 1;
while (index > 0) {//当指数减到1时跳出循环
if (index % 2 == 1) {
//奇数往这儿走,由于这里是奇数,指数减半会有余数,因此我们只需多乘以一个原来的result就行了
index = index - 1;
result = result * base % k;//乘上原来的底数
base = base * base % k;//底数平方
}else {
//偶数来这里,这里就是正常的指数减半,底数平方
index = index / 2;
base = (base * base) % k;
}
//我们可以看到这种方式节约的循环次数是指数级的
return result;
}
其实上面这个代码还能更精简一些,我们还能对它进行优化。
我们来看看整道题的全部代码:
class Solution {
//优化后的代码,这个方法就是进行幂运算
public long findMyResult(long base, long index) {
long result = 1;
while(index> 0){
if(power % 2 == 1){
result = result * base % 1000000007;
}
index = index / 2;//奇数除以2会舍去小数点后面的数,能自动实现减1操作
base = base * base % 1000000007;
}
return result;
}
public int countGoodNumbers(long n) {
if(n % 2 == 0){
long result = findMyResult(4,n/2) % 1000000007;
result = (result * findMyResult(5,n/2)) % 1000000007;
return (int) result;
}else{
long result = (findMyResult(4,n/2) % 1000000007);
result = (result * findMyResult(5,n/2 + 1)) % 1000000007;
return (int) result;
}
}
}
完 ~
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析: 在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1: print(k)k=k/2A.1000 B.10C.11D.9解析: 按照题意每次循环K/2,直到K值小于等
在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c
我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
我想为名字验证编写一个正则表达式。正则表达式应包括所有字母(拉丁/法语/德语字符等)。但是我想从中排除数字并允许-。所以基本上它是\w(减)数(加)-。请帮忙。 最佳答案 ^[\p{L}-]+$\p{L}匹配anykindofletterfromanylanguage. 关于ruby-on-rails-rails中的正则表达式匹配[\w]和"-"但不匹配数字,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c
在我的应用程序中,我有一个文本字段,用户可以在其中输入类似这样的内容"1,2,3,4"存储到数据库中。现在,当我想使用内部数字时,我有两个选择:"1,2,3,4".split(',')或string.scan(/\d+/)do|x|a两种方式我都得到一个像这样的数组["1","2","3","4"]然后我可以通过在每个数字上调用to_i来使用这些数字。有没有更好的方法可以转换"1,2,3"to[1,2,3]andnot["1","2","3"] 最佳答案 str.split(",").map{|i|i.to_i}但是这个想法对你来说
我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj
什么是测试格式验证的最佳方法让我们说一个用户名,使用字母数字的正则表达式,但不是纯数字?我一直在我的模型中使用以下验证validates:username,:format=>{:with=>/^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i}数字用户名(例如“342”)通过了验证,这是我不想要的。 最佳答案 您想“向前看”一封信:/\A(?=.*[a-z])[a-z\d]+\Z/i 关于ruby-on-rails-Rails格式验证——字母数字,但不是纯数字,我们在Sta