397. 整数替换
397. 整數(shù)替換
給定一個(gè)正整數(shù) n ,你可以做如下操作:
如果 n 是偶數(shù),則用 n / 2替換 n 。
如果 n 是奇數(shù),則可以用 n + 1或n - 1替換 n 。
n 變?yōu)?1 所需的最小替換次數(shù)是多少?
示例 1:
輸入:n = 8
輸出:3
解釋:8 -> 4 -> 2 -> 1
示例 2:
輸入:n = 7
輸出:4
解釋:7 -> 8 -> 4 -> 2 -> 1
或 7 -> 6 -> 3 -> 2 -> 1
示例 3:
輸入:n = 4
輸出:2
提示:
1 <= n <= 231 - 1
解題思路
利用隊(duì)列實(shí)現(xiàn)廣度優(yōu)先搜索,按照操作次數(shù)進(jìn)行入隊(duì)操作,每次同一批出隊(duì)的,都是具有相同操作次數(shù)的,因此我們可以根據(jù)出隊(duì)的批次,得出轉(zhuǎn)化為1的操作次數(shù),每次對(duì)于出隊(duì)的元素判斷其奇偶性,如果 n 是偶數(shù),則將 n / 2入隊(duì) 。如果 n 是奇數(shù),則將 n + 1和n - 1入隊(duì)。使用set記錄已經(jīng)遍歷過的數(shù)字,防止重復(fù)。直到我們隊(duì)頭元素出現(xiàn)1,那么當(dāng)前出隊(duì)的批次則是最小的替換次數(shù)
代碼
class Solution { public:int integerReplacement(int n) {queue<long> q;set<long> seen;seen.insert(n);q.push(n);int res(0);while (!q.empty()){int size=q.size();for (int i = 0; i < size; ++i) {long cur=q.front();if (cur==1)return res;q.pop();if (cur%2==0){if (!seen.count(cur/2)){q.push(cur/2);seen.insert(cur/2);}}else {if (!seen.count(cur+1)){q.push(cur+1);seen.insert(cur+1);}if (!seen.count(cur-1)){q.push(cur-1);seen.insert(cur-1);}}}res++;}return 0;} };- 時(shí)間復(fù)雜度:O(log?n)O(\log{n})O(logn)
- 空間復(fù)雜度:O(log?n)O(\log{n})O(logn)
或者根據(jù)題意直接進(jìn)行遞歸
class Solution { public:int integerReplacement(int n) {if (n==1)return 0;if (n==INT_MAX)return 32;if (n%2==0)return integerReplacement(n/2)+1;else return min(integerReplacement(n+1),integerReplacement(n-1))+1;} };-
時(shí)間復(fù)雜度:O(?log?n)O(\phi ^{\log n})O(?logn),其中 ?=1+52≈1.618\phi = \dfrac{1+\sqrt{5}}{2} \approx 1.618?=21+5??≈1.618表示黃金分割比。
-
空間復(fù)雜度:O(log?n)O(\log n)O(logn)。每一次遞歸都會(huì)將 n 減小一半,因此需要 $O(\log n) $的棧空間。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/integer-replacement
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
總結(jié)
- 上一篇: 2029. 石子游戏 IX
- 下一篇: 梦到车祸了有什么兆头