文章目錄
- 題目
- 標題和出處
- 難度
- 題目描述
- 要求
- 示例
- 數據范圍
- 解法
- 思路和算法
- 代碼
- 復雜度分析
題目
標題和出處
標題:連接連續二進制數字
出處:1680. 連接連續二進制數字
難度
5 級
題目描述
要求
給定一個整數 n \texttt{n} n,將 1 \texttt{1} 1 到 n \texttt{n} n 的二進制表示連接得到一個二進制數,返回連接得到的二進制數對應的十進制數對 10 9 + 7 \texttt{10}^\texttt{9} + \texttt{7} 109+7 取余的結果。
示例
示例 1:
輸入: n = 1 \texttt{n = 1} n?=?1
輸出: 1 \texttt{1} 1
解釋:二進制的 "1" \texttt{"1"} "1" 對應十進制的 1 \texttt{1} 1。
示例 2:
輸入: n = 3 \texttt{n = 3} n?=?3
輸出: 27 \texttt{27} 27
解釋:二進制下, 1 \texttt{1} 1、 2 \texttt{2} 2 和 3 \texttt{3} 3 分別對應 "1" \texttt{"1"} "1"、 "10" \texttt{"10"} "10" 和 "11" \texttt{"11"} "11"。
將它們依次連接,得到 "11011" \texttt{"11011"} "11011",對應十進制的 27 \texttt{27} 27。
示例 3:
輸入: n = 12 \texttt{n = 12} n?=?12
輸出: 505379714 \texttt{505379714} 505379714
解釋:連接結果為 "1101110010111011110001001101010111100" \texttt{"1101110010111011110001001101010111100"} "1101110010111011110001001101010111100",對應十進制的 118505380540 \texttt{118505380540} 118505380540。
對 10 9 + 7 \texttt{10}^\texttt{9} + \texttt{7} 109+7 取余后,結果為 505379714 \texttt{505379714} 505379714。
數據范圍
- 1 ≤ n ≤ 10 5 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{5} 1≤n≤105
解法
思路和算法
由于 1 1 1 到 n n n 的二進制表示的連接結果可能很長,因此需要在遍歷連接結果的過程中計算結果。
初始時,連接結果是 0 0 0。當遍歷到整數 i i i 時,假設 1 1 1 到 i ? 1 i - 1 i?1 的連接結果對應的整數是 x x x,整數 i i i 的二進制表示有 bits \textit{bits} bits 位,則 1 1 1 到 i ? 1 i - 1 i?1 的連接結果對應的整數是將 x x x 左移 bits \textit{bits} bits 位之后加 i i i。因此,只要知道 1 1 1 到 n n n 的每個整數的二進制表示的位數,即可得到連接的結果對應的整數。
如果正整數 x x x 是 2 2 2 的整數次冪,則 x x x 的二進制表示的位數比 x ? 1 x - 1 x?1 的二進制表示的位數多 1 1 1,這里規定 0 0 0 的二進制表示的位數是 0 0 0。正整數 x x x 是 2 2 2 的整數次冪等價于 x & ( x ? 1 ) = 0 x ~\&~ (x - 1) = 0 x?&?(x?1)=0,因此可以在 O ( 1 ) O(1) O(1) 的時間內判斷一個整數是不是 2 2 2 的整數次冪。
由此可以得到如下解法。
用 num \textit{num} num 表示連接結果,用 bits \textit{bits} bits 表示當前整數的二進制表示的位數,初始時 num \textit{num} num 和 bits \textit{bits} bits 都是 0 0 0。依次遍歷從 1 1 1 到 n n n 的每個整數,對于整數 i i i,執行如下操作。
-
判斷 i i i 是否是 2 2 2 的整數次冪。如果 i & ( i ? 1 ) = 0 i ~\&~ (i - 1) = 0 i?&?(i?1)=0,則 i i i 是 2 2 2 的整數次冪,將 bits \textit{bits} bits 加 1 1 1,否則 bits \textit{bits} bits 不變。此時 bits \textit{bits} bits 是 i i i 的二進制表示的位數。
-
將 num \textit{num} num 的值更新為 ( num < < bits ) + i (\textit{num} << \textit{bits}) + i (num<<bits)+i,并將更新后的值對 1 0 9 + 7 10^9 + 7 109+7 取余。
遍歷結束之后, num \textit{num} num 即為 1 1 1 到 n n n 的二進制表示的連接結果對應的整數。
需要注意的是,由于 n n n 的最大值是 1 0 5 10^5 105,因此 bits \textit{bits} bits 的最大值是 17 17 17, nums < < bits \textit{nums} << \textit{bits} nums<<bits 的結果可能超出 32 32 32 位整數的范圍。為了避免溢出,應將 num \textit{num} num 聲明為 long \texttt{long} long 型,返回結果時轉成 int \texttt{int} int 型。
代碼
class Solution {public int concatenatedBinary(int n) {final int MODULO = 1000000007;long num = 0;int bits = 0;for (int i = 1; i <= n; i++) {if ((i & (i - 1)) == 0) {bits++;}num = ((num << bits) + i) % MODULO;}return (int) num;}
}
復雜度分析
-
時間復雜度: O ( n ) O(n) O(n),其中 n n n 是給定的整數。需要遍歷 n n n 個整數,每個整數的操作時間都是 O ( 1 ) O(1) O(1)。
-
空間復雜度: O ( 1 ) O(1) O(1)。