从Leetcode 每日一题练习 继续讨论:
1945. 字符串转化后的各位数字之和
1945. Sum of Digits of String After Convert
题解
本题是一道简单题, 只需按照题目所述过程对字符串进行转换, 在转换字符串过程中可以直接将各个字母得到的数字进行按位加和, 无需将字符串转换为整个数字后再进行处理, 因为转换成数字后也是对数字进行按位加和避免溢出可以在处理字符串的过程中直接处理. 再不断对得到的新数字重复按位加和, 此处只要加和到和小于10即可停止直接返回结果, 因为只有一位数字的情况下怎么加和都是这位数字.
代码
func getLucky(s string, k int) int {
rawnum := 0
convertbyte := 0
for i:=0;i<len(s);i++{
convertbyte = int(s[i]-'a'+1)
if convertbyte >= 10{
rawnum += convertbyte/10+convertbyte%10
}else{
rawnum += convertbyte
}
}
result := rawnum
for i:=0;i<k-1;i++{
result = 0
for rawnum > 0{
result += rawnum%10
rawnum = rawnum/10
}
if result < 10{
break
}
rawnum = result
}
return result
}
3 个赞
类型转换是要耗时的,所以如果字符串很长(k很大)的情况下从字符转换成整型再从整型转换成字符串要消耗大量没必要的时间
看strconv.Itoa的源码,每次转换都要执行这些步骤, 相当于把数字按10进制遍历了一遍,这是完全没必要的,完全可以直接使用数字来操作,转换步骤是多余的,要认识到库函数都是封装好的一系列操作,而为了通用性往往会有很多无用(与题目无关)的多余步骤,这都是可以避免的
3 个赞
sprintf要处理反射等字符串输出的内容,函数就要调用4个,我用整数直接做只需要做一次除法和一个取余,sprintf也是封装好的输出包,肯定有很多多余操作的
可以自己看看他源码 看看这些newPrinter 还有doPrintf里都有什么
return
}
// Printf formats according to a format specifier and writes to standard output.
// It returns the number of bytes written and any write error encountered.
func Printf(format string, a ...any) (n int, err error) {
return Fprintf(os.Stdout, format, a...)
}
// Sprintf formats according to a format specifier and returns the resulting string.
func Sprintf(format string, a ...any) string {
p := newPrinter()
p.doPrintf(format, a)
s := string(p.buf)
p.free()
return s
}
// Appendf formats according to a format specifier, appends the result to the byte
// slice, and returns the updated slice.
func Appendf(b []byte, format string, a ...any) []byte {
归根到底 每次循环我们都要对数字一位一位的处理,我直接对数字通过除法和取余来得到数字的每一位,你每次都要先换成字符串和字符再换回数字,多了一个中间过程,一定会多花一些时间
如果k特别大而数字很小 很早就只剩1位的情况下 后面的循环都是没必要的 用if可以早停 可以考虑k是十万但数字但当k=9时数字就已经变成8这样的情况,后面的九万多次循环只是在重复8
for循环的判断也是一种if,你不是对内存什么底层很了解吗 这个应该清楚,i<k||len(str)>1实际上就是两个if判断,另外你这种用数组的方式 在go里for range遍历数组时会创建一系列数组元素的副本即v是新开辟的内存,这部分也是很耗时的,尽管go已经有了优化
另外论坛的宗旨包含友善,说自己更简单还加几个省略号可算不上友善,给人一种“这你都想不到”的感觉 @handsome 大帅哥觉得呢
我是欢迎大家来提出各种不同解法的,因为会有新思路,但是希望不要让人有一种“你这都想不到”这样的感觉,也可能是加省略号是你的说话习惯,如果是这样的请你谅解,因为一般加省略号看上去有一种”无语“的感觉,看着有点不舒服
我看了看你的帖子 好像你确实喜欢加省略号 那是我的问题。 转换成字符串在实现的简洁上确实更好一些,整体更直观,但是性能可能需要好好研究下,共同进步,以后还希望可以多多交流
追求性能无可厚非,但是在日常的业务处理中,不推荐这种做法,因为会对业务代码产生干扰。追求极致的性能一般是用在竞赛上的,知道实现方法即可。
你可以看一下题目下面的提示,使用暴力查表的方法会有更好的性能,但是代码就过于繁琐了。