这道题是在lintCode的CAT测试上遇到的,是我2019年做的第一道算法题,但是遗憾的是,我退出测试之后就再也找不到这道题了,初步测试了一下结果是正确的,希望以后能找到更好的答案。
题目如下
水仙花数:一个n位数,该数的每一位数的n次幂之和等于该数本身。
例如:
153是一个水仙花数
要求:输入位数n,输出所有n位的水仙花数。
思路如下
n位数的范围是从
所以遍历该范围的数,判断该数是否为水仙花数
/**
* n位数的范围是从10的n-1次幂到10的n次幂减1,遍历该范围的数,判断该数是否为水仙花数
* @param n
* @return
*/
public List<Integer> getNarcissisticNum(int n){
List<Integer> results = new ArrayList<Integer>();//结果集
//遍历所有n位数
for(int i=pow(10,n-1);i<pow(10,n);i++){
int cutNums[] = cutNum(i,n);//拆分该数
//int cutNums[] = cutNumByString(i,n);拆分数方法二,用String避免复杂运算
int num=0;//记录各位数的n次幂和
int j=0;//数组指针,记录当前计算到哪一位
for(j=0;j<n;j++){
num+= pow(cutNums[j],n);
//若当前结果已经大于该数,则不是水仙花数,跳出循环
if(num>i)
break;
}
//跳出循环时判断当前n次幂和是否等于该数,同时数组指针已经到达尾部,若等于则为水仙花数,添加到结果集
if(num==i&&j==n-1){
results.add(i);
}
}
return results;
}
/**
* 计算x的n次幂
* @param x
* @param n
* @return
*/
public int pow(int x,int n){
int res = 1;
for(int i=0;i<n;i++){
res*=x;
}
return res;
}
/**
* 拆分一个n位数,返回数组
* 例如365,返回[3,6,5]
* @param x
* @param n
* @return
*/
public int[] cutNum(int x,int n){
int res[] = new int[n];
for(int i=0;i<n;i++){
int num = (x/pow(10,i))%10;
res[i]=num;
}
return res;
}
/**
* 拆分n位数方法二,避免麻烦的运算
* @param x
* @return
*/
public int[] cutNumByString(int x,int n){
int res[]=new int[10];
String str = String.valueOf(x);
for(int i=0;i<str.length();i++){
res[i]=Integer.parseInt(String.valueOf(str.charAt(i)));
}
return res;
}