题目:我们把只包含因子2,3,5的数叫做丑数。寻找第1500个丑数。通常把1当成第一个丑数。

思路1:第一步判断是否为丑数:丑数是只包含2,3,5的数,因此一定可以被2,3,5整除。通过求余数是否为零做为判断条件,通过除以来减小整个数的值,知道整个数为1.返回true.

第二步找到第N个丑数的值,这一种做法的缺点是,不是丑数的数也要求余数除数的运算,因此耗时。因此我们提出一种以空间换时间的方法(谁让如今硬件更新的快呢)。如2思路。

思路2:我采用一个数组按照从小到大的顺序存放丑数。数组中最后一个放入的丑数即是最大的丑数M。然后,将M之前的数分别乘以,2,3,5来找到下一个大于M的丑数。改变M的值为最后找的的丑数。在2乘以M之前的丑数的时候一定存在某个丑数在它之前的数和2相乘都小于M,之后的数都大于M。我们可以记录下这个数。并且更新它。就可以很快的找到和2相乘大于M的那个丑数了。

Java代码思路1:

//思路:第一步:判断一个数是否为丑数。由于丑数是只包好2,3,5的因子的数,因此我们自然就想到了判断一个丑数先对2进行求余数如果为0再对它进行求除数减小数的大小,
//同样对3,和5也一样,最后如果结果为1就返回true。第二步,通过判断是否为丑数来数出第N个丑数对应的值。
public class FindUglyNumber {
//判断一个数是不是丑数
public boolean isUgly(int number){
if(number<=0)
return false;
while(number%2==0)
number/=2;
while(number%3==0)
number/=3;
while(number%5==0)
number/=5;
return (number==1)?true:false;
}
public int uglyNumber(int uglyNumber){
if(uglyNumber<=0)
return 0;
int ugly=0;//记录丑数的个数
int number=0;//记录数字
while(ugly<uglyNumber){
number++;
if(isUgly(number))
ugly++;
}
return number;
}
public static void main(String[] args){
FindUglyNumber findUglyNumber=new FindUglyNumber();
int uglyNumber=findUglyNumber.uglyNumber(3);
System.out.println(uglyNumber);
} }

Java代码思路2:

//思路:将uglyNumber按照从小到大的顺序保存在数组中。因为uglyNumber是只包含2,3,5因子的数,
//因此可以用一个M表示数组中最大的数,也是数组中最后一个存入的数,而将之前的丑数分别乘2,3,5,然后保留大于M值的最小数。
//作为下一个M。我们前面说,M之前的每一个丑数都乘以2,3,5,其实这个可以确定在乘以2时在一定存在某个值,在它之前的数都小于M
//在它之后的数都大于M。
public class FindUglyNumber1 {
public int findUglyNumer(int index){
int[] uglyNumber=new int[index];
uglyNumber[0]=1;
int nextNumber=1;
int nextNumber2=0;
int nextNumber3=0;
int nextNumber5=0;
while(nextNumber<index){
int min=min(uglyNumber[nextNumber2]*2,uglyNumber[nextNumber3]*3,uglyNumber[nextNumber5]*5);
uglyNumber[nextNumber]=min;
while(uglyNumber[nextNumber2]*2<=uglyNumber[nextNumber])
nextNumber2++;
while(uglyNumber[nextNumber3]*3<=uglyNumber[nextNumber])
nextNumber3++;
while(uglyNumber[nextNumber5]*5<=uglyNumber[nextNumber])
nextNumber5++;
nextNumber++;
}
int ugly=uglyNumber[nextNumber-1];
return ugly;
} public int min(int i, int j, int k) {
int min=i<j?i:j;
return min<k?min:k;
}
public static void main(String[] args){
FindUglyNumber1 findUglyNumber=new FindUglyNumber1();
int uglyNumber=findUglyNumber.findUglyNumer(3);
System.out.println(uglyNumber);
} }

剑指offer-第5章优化时间和空间效率(丑数)的更多相关文章

  1. 剑指offer-第五章优化时间和空间效率(从1到n的整数中1出现的次数)

    题目:输入一个整数n,从1到n这n个十进制整数中1出现的次数. 思路1:对1到n中的任意一个数i对其进行求余数来判断个位是否为1,然后再求除数,判断十位是否为1.统计出1的个数.然后对1到n用一个循环 ...

  2. 剑指offer-第五章优化时间和空间效率(数组中的逆序对的总数)

    题目:在数组中如果两个数字的前面的数比后面的数大,则称为一对逆序对.输入一个数组求出数组中逆序对的总数. 以空间换时间:思路:借助一个辅助数组,将原来的数组复制到该数组中.然后将该数组分成子数组,然后 ...

  3. 剑指offer-第五章优化时间和空间效率(数组中出现次数超过一半的数字)

    题目:输入一个数组,找出一个数字,它在数组中出现的次数超过数组的一半. 题目规定如果可以改变数组中元素的位置. 思路1:如果数组是排序的,那么中间元素的位置不就是次数超过数组一半的元素吗?是的,因此我 ...

  4. 剑指offer-第五章优化时间和空间效率(把数组排列成最小的数)

    题目:输入一个正整数数组,将所有的数,排列起来,组成一个最小的数.

  5. 剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

    思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到 ...

  6. 剑指offer-第五章优化时间和空间效率(在字符串中第一次出现切只出现一次的字符)

    题目:在字符串中第一次出现切只出现一次的字符 思路:用HashMap来存放对应的char值和该char出现的次数.做一次变量就可以得到第一个只出现一次的字符. Java代码: import java. ...

  7. 剑指offer-第五章优化时间和空间效率(连续子数组的最大和)

    题目:输入一个数组,数组中有正也有负,数组中连续的一个或者连续的多个数字组成一个子数组.求所有的子数组和的最大值.要求时间复杂度为O(n) 思路:我们的最直观的想法就是求出这个数组中的所有的子数组,然 ...

  8. 剑指offer-第五章优化时间和空间效率(最小的k个数)

    题目:输入n个数,输出最小的k个数. 时间复杂度为O(n) 思路1:我们想的到的最直接的思路就是对这个N个数进行排序,然后就可以找到最小的k个了,同样可以用快排partition.但是只要找到前K个最 ...

  9. 剑指offer第五章

    剑指offer第五章 1.数组中出现次数超过一半的数 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组 ...

随机推荐

  1. CSS 边距和填充

    margin and padding are the two most commonly used properties for spacing-out elements. A margin is t ...

  2. html5 canvas js(时钟)

    <!doctype html> <html> <head> <title>canvas</title> </head> < ...

  3. Linux系统下修改IP地址、网关、DNS的基本方法

    临时修改IP地址.网关.主机名.DNS,马上生效,无需重启(重启后失效) 1.修改主机名 #hostname Slyar 2.修改IP地址(eth0为网卡名称) #ifconfig eth0 192. ...

  4. 用JAR的方式运行SpringBoot项目

    接 Spring Boot 快速入门(Eclipse) 步骤一:部署方式 Springboot 和 web 应用程序不一样,其本质上是一个 Java 应用程序,那么又如何部署呢? 通常来说,Sprin ...

  5. tar 解压命令学习与总结

    tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个 ...

  6. 使用IDEA将代码托管到GitHub步骤和错误解决

    一.下载并安装Git版本控制工具 下载地址:https://git-scm.com/downloads 注册GitHub账号:https://github.com/ 为什么托管到GitHub要下载Gi ...

  7. java 处理emoji表情信息转换为String

    2种方式实现: 注意:如果发现运行时java.lang.NoClassDefFoundError:异常就是缺少了jar包.添加对应的jar包就可以. 一.emoji-java-4.0.0.jar实现 ...

  8. 给virtualbox里linux添加共享文件夹

    首先,必须要有已经在VirtualBox中安装好的Ubuntu系统,才能按照以下步骤操作,具体怎样在VirtualBox中安装Ubuntu系统百度经验里已经有很多,大家可以自己查询参照.   打开虚拟 ...

  9. 用WebClient在异步下载或上传时每次只进行一个任务 C#

    当在每次上传或者下载的时候,我只想进行一个任务的,我用的是WebClient类,但是我又不想用同步的方法UploadFile.DownloadFile,因为WebClient这个类的同步方法没有Upl ...

  10. include,include_once,require,require_once的区别

    1.include() include(/path/to/filename) include()语句将在其被调用的位置处包含一个文件.包含一个文件与在该语句所在位置复制制定文件的数据具有相同内容的效果 ...