分解质因数题目

以sqrt(n) 为时间复杂度的算法并不多见,最具代表性的就是分解质因数了。

 

235. 分解质因数

 

中文

 

English

 

将一个整数分解为若干质因数之乘积。

 

样例

样例 1:

输入:10
输出:[2, 5]

样例 2:

输入:660
输出:[2, 2, 3, 5, 11]

 

注意事项

你需要从小到大排列质因子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution:
    """
    @param num: An integer
    @return: an integer array
    """
    def primeFactorization(self, num):
        # write your code here
        result = []
        k = 2
        while k*k <= num:
            if num % k == 0:
                num = num//k
                result.append(k)
            else:
                k += 1
        if num > 1:
            result.append(num)
        return result

 

 

题目描述

http://www.lintcode.com/problem/prime-factorization/

具体步骤

  1. up=[n]up = [\sqrt{n}]up=[n
  1. ],作为质因数k的上界, 初始化k=2k=2k=2。
  2. k<=upk <= upk<=up 且 n不为1 时,执行步骤3,否则执行步骤4。
  3. 当n被k整除时,不断整除并覆盖n,同时结果中记录k,直到n不能整出k为止。之后k自增,执行步骤2。
  4. 当n不为1时,把n也加入结果当中,算法结束。

几点解释

  • 不需要判定k是否为质数,如果k不为质数,且能整出n时,n早被k的因数所除。故能整除n的k必是质数。
  • 为何引入up?为了优化性能。当k大于up时,k已不可能整除n,除非k是n自身。也即为何步骤4判断n是否为1,n不为1时必是比up大的质数。
  • 步骤2中,也判定n是否为1,这也是为了性能,当n已为1时,可早停。

代码

Java:

public List<Integer> primeFactorization(int n) {
    List<Integer> result = new ArrayList<>();
    int up = (int) Math.sqrt(n);
    
    for (int k = 2; k <= up && n > 1; ++k) {
        while (n % k == 0) {
            n /= k;
            result.add(k);
        }
    }
    
    if (n > 1) {
        result.add(n);
    }
    
    return result;
}

Python:

def primeFactorization(n):
    result = []
    up = int(math.sqrt(n));
    
    k = 2
    while k <= up and n > 1: 
        while n % k == 0:
            n //= k
            result.append(k)
        k += 1
            
    if n > 1:
        result.append(n)
        
    return result

C++:

vector<int> primeFactorization(int n) {
    vector<int> result;
    int up = (int)sqrt(n);
    
    for (int k = 2; k <= up && n > 1; ++k) {
        while (n % k == 0) {
            n /= k;
            result.push_back(k);
        }
    }
    
    if (n > 1) {
        result.push_back(n);
    }
    
    return result;
}

复杂度分析

  • 最坏时间复杂度 O(n)O(\sqrt{n})O(n
  • )。当n为质数时,取到其最坏时间复杂度。
  • 空间复杂度 O(log(n))O(log(n))O(log(n)),当n质因数很多时,需要空间大,但总不会多于O(log(n))O(log(n))O(log(n))个。

延伸

质因数分解有一种更快的算法,叫做Pollard Rho快速因数分解。该算法时间复杂度为O(n1/4)O(n^{1/4})O(n1/4),其理解起来稍有难度,有兴趣的同学可以进行自学,参考链接

posted @   bonelee  阅读(1239)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2018-11-03 时间序列预测——深度好文,ARIMA是最难用的(数据预处理过程不适合工业应用),线性回归模型简单适用,预测趋势很不错,xgboost的话,不太适合趋势预测,如果数据平稳也可以使用。
2017-11-03 查看suse系统版本
2017-11-03 pyspark.mllib.feature module
2017-11-03 LSTM 时间序列数据的异常检测
2017-11-03 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否
2017-11-03 异常检测概览——孤立森林 效果是最好的
2017-11-03 异常检测——无监督、高斯分布模型,需要带标记的样本数据,基本假设:特征符合高斯分布
点击右上角即可分享
微信分享提示