Skip to content

Commit cc17920

Browse files
authored
feat: add solutions for lc No.1680 (#5049)
1 parent 987f1d0 commit cc17920

7 files changed

Lines changed: 171 additions & 34 deletions

File tree

solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README.md

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ tags:
6464

6565
### 方法一:位运算
6666

67-
观察数字的连接规律,我们可以发现,当连接到第 $i$ 个数时,实际上是将前 $i-1$ 个数连接而成的结果 $ans$ 往左移动一定的位数,然后再加上 $i$ 这个数,移动的位数 $shift$ 是 $i$ 中二进制的位数。由于 $i$ 在不断加 $1$,移动的位数要么与上一次移动的位数保持不变,要么加一。当 $i$ 为 $2$ 的幂次方的时候,也即是说 $i$ 的二进制数中只有一位是 $1$ 时,移动的位数相比于上次加 $1$
67+
观察数字的连接规律,我们可以发现,当连接到第 $i$ 个数时,实际上是将前 $i-1$ 个数连接而成的结果 $ans$ 往左移动一定的位数,然后再加上 $i$ 这个数,移动的位数是 $i$ 中二进制的位数。
6868

6969
时间复杂度 $O(n)$,其中 $n$ 为给定的整数。空间复杂度 $O(1)$。
7070

@@ -104,7 +104,7 @@ class Solution {
104104
public:
105105
int concatenatedBinary(int n) {
106106
const int mod = 1e9 + 7;
107-
long ans = 0;
107+
long long ans = 0;
108108
for (int i = 1; i <= n; ++i) {
109109
ans = (ans << (32 - __builtin_clz(i)) | i) % mod;
110110
}
@@ -129,16 +129,28 @@ func concatenatedBinary(n int) (ans int) {
129129

130130
```ts
131131
function concatenatedBinary(n: number): number {
132-
const mod = BigInt(10 ** 9 + 7);
133-
let ans = 0n;
134-
let shift = 0n;
135-
for (let i = 1n; i <= n; ++i) {
136-
if ((i & (i - 1n)) == 0n) {
137-
++shift;
132+
const mod = 1_000_000_007;
133+
let ans = 0;
134+
for (let i = 1; i <= n; i++) {
135+
ans = ((ans * (1 << (32 - Math.clz32(i)))) % mod + i) % mod;
136+
}
137+
return ans;
138+
}
139+
```
140+
141+
#### Rust
142+
143+
```rust
144+
impl Solution {
145+
pub fn concatenated_binary(n: i32) -> i32 {
146+
let mod_: i64 = 1_000_000_007;
147+
let mut ans: i64 = 0;
148+
for i in 1..=n as i64 {
149+
let bit_length: u32 = 64 - i.leading_zeros() as u32;
150+
ans = ((ans << bit_length) | i) % mod_;
138151
}
139-
ans = ((ans << shift) | i) % mod;
152+
ans as i32
140153
}
141-
return Number(ans);
142154
}
143155
```
144156

@@ -148,7 +160,11 @@ function concatenatedBinary(n: number): number {
148160

149161
<!-- solution:start -->
150162

151-
### 方法二
163+
### 方法二:位运算(优化)
164+
165+
在方法一中,我们每次都需要计算 $i$ 的二进制位数,这样会增加一些额外的计算。我们可以通过一个变量 $\textit{shift}$ 来记录当前需要移动的位数,当 $i$ 是 $2$ 的幂时,$\textit{shift}$ 需要增加 $1$。
166+
167+
时间复杂度 $O(n)$,其中 $n$ 为给定的整数。空间复杂度 $O(1)$。
152168

153169
<!-- tabs:start -->
154170

@@ -221,6 +237,42 @@ func concatenatedBinary(n int) (ans int) {
221237
}
222238
```
223239

240+
#### TypeScript
241+
242+
```ts
243+
function concatenatedBinary(n: number): number {
244+
const mod = 1_000_000_007;
245+
let ans = 0;
246+
let shift = 0;
247+
for (let i = 1; i <= n; i++) {
248+
if ((i & (i - 1)) === 0) {
249+
shift++;
250+
}
251+
ans = ((ans * (1 << shift)) % mod + i) % mod;
252+
}
253+
return ans;
254+
}
255+
```
256+
257+
#### Rust
258+
259+
```rust
260+
impl Solution {
261+
pub fn concatenated_binary(n: i32) -> i32 {
262+
let mod_: i64 = 1_000_000_007;
263+
let mut ans: i64 = 0;
264+
let mut shift: u32 = 0;
265+
for i in 1..=n as i64 {
266+
if (i & (i - 1)) == 0 {
267+
shift += 1;
268+
}
269+
ans = ((ans << shift) | i) % mod_;
270+
}
271+
ans as i32
272+
}
273+
}
274+
```
275+
224276
<!-- tabs:end -->
225277

226278
<!-- solution:end -->

solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/README_EN.md

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ tags:
2828
<pre>
2929
<strong>Input:</strong> n = 1
3030
<strong>Output:</strong> 1
31-
<strong>Explanation: </strong>&quot;1&quot; in binary corresponds to the decimal value 1.
31+
<strong>Explanation: </strong>&quot;1&quot; in binary corresponds to the decimal value 1.
3232
</pre>
3333

3434
<p><strong class="example">Example 2:</strong></p>
@@ -65,7 +65,7 @@ After modulo 10<sup>9</sup> + 7, the result is 505379714.
6565

6666
### Solution 1: Bit Manipulation
6767

68-
By observing the pattern of number concatenation, we can find that when concatenating to the $i$-th number, the result $ans$ formed by concatenating the previous $i-1$ numbers is actually shifted to the left by a certain number of bits, and then $i$ is added. The number of bits shifted, $shift$, is the number of binary digits in $i$. Since $i$ is continuously incremented by $1$, the number of bits shifted either remains the same as the last shift or increases by one. When $i$ is a power of $2$, that is, when there is only one bit in the binary number of $i$ that is $1$, the number of bits shifted increases by $1$ compared to the last time.
68+
By observing the pattern of number concatenation, we can find that when concatenating to the $i$-th number, the result $ans$ formed by concatenating the previous $i-1$ numbers is actually shifted to the left by a certain number of bits, and then $i$ is added. The number of bits shifted is the number of binary digits in $i$.
6969

7070
The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$.
7171

@@ -105,7 +105,7 @@ class Solution {
105105
public:
106106
int concatenatedBinary(int n) {
107107
const int mod = 1e9 + 7;
108-
long ans = 0;
108+
long long ans = 0;
109109
for (int i = 1; i <= n; ++i) {
110110
ans = (ans << (32 - __builtin_clz(i)) | i) % mod;
111111
}
@@ -130,16 +130,28 @@ func concatenatedBinary(n int) (ans int) {
130130

131131
```ts
132132
function concatenatedBinary(n: number): number {
133-
const mod = BigInt(10 ** 9 + 7);
134-
let ans = 0n;
135-
let shift = 0n;
136-
for (let i = 1n; i <= n; ++i) {
137-
if ((i & (i - 1n)) == 0n) {
138-
++shift;
133+
const mod = 1_000_000_007;
134+
let ans = 0;
135+
for (let i = 1; i <= n; i++) {
136+
ans = ((ans * (1 << (32 - Math.clz32(i)))) % mod + i) % mod;
137+
}
138+
return ans;
139+
}
140+
```
141+
142+
#### Rust
143+
144+
```rust
145+
impl Solution {
146+
pub fn concatenated_binary(n: i32) -> i32 {
147+
let mod_: i64 = 1_000_000_007;
148+
let mut ans: i64 = 0;
149+
for i in 1..=n as i64 {
150+
let bit_length: u32 = 64 - i.leading_zeros() as u32;
151+
ans = ((ans << bit_length) | i) % mod_;
139152
}
140-
ans = ((ans << shift) | i) % mod;
153+
ans as i32
141154
}
142-
return Number(ans);
143155
}
144156
```
145157

@@ -149,7 +161,11 @@ function concatenatedBinary(n: number): number {
149161

150162
<!-- solution:start -->
151163

152-
### Solution 2
164+
### Solution 2: Bit Manipulation (Optimization)
165+
166+
In Solution 1, we need to calculate the number of binary digits of $i$ each time, which adds some extra computation. We can use a variable $\textit{shift}$ to record the current number of bits to shift. When $i$ is a power of $2$, $\textit{shift}$ needs to be incremented by $1$.
167+
168+
The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$.
153169

154170
<!-- tabs:start -->
155171

@@ -222,6 +238,42 @@ func concatenatedBinary(n int) (ans int) {
222238
}
223239
```
224240

241+
#### TypeScript
242+
243+
```ts
244+
function concatenatedBinary(n: number): number {
245+
const mod = 1_000_000_007;
246+
let ans = 0;
247+
let shift = 0;
248+
for (let i = 1; i <= n; i++) {
249+
if ((i & (i - 1)) === 0) {
250+
shift++;
251+
}
252+
ans = ((ans * (1 << shift)) % mod + i) % mod;
253+
}
254+
return ans;
255+
}
256+
```
257+
258+
#### Rust
259+
260+
```rust
261+
impl Solution {
262+
pub fn concatenated_binary(n: i32) -> i32 {
263+
let mod_: i64 = 1_000_000_007;
264+
let mut ans: i64 = 0;
265+
let mut shift: u32 = 0;
266+
for i in 1..=n as i64 {
267+
if (i & (i - 1)) == 0 {
268+
shift += 1;
269+
}
270+
ans = ((ans << shift) | i) % mod_;
271+
}
272+
ans as i32
273+
}
274+
}
275+
```
276+
225277
<!-- tabs:end -->
226278

227279
<!-- solution:end -->

solution/1600-1699/1680.Concatenation of Consecutive Binary Numbers/Solution.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ class Solution {
22
public:
33
int concatenatedBinary(int n) {
44
const int mod = 1e9 + 7;
5-
long ans = 0;
5+
long long ans = 0;
66
for (int i = 1; i <= n; ++i) {
77
ans = (ans << (32 - __builtin_clz(i)) | i) % mod;
88
}
99
return ans;
1010
}
11-
};
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
impl Solution {
2+
pub fn concatenated_binary(n: i32) -> i32 {
3+
let mod_: i64 = 1_000_000_007;
4+
let mut ans: i64 = 0;
5+
for i in 1..=n as i64 {
6+
let bit_length: u32 = 64 - i.leading_zeros() as u32;
7+
ans = ((ans << bit_length) | i) % mod_;
8+
}
9+
ans as i32
10+
}
11+
}
Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
function concatenatedBinary(n: number): number {
2-
const mod = BigInt(10 ** 9 + 7);
3-
let ans = 0n;
4-
let shift = 0n;
5-
for (let i = 1n; i <= n; ++i) {
6-
if ((i & (i - 1n)) == 0n) {
7-
++shift;
8-
}
9-
ans = ((ans << shift) | i) % mod;
2+
const mod = 1_000_000_007;
3+
let ans = 0;
4+
for (let i = 1; i <= n; i++) {
5+
ans = ((ans * (1 << (32 - Math.clz32(i)))) % mod + i) % mod;
106
}
11-
return Number(ans);
7+
return ans;
128
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
impl Solution {
2+
pub fn concatenated_binary(n: i32) -> i32 {
3+
let mod_: i64 = 1_000_000_007;
4+
let mut ans: i64 = 0;
5+
let mut shift: u32 = 0;
6+
for i in 1..=n as i64 {
7+
if (i & (i - 1)) == 0 {
8+
shift += 1;
9+
}
10+
ans = ((ans << shift) | i) % mod_;
11+
}
12+
ans as i32
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function concatenatedBinary(n: number): number {
2+
const mod = 1_000_000_007;
3+
let ans = 0;
4+
let shift = 0;
5+
for (let i = 1; i <= n; i++) {
6+
if ((i & (i - 1)) === 0) {
7+
shift++;
8+
}
9+
ans = ((ans * (1 << shift)) % mod + i) % mod;
10+
}
11+
return ans;
12+
}

0 commit comments

Comments
 (0)