如果正整数可以被 A 或 B 整除,那么它是神奇的。
返回第 N 个神奇数字。由于答案可能非常大,返回它模 10^9 + 7
的结果。
示例 1:输入:N = 1, A = 2, B = 3 输出:2 示例 2:输入:N = 4, A = 2, B = 3 输出:6 示例 3:
输入:N = 5, A = 2, B = 4 输出:10 示例 4:输入:N = 3, A = 6, B = 4 输出:8
提示:
1 <= N <= 10^9
2 <= A <= 40000
2 <= B <= 40000
由题知要求A/B的倍数即可,按照顺序;
该数字被A或B任一整除即可,中间的数字可能既被A整除也被B整除,所以要去除交集:N/A+N/B-N/(AB)。
给出的数可能太大,所以设一个大的区间ll,用二分法来找出第N个数
class Solution {
public:
int gongyue(int a,int b)//求最大公约数
{
return b==0?a:gongyue(b,a%b);
}
int nthMagicalNumber(int N, int A, int B) {
long long low=0,high=2000000000000000000L;
int g=A*B/gongyue(A,B);
while(low<high)//二分法
{
long long mid=(low+high)/2;
long long t=mid/A+mid/B-mid/g;
if(t<N)
low=mid+1;
else
high=mid;
}
return (int)(high%1000000007);
}
};
这道题类似于求第N个丑数,只不过丑数根据那三个数就可以确定,每次*一个丑数,比较三个最小的,依次增加,这道题中按照这种做法要增加整除数大小的指针来进行比较。
class Solution {
public:
int min(int number1, int number2, int number3)
{
int min = (number1 < number2) ? number1:number2;
min = (min < number3) ? min:number3;
return min;
}
int GetUglyNumber_Solution(int index) {
if (index <= 0)
{
return 0;
}
int *puglynumber = new int[index];
puglynumber[0] = 1;
int *puglymulty2 = puglynumber;
int *puglymulty3 = puglynumber;
int *puglymulty5 = puglynumber;//三个指标
int uglynumberindex = 1;//记录丑数的个数
while (uglynumberindex < index)
{
int m = min(*puglymulty2 * 2, *puglymulty3 * 3, *puglymulty5 * 5);
puglynumber[uglynumberindex] = m;
//下边就是更新2,3,5的指标
if (*puglymulty2 * 2 <= m)//小于等于当前最大的丑数,则要更新
{ //因为在这个指标之前的数乘以2都比当前
puglymulty2++; //的最大丑数小,
}
if (*puglymulty3 * 3 <= m)
{
puglymulty3++;
}
if (*puglymulty5 * 5 <= m)
{
puglymulty5++;
}
uglynumberindex++;
}
int ugly = puglynumber[uglynumberindex - 1];
return ugly;
}
};