Lintcode 235: Prime Factorization

注意:
1)for循环里面必须是while()循环,其作用是判定i是不是n的prime factor。为什么要用while循环而不是if循环呢?因为有时候i可能出现多次,故i不动,while循环动。以n=36为例,一开始i=2,36/2=18,故将2放入result,然后i还是2,18/2=9,又将2放入result。然后9/2不是整数了,此时i=3,9/3=3,将3放入result。然后i还是3,3/3=1,又将3放入result。现在n=1了,退出来。
2)最后当n>1时,必须将n放入result。
比如n = 10,则一开始的for循环将2放入result,程序退出循环。n=5。此时应将5放入result。
什么时候会出现n == 1退出的情况,什么时候又会出现n>1的情况呢?我认为当n的prime factors都小于等于up时,最终会n == 1而退出
当n有大于up的的prime factor(此时要么n是质数,要么n有一个大于up的prime factor)时,因为for循环结束了,n还是>1,此时应将这个大于up的prime factor加入result。
注意: 我认为
n只会有1个大于up的prime factor
,否则有2个或多个大于up的prime factor的话,这几个数乘起来就大于n了。
3)
当n为质数,或有大于sqrt(n)的prime factor时,时间复杂度最高: O(sqrt(n)), 但空间复杂度最低: O(1)。
当n为2的幂时,时间复杂度最低: O(logn), 但空间复杂度最高: O(logn)。

因为当n质因数很多时,需要空间大。当n是2的幂时,质因子最多。比如说1024=222222222*2。
为什么说时间复杂度最多O(sqrt(n))呢?这种情况时当n为质数或有大于sqrt(n)的prime factor时,程序要试从2到sqrt(n))的所有数,结果都不合适。所以时间复杂度为O(sqrt(n))。
当n的prime factor都小于等于sqrt(n))时,程序不需要走到sqrt(n),num就等于1了,

代码如下:

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

class Solution {
public:
    /**
     * @param num: An integer
     * @return: an integer array
     */
    vector<int> primeFactorization(int num) {
        if (num <= 0) return vector<int>();
         
        vector<int> result;
         
        int up = sqrt(num);
        for (int i = 2; i <= up; ++i) {
            if (num == 1) return result;
            while ((num % i) == 0) {
                result.push_back(i);
                num /= i;
            }
        }
        
        if (num > 1) result.push_back(num); 
        return result;
    }
};

int main()
{
    vector<int> ret1=primeFactorization(10);
    for (auto i : ret1) cout<<i<<" ";
    cout<<endl;

    vector<int> ret2=primeFactorization(660);
    for (auto i : ret2) cout<<i<<" ";
    cout<<endl;

    vector<int> ret3=primeFactorization(1024);
    for (auto i : ret3) cout<<i<<" ";
    cout<<endl;

    return 0;
}

下面补充一个输出小于N的所有质数的程序。

#include <stdio.h>

int main() {

    int primes[10000];
    int primeCount = 1;
    primes[0] = 2;
    int N;
    scanf("%d", &N);
    printf("2\n");
    for (int i = 3; i <= N; i += 2) {
        int isDivisible = 0;
        for (int j = 0; j < primeCount; ++j) {
            if (i % primes[j] == 0) {
                isDivisible = 1;
                break;
            }
        }
        if (!isDivisible) {
            primes[primeCount++] = i;
            printf("%d\n", primes[primeCount - 1]);
        }
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值