1680. Concatenation of Consecutive Binary Numbers

練習日期:2026-02-28

難度:Medium

類型:Math、Bit Manipulation、Simulation

📘 題目敘述

給你一個整數 n,請把 1n 的二進位表示依序串接起來,形成一個很長的二進位字串。回傳這個二進位字串對應的十進位數值,並對 10^9 + 7 取模。

條件限制

  • 1 <= n <= 10^5

🧠 解題思路

這題如果真的去建立那條很長的二進位字串再轉回十進位,長度會爆,而且成本很高。所以要改成「邊串邊算」的方式。

假設目前已經串好 1..(x-1) 的結果是 ans(十進位),現在要把 x 的二進位接到右邊。

如果 x 的二進位長度是 len,那把 x 接到右邊的十進位等價操作就是:

  • ans = ans * 2^len + x

原因是:在二進位往左移 len 位,等價於乘上 2^len,然後再加上 x 就是把它接在尾巴。

所以整題變成從 1 跑到 n,每次算出當前數字的 bit 長度 len,再做一次 ans = ans * 2^len + now,每一步都取模即可。

這份寫法重點是邏輯直觀:每次乘上 2^len 代表左移 len 格,再加上 now 就完成串接。

所有變數

  • c:模數 1e9+7
  • ans:目前串接結果的十進位值(每一步都會取模)。
  • now:目前要接上的數字(從 1 跑到 n)。
  • lennow 的 bit 長度,用 (int)log2(now) + 1 計算。

🪜 主要流程步驟

1. 初始化

  • ans = 0
  • now = 1
  • c = 1e9+7

2. 迴圈把 1 到 n 串起來

對每個 now

  • 計算 len = (int)log2(now) + 1
  • 先把 ans 左移 len 位:ans *= 2^len
  • 再把 now 接到尾巴:ans += now
  • 取模:ans %= c
  • now++

3. 回傳答案

  • 回傳 ans

⏱️ 複雜度

  • 時間複雜度:O(n),從 1 到 n 每個數字處理一次。
  • 空間複雜度:O(1),只使用固定數量變數。

💻 程式碼實作

class Solution {
public:
    int concatenatedBinary(int n) {
        const int c = 1000000007;
        long long ans = 0;
        int now = 1;
        while (now <= n) {
            ans *= pow(2, (int)log2(now) + 1);
            ans += now;
            ans %= c;
            now++;
        }
        return ans;
    }
};

https://leetcode.com/problems/concatenation-of-consecutive-binary-numbers/

作者: scottnick
撰寫日期: 2026-02-28
類別:
原文連結: https://scottnick.github.io/cpp-notes/all%20problems/1680-concatenation-of-consecutive-binary-numbers.html