寻找第K个丑数

把只包含质因子2、3和5的数称作丑数(Ugly Number),例如:2,3,4,5,6,8,9,10,12,15,等,习惯上我们把1当做是第一个丑数。

写一个高效算法,返回第n个丑数。

import static java.lang.Math.min;
import static java.lang.System.out;

public class UglyNumber {

	public static void main(String[] args) {
		out.println(findKthUglyNumber(1500));
	}

	/**
	 * 寻找第K个丑数
	 *
	 * @param k
	 * @return
	 */
	public static int findKthUglyNumber(int k) {
		if (k < 0) {
			return 1;// 把第一个丑数返回
		}
		int[] numbers = new int[k];
		numbers[0] = 1;
		int next = 1;
		int ugly2Index = 0;
		int ugly3Index = 0;
		int ugly5Index = 0;
		while (next < k) {
			int uglyNum = min(numbers[ugly2Index] * 2,
					min(numbers[ugly3Index] * 3, numbers[ugly5Index] * 5));
			numbers[next] = uglyNum;
			while (numbers[ugly2Index] * 2 <= numbers[next]) {
				ugly2Index++;
			}
			while (numbers[ugly3Index] * 3 <= numbers[next]) {
				ugly3Index++;
			}
			while (numbers[ugly5Index] * 5 <= numbers[next]) {
				ugly5Index++;
			}
			next++;
		}
		return numbers[k - 1];// 从0开始
	}

}
时间: 2024-08-29 01:56:52

寻找第K个丑数的相关文章

分治法寻找第k大的数

利用快速排序的思想·去做 #include<iostream>using namespace std;int FindKthMax(int*list, int left, int right, int k);int main(){ int i,n,k; while (cin >> n){ int *a = new int[n]; for (i = 0; i < n; i++) cin >> a[i]; cin >> k; cout << F

寻找第K小的数。

思想,利用快排思想,不断寻找分解点,将分界点的下标与K-1比较如果相等,返回该值,否则更新左右边界.当左右边界中的值少于等于2个时,运用插入排序,返回a[k-1] int findCut(vector<int>& a, int l, int r) { if (l + 1 >= r) { return -1; } int pivot = a[l]; int i = l, j = r; while (true) { do { i++; } while (i<r&&

算法分析---寻找丑数

什么是丑数: 一个数的因子仅仅包括2,3,5的数称为丑数.数字1特别对待也看作是丑数,所以从1開始的10个丑数分别为1,2.3.4,5,6,8,9.10.12. 因子的概念: 整数m除以n,得到无余数的商,则称n是m的一个因子.如8的因子有1.2.4.8.而丑数要求的因子仅仅包括2.3.5.所以丑数中的因子应理解为质因子. 即因子为质数.质数又称素数,指一个大于1的自然数.除了1和它自身外,不能被其它自然数整除的数. 与质数相相应的数称为合数. 如今要求写一个程序,输出从1開始的第N个丑数. 如

寻找数列中第K大的数

版权所有 未经允许 请勿擅自商用 转载请指明出处 最早看到这个问题是在那本Mark写的数据结构与算法分析的书中引论部分,当时就是瞅瞅,到了最近,在实际应用中,我需要查找一些列的数中第k大的数时,我才重新回顾品味这个问题.现在,实际问题中,我还暂时没有解决问题,但是这段思考过程很有意思,在这里给大家品味下. 具体的问题有点复杂,在这里就不赘述了,暂且将这个问题形式化的描述如下: 给定一个有限无序数列记做{an},从这个数列中找出第k大的数. 输入:数列{an},k 输出:第k大的数 首先,有个最简

剑指offer (34) 丑数

题目:只包含因子2,3,5的数成为 丑数 求从小到大第1500个丑数 通常我们把1当作第一个丑数 方法一:逐个判断每个整数是不是丑数 如何判断一个数是不是丑数? 根据定义,丑数只能被2,3,5整除,也就是说,这个数的因子中只能是2,3,5 我们不断用这个数除以2,3,5,直到最后,如果得到1,那么这个数就是丑数 bool IsUgly(int num) { assert(num >= 0); while (num % 2 == 0) { num /= 2; } while (num % 3 ==

剑指offer-第5章优化时间和空间效率(丑数)

题目:我们把只包含因子2,3,5的数叫做丑数.寻找第1500个丑数.通常把1当成第一个丑数. 思路1:第一步判断是否为丑数:丑数是只包含2,3,5的数,因此一定可以被2,3,5整除.通过求余数是否为零做为判断条件,通过除以来减小整个数的值,知道整个数为1.返回true. 第二步找到第N个丑数的值,这一种做法的缺点是,不是丑数的数也要求余数除数的运算,因此耗时.因此我们提出一种以空间换时间的方法(谁让如今硬件更新的快呢).如2思路. 思路2:我采用一个数组按照从小到大的顺序存放丑数.数组中最后一个

O(n)时间复杂度求最小的k个数和第k小的数

//思路:使用快速排序的patition函数来进行处理 时间复杂度为O(n) #include<iostream> #include<cassert> using namespace std; int partition(int *ar, int len, int low, int high) { int temp = ar[low]; while(low < high) { while(low < high && temp < ar[high])

两个有序数组的中位数(第k大的数)

问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 感觉这种题目挺难的,尤其是将算法完全写对.因为当初自己微软面试的时候遇到了,但是没有想出来思路.看网上写了一堆解法,但是将思路说得非常清楚的少之又少. 有两种思路,一个是算法导论里面的,一个是求解k大元素.建议使用下面第二种思路,代码少不容易出错. 下面的内容摘自:https://blog.csdn.net/hackbuteer1/article/details/7584838 求解中位数,算

分治法题目整理分析 找第k小的数/求逆序对数目/派

设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数. 提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数.因此可以编制int find(int a[],int left,