Skip to content

Commit 863de89

Browse files
committed
feat: update solutions to lc problems: No.0762,0763
* No.0762.Prime Number of Set Bits in Binary Representation * No.0763.Partition Labels
1 parent 04d6289 commit 863de89

File tree

10 files changed

+178
-108
lines changed

10 files changed

+178
-108
lines changed

solution/0700-0799/0762.Prime Number of Set Bits in Binary Representation/README.md

+15-16
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60-
题目中 `left``right` 的范围均在 10<sup>6</sup> 内,而 2<sup>20</sup>=1048576,因此二进制中 1 的个数最多也就 20 个,20 以内的质数为 {2, 3, 5, 7, 11, 13, 17, 19}。
60+
**方法一:数学 + 位运算**
6161

62-
我们可以遍历 `[left, right]` 范围内的每个数,计算出每个数的二进制表示中 1 的个数,判断此个数是否在上述列举的质数中,是则累加结果
62+
题目中 $left$ 和 $right$ 的范围均在 $10^6$ 以内,而 $2^{20} = 1048576$,因此,二进制中 $1$ 的个数最多也就 $20$ 个,而 $20$ 以内的质数有 `[2, 3, 5, 7, 11, 13, 17, 19]`
6363

64-
时间复杂度 `O((right-left)*log right)`,其中求二进制中 1 的个数的时间为 `O(log right)`
64+
我们枚举 $[left,.. right]$ 范围内的每个数,统计其二进制中 $1$ 的个数,然后判断该个数是否为质数,如果是,答案加一。
65+
66+
时间复杂度 $O(n\times \log m)$。其中 $n = right - left + 1$,而 $m$ 为 $[left,.. right]$ 范围内的最大数。
6567

6668
<!-- tabs:start -->
6769

@@ -82,7 +84,7 @@ class Solution:
8284

8385
```java
8486
class Solution {
85-
private static Set<Integer> primes = new HashSet<>(Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19));
87+
private static Set<Integer> primes = Set.of(2, 3, 5, 7, 11, 13, 17, 19);
8688

8789
public int countPrimeSetBits(int left, int right) {
8890
int ans = 0;
@@ -101,13 +103,10 @@ class Solution {
101103
```cpp
102104
class Solution {
103105
public:
104-
unordered_set<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
105-
106106
int countPrimeSetBits(int left, int right) {
107+
unordered_set<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
107108
int ans = 0;
108-
for (int i = left; i <= right; ++i)
109-
if (primes.count(__builtin_popcount(i)))
110-
++ans;
109+
for (int i = left; i <= right; ++i) ans += primes.count(__builtin_popcount(i));
111110
return ans;
112111
}
113112
};
@@ -116,15 +115,15 @@ public:
116115
### **Go**
117116
118117
```go
119-
func countPrimeSetBits(left int, right int) int {
120-
primes := map[int]bool{2: true, 3: true, 5: true, 7: true, 11: true, 13: true, 17: true, 19: true}
121-
ans := 0
118+
func countPrimeSetBits(left int, right int) (ans int) {
119+
primes := map[int]int{}
120+
for _, v := range []int{2, 3, 5, 7, 11, 13, 17, 19} {
121+
primes[v] = 1
122+
}
122123
for i := left; i <= right; i++ {
123-
if primes[bits.OnesCount(uint(i))] {
124-
ans++
125-
}
124+
ans += primes[bits.OnesCount(uint(i))]
126125
}
127-
return ans
126+
return
128127
}
129128
```
130129

solution/0700-0799/0762.Prime Number of Set Bits in Binary Representation/README_EN.md

+10-13
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Solution:
6767

6868
```java
6969
class Solution {
70-
private static Set<Integer> primes = new HashSet<>(Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19));
70+
private static Set<Integer> primes = Set.of(2, 3, 5, 7, 11, 13, 17, 19);
7171

7272
public int countPrimeSetBits(int left, int right) {
7373
int ans = 0;
@@ -86,13 +86,10 @@ class Solution {
8686
```cpp
8787
class Solution {
8888
public:
89-
unordered_set<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
90-
9189
int countPrimeSetBits(int left, int right) {
90+
unordered_set<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
9291
int ans = 0;
93-
for (int i = left; i <= right; ++i)
94-
if (primes.count(__builtin_popcount(i)))
95-
++ans;
92+
for (int i = left; i <= right; ++i) ans += primes.count(__builtin_popcount(i));
9693
return ans;
9794
}
9895
};
@@ -101,15 +98,15 @@ public:
10198
### **Go**
10299
103100
```go
104-
func countPrimeSetBits(left int, right int) int {
105-
primes := map[int]bool{2: true, 3: true, 5: true, 7: true, 11: true, 13: true, 17: true, 19: true}
106-
ans := 0
101+
func countPrimeSetBits(left int, right int) (ans int) {
102+
primes := map[int]int{}
103+
for _, v := range []int{2, 3, 5, 7, 11, 13, 17, 19} {
104+
primes[v] = 1
105+
}
107106
for i := left; i <= right; i++ {
108-
if primes[bits.OnesCount(uint(i))] {
109-
ans++
110-
}
107+
ans += primes[bits.OnesCount(uint(i))]
111108
}
112-
return ans
109+
return
113110
}
114111
```
115112

Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
class Solution {
22
public:
3-
unordered_set<int> primes{2, 3, 5, 7, 11, 13, 17, 19};
4-
53
int countPrimeSetBits(int left, int right) {
4+
unordered_set<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
65
int ans = 0;
7-
for (int i = left; i <= right; ++i)
8-
if (primes.count(__builtin_popcount(i)))
9-
++ans;
6+
for (int i = left; i <= right; ++i) ans += primes.count(__builtin_popcount(i));
107
return ans;
118
}
129
};
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
func countPrimeSetBits(left int, right int) int {
2-
primes := map[int]bool{2: true, 3: true, 5: true, 7: true, 11: true, 13: true, 17: true, 19: true}
3-
ans := 0
1+
func countPrimeSetBits(left int, right int) (ans int) {
2+
primes := map[int]int{}
3+
for _, v := range []int{2, 3, 5, 7, 11, 13, 17, 19} {
4+
primes[v] = 1
5+
}
46
for i := left; i <= right; i++ {
5-
if primes[bits.OnesCount(uint(i))] {
6-
ans++
7-
}
7+
ans += primes[bits.OnesCount(uint(i))]
88
}
9-
return ans
9+
return
1010
}

solution/0700-0799/0762.Prime Number of Set Bits in Binary Representation/Solution.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class Solution {
2-
private static Set<Integer> primes = new HashSet<>(Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19));
2+
private static Set<Integer> primes = Set.of(2, 3, 5, 7, 11, 13, 17, 19);
33

44
public int countPrimeSetBits(int left, int right) {
55
int ans = 0;

solution/0700-0799/0763.Partition Labels/README.md

+65-33
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,21 @@
3434

3535
<!-- 这里可写通用的实现逻辑 -->
3636

37-
先用数组或哈希表 last 记录每个字母最后一次出现的位置。
37+
**方法一:数组或哈希表 + 贪心**
38+
39+
我们先用数组或哈希表 `last` 记录字符串 $s$ 中每个字母最后一次出现的位置。
3840

3941
接下来使用贪心的方法,将字符串划分为尽可能多的片段:
4042

41-
- 从左到右遍历字符串,遍历的同时维护当前片段的开始下标 left 和结束下标 right,初始均为 0;
42-
- 对于每个访问到的字母 c,获取到最后一次出现的位置 `last[c]`。由于当前片段的结束下标一定不会小于 `last[c]`,因此令 `right = max(right, last[c])`
43-
- 当访问到下标 right 时,当前片段访问结束,当前片段的下标范围是 `[left, right]`,长度为 `right - left + 1`,将其添加到结果数组中,然后令 left = right + 1, 继续寻找下一个片段;
44-
- 重复上述过程,直至字符串遍历结束。
43+
从左到右遍历字符串,遍历的同时维护当前片段的开始下标 $left$ 和结束下标 $right$,初始均为 $0$。
44+
45+
对于每个访问到的字母 $c$,获取到最后一次出现的位置 $last[c]$。由于当前片段的结束下标一定不会小于 $last[c]$,因此令 $right = \max(right, last[c])$。
46+
47+
当访问到下标 $right$ 时,意味着当前片段访问结束,当前片段的下标范围是 $[left,.. right]$,长度为 $right - left + 1$,我们将其添加到结果数组中。然后令 $left = right + 1$, 继续寻找下一个片段。
48+
49+
重复上述过程,直至字符串遍历结束,即可得到所有片段的长度。
50+
51+
时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $s$ 的长度,而 $C$ 为字符集的大小。本题中 $C = 26$。
4552

4653
<!-- tabs:start -->
4754

@@ -52,13 +59,11 @@
5259
```python
5360
class Solution:
5461
def partitionLabels(self, s: str) -> List[int]:
55-
last = [0] * 26
56-
for i, c in enumerate(s):
57-
last[ord(c) - ord('a')] = i
62+
last = {c: i for i, c in enumerate(s)}
5863
ans = []
5964
left = right = 0
6065
for i, c in enumerate(s):
61-
right = max(right, last[ord(c) - ord('a')])
66+
right = max(right, last[c])
6267
if i == right:
6368
ans.append(right - left + 1)
6469
left = right + 1
@@ -90,36 +95,13 @@ class Solution {
9095
}
9196
```
9297

93-
### **TypeScript**
94-
95-
```ts
96-
function partitionLabels(s: string): number[] {
97-
const n = s.length;
98-
let last = new Array(26);
99-
for (let i = 0; i < n; i++) {
100-
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
101-
}
102-
let ans = [];
103-
let left = 0,
104-
right = 0;
105-
for (let i = 0; i < n; i++) {
106-
right = Math.max(right, last[s.charCodeAt(i) - 'a'.charCodeAt(0)]);
107-
if (i == right) {
108-
ans.push(right - left + 1);
109-
left = right + 1;
110-
}
111-
}
112-
return ans;
113-
}
114-
```
115-
11698
### **C++**
11799

118100
```cpp
119101
class Solution {
120102
public:
121103
vector<int> partitionLabels(string s) {
122-
vector<int> last(26);
104+
int last[26] = {0};
123105
int n = s.size();
124106
for (int i = 0; i < n; ++i) last[s[i] - 'a'] = i;
125107
vector<int> ans;
@@ -163,6 +145,29 @@ func max(a, b int) int {
163145
}
164146
```
165147

148+
### **TypeScript**
149+
150+
```ts
151+
function partitionLabels(s: string): number[] {
152+
const n = s.length;
153+
let last = new Array(26);
154+
for (let i = 0; i < n; i++) {
155+
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
156+
}
157+
let ans = [];
158+
let left = 0,
159+
right = 0;
160+
for (let i = 0; i < n; i++) {
161+
right = Math.max(right, last[s.charCodeAt(i) - 'a'.charCodeAt(0)]);
162+
if (i == right) {
163+
ans.push(right - left + 1);
164+
left = right + 1;
165+
}
166+
}
167+
return ans;
168+
}
169+
```
170+
166171
### **Rust**
167172

168173
```rust
@@ -189,6 +194,33 @@ impl Solution {
189194
}
190195
```
191196

197+
### **JavaScript**
198+
199+
```js
200+
/**
201+
* @param {string} s
202+
* @return {number[]}
203+
*/
204+
var partitionLabels = function (s) {
205+
const n = s.length;
206+
let last = new Array(26);
207+
for (let i = 0; i < n; i++) {
208+
last[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
209+
}
210+
let ans = [];
211+
let left = 0,
212+
right = 0;
213+
for (let i = 0; i < n; i++) {
214+
right = Math.max(right, last[s.charCodeAt(i) - 'a'.charCodeAt(0)]);
215+
if (i == right) {
216+
ans.push(right - left + 1);
217+
left = right + 1;
218+
}
219+
}
220+
return ans;
221+
};
222+
```
223+
192224
### **...**
193225

194226
```

0 commit comments

Comments
 (0)