题解 | #质数因子#
质数因子
https://www.nowcoder.com/practice/196534628ca6490ebce2e336b47b3607
package main
import (
"fmt"
"math"
)
func main() {
var n int
fmt.Scanln(&n)
factors := getPrimeFactors(n)
for _, factor := range factors {
fmt.Printf("%d ", factor)
}
}
func getPrimeFactors(n int) []int {
factors := []int{}
// 处理2的因子
for n%2 == 0 {
factors = append(factors, 2)
n /= 2
}
// 处理大于2的奇数因子
sqrtN := int(math.Sqrt(float64(n)))
for i := 3; i <= sqrtN; i += 2 {
for n%i == 0 {
factors = append(factors, i)
n /= i
}
}
// 如果n是一个大于2的质数,则n本身就是一个因子
if n > 2 {
factors = append(factors, n)
}
return factors
}
正确示例:
改进思路: 对于2这个特殊的质因数,我们可以在进入循环之前先处理,以减少循环次数。
最后,如果经过上述处理后,n仍然大于2,说明n本身就是一个大于2的质数,将其作为一个因子添加到结果中。 通过以上改进,我们可以减少内层循环的次数,从而改善程序的时间复杂度。
该优化的算法使用两个循环。第一个循环处理2作为质因子的情况,将2不断整除n,并将2添加到质因子列表中。第二个循环从3开始以步长为2循环,只考虑奇数作为质因子的可能性。这样可以减少循环次数。
通过使用这种优化方法,时间复杂度从O(n)降低到了O(sqrt(n)),在处理较大的整数时会更加高效。
占用时间超时:
package main
import ( "fmt" )
func main() { var n int fmt.Scanln(&n)
factors := getPrimeFactors(n)
for _, factor := range factors {
fmt.Printf("%d ", factor)
}
}
func getPrimeFactors(n int) []int { factors := []int{}
for i := 2; i <= n; i++ {
for n%i == 0 {
factors = append(factors, i)
n /= i
}
}
return factors
}
此代码中,我们通过一个getPrimeFactors函数来获取正整数的所有质因子。该函数使用两个循环嵌套,外层的循环从2开始递增,内层的循环用于判断当前数字是否是n的因子。如果是因子,则将其添加到factors数组中,并将n除以该因子,以继续寻找下一个因子。
最后,在主函数中,我们先读取用户输入的整数值n,然后调用getPrimeFactors函数获取所有质因子,并按照从小到大的顺序打印出来。
请注意,由于数据范围较大(1≤n≤2×10^9+14),在某些情况下,计算所有质因子可能需要较长时间。如果输入的数字非常大,可能需要优化算法或使用更高效的质因数分解方法来提高性能。
为了优化代码的时间复杂度,可以对获取正整数的所有质因子的部分进行改进。目前的实现方式是通过从2开始循环除以n,并判断是否能整除来找到质因子。这种方法的时间复杂度是O(n)。