202、快乐数
题目描述:
编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1,那么这个数就是快乐数。 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。 示例 1: 输入:n = 19 输出:true 解释: 1+81=82 64+4=68 26+64=100 1+0+0=1 示例 2: 输入:n = 2 输出:false
解题思想:
就是将n中的数分解出来,然后求每个数的平方和是否等于1;但是有问题存在 1、如果这数一个陷入循环怎么办;2、如果这个数不断的增大怎么办,例如2---4---16----37----58----- ;
解决办法:创建一个Set集合,如果n!=1&&!set.contains(n) set.add(n)
代码:
public boolean isHappy(int n){
Set<Integer> set=new HashSet<>();
while(n!=1&&!set.contains(n)){
set.add(n);
n=Found(n);
}
return n==1;
}
//计算个数的平方和
public int Found(int n){
int y=0;
while(n!=0){
int x=y%10;
y+=x*x;
y=y/10;
}
return y;
}
263、丑数判断
题目描述:
丑数 就是只包含质因数 2、3 和 5 的正整数。 给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:n = 6 输出:true 解释:6 = 2 × 3 示例 2: 输入:n = 1 输出:true 解释:1 没有质因数,因此它的全部质因数是 {2, 3, 5} 的空集。习惯上将其视作第一个丑数。 示例 3: 输入:n = 14 输出:false 解释:14 不是丑数,因为它包含了另外一个质因数 7 。
解题思想:
该数是丑数表示该数n=2*i+3*j+5*m,即该数可以用2 3 5 的倍数来表示。
因此创建一个数组prim[]用来存放2 3 5,如果该数可以循环的被数组prim整除,则该数就是丑数。
代码:
public boolean isUgly(int n){
int [] prim=new int []{2,3,5};
if(n<0)
return false;
if(n == 1 || n == 2 || n == 3 || n == 5)
return true;
if()
for(int i:prim){
if(n%i==0)
n=n/i;
}
if(n==1)
return true;
else
return false;
}
264、找出第n个丑数
题目描述:
给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是只包含质因数 2、3 和/或 5 的正整数。 示例 1: 输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。 示例 2: 输入:n = 1 输出:1 解释:1 通常被视为丑数。 提示:1 <= n <= 1690
解题思想:
1、从1开始不断的循环调用isUgly()函数来判断该数是不是丑数,如果是设标记++,直到标记等于 n;
该算法思想简单,但是对于每一个数都要调用一次isUgly()函数,效率较低
2、之前有提过丑数就 2i+3j+5m,那么我们就可以利用其定义来获取丑数。
(1)创建一个优先队列(小顶堆,即父节点最小)来存储丑数
(2)创建一个Set集合用来判断该数是否已存在
(3)先将1加入到队列和集合中去
(4)需要弹出队头元素n次,第n次为我们想要的结果
(5)对弹出的元素进行2i 3i 5i的操作并调整堆的结构仍为小顶堆
代码:
//第1种解法的代码
public int nthUglyNumber(int n){
if(n==1)
return 1;
int x=1; //标记此时是第几个丑数
int y=2; //从2开始循环
while(true){
if(isUgly(y)) //如果该数是丑数,则x++
x++;
if(x==n) //直到x==n
return x;
y++;
}
}
//第2种解题方法
public int nthUglyNumber_2(int n){
int [] prim =new int []{2,3,5};
Set<Long> set = new HashSet<Long>();//创建Set集合
PriorityQueue<Long> queue = new PriorityQueue<Long>();//创建小顶堆
//将1加入到集合和堆
set.add(1l);
queue.offer(1l);
for(int i=1;i<=n;i++) //第n次弹出的数为我们要的结果
long x=queue.poll(); //弹出对头元素
int y=(int)x;
for(int j:prim){ //对其进行 *2 ,*3 ,*5的操作
long h=y*j;
if(set.add(h)) //set.add(),如果set中不包含添加的元素返回true
queue.offer(h);
}
return y;
}
204、n的质数的数量
题目描述:
给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。 示例 1: 输入:n = 10 输出:4 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 示例 2: 输入:n = 0 输出:0 示例 3: 输入:n = 1 输出:0
解题思想:
1、从2开始不断的进行循环,去判断该数是否为质数,如果为质数,则标记加1。这个算法思想简 单,但是超时了。
2、使用埃及筛(详细的可以去看我的上一篇博客)。http://t.csdn.cn/WygNg
代码:
//第1种解题方法(这个方法虽然超时了,但是我想让大家理解一下这个思路)
public int countPrimes(int n){
if(n<=0)
return 0;
int x=0;//用来标记质数的个数
for(int i=2;i<=n;i++)
{
if(judge(i))
x++;
}
return x;
}
public boolean judge(int n){
for(int i=2;i<=Math.sqrt(n);i++)
if(n%i==0)
return false;
return true;
}
//第2种解题方法----埃及筛
public int countPrimes_2(int n){
//创建一个用来标记是否为质数的数组
int [] prim=new int[n];
int ans=0;//质数的个数
//初始化默认全都为质数
Arrays.fill(prim,1);
for(int i=2;i<n;i++)
{
if(prim[i]==1)
{
ans++;
if(i*i<n)
{
for(int j=i*i;j<n;j+=i)
prim[j]=0;
}
}
}
return ans;
}
279、完全平方数
题目描述:
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。 示例 1: 输入:n = 12 输出:3 解释:12 = 4 + 4 + 4 示例 2: 输入:n = 13 输出:2 解释:13 = 4 + 9 提示:1 <= n <= 104
解题思路:
使用动态规划的思想来解:
(1)创建一个数组f[i],用来表示最少需要几位数来表示i
(2)使f[i]=i,即最少需要i位数来表示i ;例4=1+1+1+1
(3)进入循环。递推公式为f[i]=Math.min(f[i],f[i-j*j]+1)
代码:
public int Find(int n){
int [] f=new int [n+1];
for(int i=1;i<=n;i++)
{
f[i]=i;
for(int j=1;j*j<i;j++)
f[i]=Math.min(f[i],f[i-j*j]+1);
}
return f[n];
}