丑数是唯一素数为2、3或5的数。序列1、2、3、4、5、6、8、9、10、12、15…显示前11个丑数。按照惯例,其中包括1。
给定数字n,任务是找到第n个丑数。
例子:
Input : n = 7
Output : 8
Input : n = 10
Output : 12
Input : n = 15
Output : 24
Input : n = 150
Output : 5832
方法1(简单)
循环所有正整数,直到一个丑陋的数字小于n(如果一个整数丑陋而不是递增的丑陋数字计数)。
要检查数字是否丑陋,请将该数字除以2、3和5的最大可除幂。如果数字变为1,则它是丑陋的数字,否则不是。
例如,让我们看看如何检查300是否丑陋。 2的最大可乘幂是4,将300除以4后得到75。3的最大可乘幂是3,将75除以3后得到25。5的最大可乘幂是25,将25除以25后得到1由于我们最终得到1,所以300是丑数。
下面是上述方法的实现:
C++
// CPP program to find nth ugly number
#include
#include
// This function divides a by greatest divisible
// power of b
int maxDivide(int a, int b)
{
while (a % b == 0)
a = a / b;
return a;
}
// Function to check if a number is ugly or not
int isUgly(int no)
{
no = maxDivide(no, 2);
no = maxDivide(no, 3);
no = maxDivide(no, 5);
return (no == 1) ? 1 : 0;
}
// Function to get the nth ugly number
int getNthUglyNo(int n)
{
int i = 1;
// ugly number count
int count = 1;
// Check for all integers untill ugly count
// becomes n
while (n > count) {
i++;
if (isUgly(i))
count++;
}
return i;
}
// Driver Code
int main()
{
// Function call
unsigned no = getNthUglyNo(150);
printf("150th ugly no. is %d ", no);
getchar();
return 0;
}
Java
// Java program to find nth ugly number
class GFG {
/*This function divides a by greatest
divisible power of b*/
static int maxDivide(int a, int b)
{
while (a % b == 0)
a = a / b;
return a;
}
/* Function to check if a number
is ugly or not */
static int isUgly(int no)
{
no = maxDivide(no, 2);
no = maxDivide(no, 3);
no = maxDivide(no, 5);
return (no == 1) ? 1 : 0;
}
/* Function to get the nth ugly
number*/
static int getNthUglyNo(int n)
{
int i = 1;
// ugly number count
int count = 1;
// check for all integers
// until count becomes n
while (n > count) {
i++;
if (isUgly(i) == 1)
count++;
}
return i;
}
/* Driver Code*/
public static void main(String args[])
{
int no = getNthUglyNo(150);
// Function call
System.out.println("150th ugly "
+ "no. is " + no);
}
}
// This code has been contributed by
// Amit Khandelwal (Amit Khandelwal 1)
Python3
# Python3 code to find nth ugly number
# This function divides a by greatest
# divisible power of b
def maxDivide(a, b):
while a % b == 0:
a = a / b
return a
# Function to check if a number
# is ugly or not
def isUgly(no):
no = maxDivide(no, 2)
no = maxDivide(no, 3)
no = maxDivide(no, 5)
return 1 if no == 1 else 0
# Function to get the nth ugly number
def getNthUglyNo(n):
i = 1
# ugly number count
count = 1
# Check for all integers untill
# ugly count becomes n
while n > count:
i += 1
if isUgly(i):
count += 1
return i
# Driver code
no = getNthUglyNo(150)
print("150th ugly no. is ", no)
# This code is contributed by "Sharad_Bhardwaj".
C#
// C# program to find nth ugly number
using System;
class GFG {
/*This function divides a by
greatest divisible power of b*/
static int maxDivide(int a, int b)
{
while (a % b == 0)
a = a / b;
return a;
}
/* Function to check if a number
is ugly or not */
static int isUgly(int no)
{
no = maxDivide(no, 2);
no = maxDivide(no, 3);
no = maxDivide(no, 5);
return (no == 1) ? 1 : 0;
}
/* Function to get the nth ugly
number*/
static int getNthUglyNo(int n)
{
int i = 1;
// ugly number count
int count = 1;
// Check for all integers
// until count becomes n
while (n > count) {
i++;
if (isUgly(i) == 1)
count++;
}
return i;
}
// Driver code
public static void Main()
{
int no = getNthUglyNo(150);
// Function call
Console.WriteLine("150th ugly"
+ " no. is " + no);
}
}
// This code is contributed by Sam007.
PHP
$count)
{
$i++;
if (isUgly($i))
$count++;
}
return $i;
}
// Driver Code
$no = getNthUglyNo(150);
echo "150th ugly no. is ". $no;
// This code is contributed by Sam007
?>
Javascript
C++
// C++ program to find n'th Ugly number
#include
using namespace std;
// Function to get the nth ugly number
unsigned getNthUglyNo(unsigned n)
{
// To store ugly numbers
unsigned ugly[n];
unsigned i2 = 0, i3 = 0, i5 = 0;
unsigned next_multiple_of_2 = 2;
unsigned next_multiple_of_3 = 3;
unsigned next_multiple_of_5 = 5;
unsigned next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++) {
next_ugly_no = min(
next_multiple_of_2,
min(next_multiple_of_3, next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2) {
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3) {
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5) {
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
// End of for loop (i=1; i
Java
// Java program to find nth ugly number
import java.lang.Math;
class UglyNumber
{
// Function to get the nth ugly number
int getNthUglyNo(int n)
{
// To store ugly numbers
int ugly[] = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no
= Math.min(next_multiple_of_2,
Math.min(next_multiple_of_3,
next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
// End of for loop (i=1; i
Python
# Python program to find n'th Ugly number
# Function to get the nth ugly number
def getNthUglyNo(n):
ugly = [0] * n # To store ugly numbers
# 1 is the first ugly number
ugly[0] = 1
# i2, i3, i5 will indicate indices for
# 2,3,5 respectively
i2 = i3 = i5 = 0
# Set initial multiple value
next_multiple_of_2 = 2
next_multiple_of_3 = 3
next_multiple_of_5 = 5
# Start loop to find value from
# ugly[1] to ugly[n]
for l in range(1, n):
# Shoose the min value of all
# available multiples
ugly[l] = min(next_multiple_of_2,
next_multiple_of_3,
next_multiple_of_5)
# Increment the value of index accordingly
if ugly[l] == next_multiple_of_2:
i2 += 1
next_multiple_of_2 = ugly[i2] * 2
if ugly[l] == next_multiple_of_3:
i3 += 1
next_multiple_of_3 = ugly[i3] * 3
if ugly[l] == next_multiple_of_5:
i5 += 1
next_multiple_of_5 = ugly[i5] * 5
# Return ugly[n] value
return ugly[-1]
# Driver Code
def main():
n = 150
print getNthUglyNo(n)
if __name__ == '__main__':
main()
# This code is contributed by Neelam Yadav
C#
// C# program to count inversions in an array
using System;
using System.Collections.Generic;
class GFG {
// Function to get the nth ugly number
static int getNthUglyNo(int n)
{
// To store ugly numbers
int[] ugly = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no
= Math.Min(next_multiple_of_2,
Math.Min(next_multiple_of_3,
next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
return next_ugly_no;
}
// Driver code
public static void Main()
{
int n = 150;
// Function call
Console.WriteLine(getNthUglyNo(n));
}
}
// This code is contributed by Sam007
PHP
Javascript
C++
// C++ Implemenatation of the above approach
#include
using namespace std;
int nthUglyNumber(int n)
{
// Base cases...
if(n==1 or n==2 or n==3 or n==4 or n==5)
return n;
set s;
s.insert(1);
n--;
while(n)
{
auto it=s.begin();
//Get the beginning element of the set
long long int x=*it;
// Deleting the ith element
s.erase(it);
// Inserting all the other options
s.insert(x*2);
s.insert(x*3);
s.insert(x*5);
n--;
}
// The top of the set represents the nth ugly number
return *s.begin();
}
// Driver Code
int main()
{
int n=150;
// Function call
cout<
C++
// CPP program for the above approach
#include
using namespace std;
// Print nth Ugly number
int nthUglyNumber(int n)
{
int pow[40] = { 1 };
// stored powers of 2 from
// pow(2,0) to pow(2,30)
for (int i = 1; i <= 30; ++i)
pow[i] = pow[i - 1] * 2;
// Initialized low and high
int l = 1, r = 2147483647;
int ans = -1;
// Applying Binary Search
while (l <= r) {
// Found mid
int mid = l + ((r - l) / 2);
// cnt stores total numbers of ugly
// number less than mid
int cnt = 0;
// Iterate from 1 to mid
for (long long i = 1; i <= mid; i *= 5)
{
// Possible powers of i less than mid is i
for (long long j = 1; j * i <= mid; j *= 3)
{
// possible powers of 3 and 5 such that
// their product is less than mid
// using the power array of 2 (pow) we are
// trying to find the max power of 2 such
// that i*J*power of 2 is less than mid
cnt += upper_bound(pow, pow + 31,
mid / (i * j)) - pow;
}
}
// If total numbers of ugly number
// less than equal
// to mid is less than n we update l
if (cnt < n)
l = mid + 1;
// If total numbers of ugly number
// less than qual to
// mid is greater than n we update
// r and ans simultaneously.
else
r = mid - 1, ans = mid;
}
return ans;
}
// Driver Code
int main()
{
int n = 150;
// Function Call
cout << nthUglyNumber(n);
return 0;
}
150th ugly no. is 5832
此方法效率不高,因为它会检查所有整数,直到丑陋的数字计数变为n,但此方法的空间复杂度为O(1)方法2(使用动态编程)
这是具有O(n)额外空间的省时解决方案。丑数序列是1、2、3、4、5、6、8、9、10、12、15…
因为每个数字只能被2、3、5除,所以查看序列的一种方法是将序列分成三组,如下所示:
(1)1×2、2×2、3×2、4×2、5×2,…
(2)1×3、2×3、3×3、4×3、5×3,…
(3)1×5、2×5、3×5、4×5、5×5,…
我们可以发现每个子序列都是丑序列本身(1、2、3、4、5,…)乘以2、3、5。然后我们使用类似的合并方法作为合并排序,从三个序列中获取每个丑数子序列。每一步我们都选择最小的一步,然后再向前迈一步。
1 Declare an array for ugly numbers: ugly[n]
2 Initialize first ugly no: ugly[0] = 1
3 Initialize three array index variables i2, i3, i5 to point to
1st element of the ugly array:
i2 = i3 = i5 =0;
4 Initialize 3 choices for the next ugly no:
next_mulitple_of_2 = ugly[i2]*2;
next_mulitple_of_3 = ugly[i3]*3
next_mulitple_of_5 = ugly[i5]*5;
5 Now go in a loop to fill all ugly numbers till 150:
For (i = 1; i < 150; i++ )
{
/* These small steps are not optimized for good
readability. Will optimize them in C program */
next_ugly_no = Min(next_mulitple_of_2,
next_mulitple_of_3,
next_mulitple_of_5);
ugly[i] = next_ugly_no
if (next_ugly_no == next_mulitple_of_2)
{
i2 = i2 + 1;
next_mulitple_of_2 = ugly[i2]*2;
}
if (next_ugly_no == next_mulitple_of_3)
{
i3 = i3 + 1;
next_mulitple_of_3 = ugly[i3]*3;
}
if (next_ugly_no == next_mulitple_of_5)
{
i5 = i5 + 1;
next_mulitple_of_5 = ugly[i5]*5;
}
}/* end of for loop */
6.return next_ugly_no
例子:
让我们看看它是如何工作的
initialize
ugly[] = | 1 |
i2 = i3 = i5 = 0;
First iteration
ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(2, 3, 5)
= 2
ugly[] = | 1 | 2 |
i2 = 1, i3 = i5 = 0 (i2 got incremented )
Second iteration
ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 3, 5)
= 3
ugly[] = | 1 | 2 | 3 |
i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )
Third iteration
ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 6, 5)
= 4
ugly[] = | 1 | 2 | 3 | 4 |
i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )
Fourth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 5)
= 5
ugly[] = | 1 | 2 | 3 | 4 | 5 |
i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )
Fifth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 10)
= 6
ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 |
i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )
Will continue same way till I < 150
C++
// C++ program to find n'th Ugly number
#include
using namespace std;
// Function to get the nth ugly number
unsigned getNthUglyNo(unsigned n)
{
// To store ugly numbers
unsigned ugly[n];
unsigned i2 = 0, i3 = 0, i5 = 0;
unsigned next_multiple_of_2 = 2;
unsigned next_multiple_of_3 = 3;
unsigned next_multiple_of_5 = 5;
unsigned next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++) {
next_ugly_no = min(
next_multiple_of_2,
min(next_multiple_of_3, next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2) {
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3) {
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5) {
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
// End of for loop (i=1; i
Java
// Java program to find nth ugly number
import java.lang.Math;
class UglyNumber
{
// Function to get the nth ugly number
int getNthUglyNo(int n)
{
// To store ugly numbers
int ugly[] = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no
= Math.min(next_multiple_of_2,
Math.min(next_multiple_of_3,
next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
// End of for loop (i=1; i
Python
# Python program to find n'th Ugly number
# Function to get the nth ugly number
def getNthUglyNo(n):
ugly = [0] * n # To store ugly numbers
# 1 is the first ugly number
ugly[0] = 1
# i2, i3, i5 will indicate indices for
# 2,3,5 respectively
i2 = i3 = i5 = 0
# Set initial multiple value
next_multiple_of_2 = 2
next_multiple_of_3 = 3
next_multiple_of_5 = 5
# Start loop to find value from
# ugly[1] to ugly[n]
for l in range(1, n):
# Shoose the min value of all
# available multiples
ugly[l] = min(next_multiple_of_2,
next_multiple_of_3,
next_multiple_of_5)
# Increment the value of index accordingly
if ugly[l] == next_multiple_of_2:
i2 += 1
next_multiple_of_2 = ugly[i2] * 2
if ugly[l] == next_multiple_of_3:
i3 += 1
next_multiple_of_3 = ugly[i3] * 3
if ugly[l] == next_multiple_of_5:
i5 += 1
next_multiple_of_5 = ugly[i5] * 5
# Return ugly[n] value
return ugly[-1]
# Driver Code
def main():
n = 150
print getNthUglyNo(n)
if __name__ == '__main__':
main()
# This code is contributed by Neelam Yadav
C#
// C# program to count inversions in an array
using System;
using System.Collections.Generic;
class GFG {
// Function to get the nth ugly number
static int getNthUglyNo(int n)
{
// To store ugly numbers
int[] ugly = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no
= Math.Min(next_multiple_of_2,
Math.Min(next_multiple_of_3,
next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
return next_ugly_no;
}
// Driver code
public static void Main()
{
int n = 150;
// Function call
Console.WriteLine(getNthUglyNo(n));
}
}
// This code is contributed by Sam007
的PHP
Java脚本
5832
时间复杂度: O(n)
辅助空间: O(n)
超级丑陋数字(主要因子在给定集中的数字)
方法3(在C++中使用SET数据结构)
在此方法中,SET数据结构用于存储3个生成的丑陋编号中的最小值,这将是第i个丑陋编号存储在集合的第一个位置。 SET数据结构作为一个集合按升序存储所有元素
下面是上述方法的实现:
C++
// C++ Implemenatation of the above approach
#include
using namespace std;
int nthUglyNumber(int n)
{
// Base cases...
if(n==1 or n==2 or n==3 or n==4 or n==5)
return n;
set s;
s.insert(1);
n--;
while(n)
{
auto it=s.begin();
//Get the beginning element of the set
long long int x=*it;
// Deleting the ith element
s.erase(it);
// Inserting all the other options
s.insert(x*2);
s.insert(x*3);
s.insert(x*5);
n--;
}
// The top of the set represents the nth ugly number
return *s.begin();
}
// Driver Code
int main()
{
int n=150;
// Function call
cout<
5832
时间复杂度: -O(N log N)
辅助空间: -O(N)
方法4(使用二进制搜索)
- 如果您具有n的最大值,则此方法适用。 no的形式为x = pow(2,p)* pow(3,q)* pow(5,r)。
- 从低= 1到高= 21474836647进行搜索。我们期望第n个丑陋的no处于此范围内。
- 因此,我们进行了二进制搜索。现在假设我们现在是中点,我们将查找少于中点的丑陋总数,并相应地设置条件。
以下是大致的CPP代码:
C++
// CPP program for the above approach
#include
using namespace std;
// Print nth Ugly number
int nthUglyNumber(int n)
{
int pow[40] = { 1 };
// stored powers of 2 from
// pow(2,0) to pow(2,30)
for (int i = 1; i <= 30; ++i)
pow[i] = pow[i - 1] * 2;
// Initialized low and high
int l = 1, r = 2147483647;
int ans = -1;
// Applying Binary Search
while (l <= r) {
// Found mid
int mid = l + ((r - l) / 2);
// cnt stores total numbers of ugly
// number less than mid
int cnt = 0;
// Iterate from 1 to mid
for (long long i = 1; i <= mid; i *= 5)
{
// Possible powers of i less than mid is i
for (long long j = 1; j * i <= mid; j *= 3)
{
// possible powers of 3 and 5 such that
// their product is less than mid
// using the power array of 2 (pow) we are
// trying to find the max power of 2 such
// that i*J*power of 2 is less than mid
cnt += upper_bound(pow, pow + 31,
mid / (i * j)) - pow;
}
}
// If total numbers of ugly number
// less than equal
// to mid is less than n we update l
if (cnt < n)
l = mid + 1;
// If total numbers of ugly number
// less than qual to
// mid is greater than n we update
// r and ans simultaneously.
else
r = mid - 1, ans = mid;
}
return ans;
}
// Driver Code
int main()
{
int n = 150;
// Function Call
cout << nthUglyNumber(n);
return 0;
}
5832
时间复杂度: O(log N)
辅助空间: O(1)