1. 263. 醜數
給你一個整數 n ,請你判斷 n 是否為 醜數 。如果是,返回 true ;否則,返回 false 。
醜數 就是隻包含質因數 2、3 或 5 的正整數。
示例 1:
輸入:n = 6
輸出:true
解釋:6 = 2 × 3
示例 3:
輸入:n = 14
輸出:false
解釋:14 不是醜數,因為它包含了另外一個質因數 7 。
題解
這個題其實很簡單。因為醜數的概念就必須是隻有2、3、5這三個質因子的數。
那它需要滿足什麼條件那
- 如果這個數是2的倍數則就除2
- 如果是3的倍數則就除3
- 如果是5的倍數就除5
如果這個是醜數的話,那這樣剩下的數一定是1。
證明
如果這個數不是1,那麼也不能是2,3,5的倍數。那麼他就必須是7, 11 這種的質因子。
這與它是醜數相悖。所以一定滿足上面說的條件,那程式碼就呼之欲出了
程式碼
class Solution {
public:
bool isUgly(int n) {
if (n < 1)return false;
while(n % 2 == 0) n /= 2;
while(n % 3 == 0) n /= 3;
while(n % 5 == 0) n /= 5;
return n == 1;
}
};
2. 264. 醜數 II
給你一個整數 n
,請你找出並返回第 n
個 醜數 。
醜數 就是隻包含質因數 2
、3
和/或 5
的正整數。
示例 1:
輸入:n = 10
輸出:12
解釋:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 個醜陣列成的序列。
示例 2:
輸入:n = 1
輸出:1
解釋:1 通常被視為醜數。
題解
這個題和上面的區別就是要我們找出第n個醜數。
實際上我們可以先列表找一個感覺1、2、3、4、5、6、8、9、10、12 .....
我們把這個序列稱為S那我們要返回的就是S[n]
我們用S2表示只包含質因子2的數。S3表示只包含質因子3的數。S5表示只包含質因子為5的數
S2 : 2, 4, 6 , 8 , ....
S3 : 3, 6, 9 , 12, 15 ...
S5 : 5, 10, 15, ....
可以發現S陣列的數就是從S2,S3,S5並操作得到的(在並上一個1)
另外一個特性就是 S2 = 2 * S, S3 = 3 * S , S5 = 5 * S
這樣就可以用三個指標指向1這個數。
然後對指標往下移動。依次取三個指標的最小值。最後就可以得到S序列,那程式碼也就好寫了
程式碼
class Solution {
public:
int nthUglyNumber(int n) {
vector<int>q(1,1); // 表示只有1這個數,是第一個醜數
for (int i = 0, j = 0, k = 0; q.size() < n; ) {
int t = min(q[i] * 2, min(q[j] * 3, q[k] * 5));
if (t == q[i] * 2) i++;
if (t == q[j] * 3) j++;
if (t == q[k] * 5) k++;
q.push_back(t);
}
return q[n - 1];
}
};
3. 313. 超級醜數
超級醜數 是一個正整數,並滿足其所有質因數都出現在質數陣列 primes
中。
給你一個整數 n
和一個整數陣列 primes
,返回第 n
個 超級醜數 。
題目資料保證第 n
個 超級醜數 在 32-bit 帶符號整數範圍內。
示例 1:
輸入:n = 12, primes = [2,7,13,19]
輸出:32
解釋:給定長度為 4 的質數陣列 primes = [2,7,13,19],前 12 個超級醜數序列為:[1,2,4,7,8,13,14,16,19,26,28,32] 。
示例 2:
輸入:n = 1, primes = [2,3,5]
輸出:1
解釋:1 不含質因數,因此它的所有質因數都在質數陣列 primes = [2,3,5] 中。
題解
這個題和上面的題,非常類似哦。
只不過是上面的要求是隻能有2,3,5而這個題目給了一個要求是隻能包含特定序列的質數
因此這裡用了一個小根堆來儲存相關的最小值。這樣每次logk
就可以了
這裡的指標移動就是向堆內加入一個新的元素
- 這裡利用這樣的一個堆儲存{value, position} position為這個值是由陣列中哪個值更新的
- 然後算除當前值是由之前的值如何更新的。因為一定是會️一個集合內的素數
- 隨後將這個集合指標往下移動那就是入堆一個{p * q[idx + 1], idx + 1}
程式碼
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
typedef pair<int,int> PII;
priority_queue<PII, vector<PII>, greater<PII>> heap;
for (auto e : primes) {
heap.push({e, 0});
}
vector<int>q(n);
q[0] = 1;
for (int i = 1; i < n; ) {
auto t = heap.top();
heap.pop();
if (t.first != q[i - 1])q[i++] = t.first;
int idx = t.second;
int p = t.first / q[idx];
heap.push({p * q[idx + 1], idx+1});
}
return q[n - 1];
}
};