思路
这道题第一次见到的时候发现解法可以很暴力。
Java版本代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static List<Integer> revert(int num) {
List<Integer> list = new ArrayList<>();
for (int i = 2; i <= num; i++) {
if (num % i == 0) {
list.add(i);
num /= i;
i--;
}
}
if (list.isEmpty()) {
list.add(num);
}
return list;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
List<Integer> list = revert(a);
list.forEach(integer -> System.out.print(integer + " "));
}
}
} 就是从2开始反复的去除输入的数字,发现可以整除就输出。这种解法的好处就是简单,但是坏处也很明显,就是特别慢,我的这段代码的执行时间已经达到了3259ms,基本快超时了。
继续审视这道题,发现这其实是判断素数的一个变种。
我们知道,如果一个数不是素数,那么这个数字一定会有至少一个因子小于sqrt(number),另外会有一个因子大于sqrt(number),根据这个原理改造一下代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static List<Integer> revert(int num) {
List<Integer> list = new ArrayList<>();
int end = (int) Math.sqrt(num);
for (int i = 2; i <= end; i++) {
while (num % i == 0) {
list.add(i);
num /= i;
}
if (num == 1) {
break;
}
}
// 这一句负责找到那个大于num平方根的因子
if (num != 1) {
list.add(num);
}
if (list.isEmpty()) {
list.add(num);
}
return list;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
List<Integer> list = revert(a);
list.forEach(integer -> System.out.print(integer + " "));
}
}
} 这一段代码的执行时间就只有185ms了。
另外还是要感叹C语言的效率,同样的算法,执行只需要3ms:
#include <stdio.h>
#include <math.h>
int main(void)
{
int num;
scanf("%d", &num);
int end = (int) sqrt(num);
for (int i = 2; i <= end; i++)
{
while (num % i == 0)
{
printf("%d ", i);
num /= i;
}
if (num == 1)
{
break;
}
}
if (num != 1)
{
printf("%d ", num);
}
return 0;
} 
京公网安备 11010502036488号