注意:
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;
}