题目:我们把只包含因子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. 优秀 H5 案例收集 vol.1(不定期更新)

    一生要历经的三种战斗http://datang.wearewer.com/ 雍正去哪儿http://news.163.com/college/special/craftsman_h5/ 比Emoji更 ...

  2. overflow应用场景

    overflow属性可以设置的值有5种: (1)visible  默认值,内容不会裁剪,呈现在元素框之外: (2)hidden 内容会被裁剪,并且子元素内容是不可见的: (3)scroll 内容会被裁 ...

  3. 在U盘上安装Damn Small Linux

    Damn Small Linux 是一个袖珍Linux发行版,整个系统只有50M左右,所以可以放到U盘中,从而可以在支持U盘启动的电脑上使用Linux,功能与LiveCD相当.   有很多种方法可以将 ...

  4. sublime使用sublimelint-luacheck屏蔽指定警告

    在成功安装SublimeLinter-lua与luacheck以后,如果没有语法error,则会进行警告提示. 如下图 waring: line contains trailing whitespac ...

  5. JSR规范整理

    Web Service技术 Java Date与Time API ( JSR 310) Java API for RESTful Web Services (JAX-RS) 1.1 (JSR 311) ...

  6. JMS-activeMq点对点模式

    上一篇对JMS进行介绍了一下,接下来总结一下activemq点对点模式以及订阅发布模式. (1)下载:首先到官网http://activemq.apache.org下载activemq (2)运行:解 ...

  7. Scala学习手记1 - 快速体验

    又重新开始了scala的学习,因为中断了太长时间,所以这次还得从零开始.学习的过程就记录在这个博客上了. 这次学习的教程是<scala程序设计 java虚拟机多核编程实战>,我在多看上买了 ...

  8. 表格布局tabelLayout

    表格布局tabelLayout 一.简介 二.实例 <!-- 这个tableRow里面有两个组件,所以是两列 --> <!-- 这个tableRow里面有三个组件,所以是三列 --& ...

  9. Go语言 channel 管道 阻塞 死锁 经典问题

    建议阅读:14.2协程间的信道 问题:为什么代码1会报死锁的错误,而代码2不会报错? 代码1: package main import ( "fmt" ) func main() ...

  10. java之字符串中查找字串的常见方法

    1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引.      int indexOf(String str, int startIndex):从指定 ...