Skip to content

Commit 91b3f1d

Browse files
authored
feat: add solutions to lc problem: No.3020 (doocs#2279)
No.3020.Find the Maximum Number of Elements in Subset
1 parent a980a4f commit 91b3f1d

File tree

7 files changed

+236
-313
lines changed

7 files changed

+236
-313
lines changed

solution/3000-3099/3020.Find the Maximum Number of Elements in Subset/README.md

+81-104
Original file line numberDiff line numberDiff line change
@@ -45,54 +45,51 @@
4545

4646
## 解法
4747

48-
### 方法一
48+
### 方法一:哈希表 + 枚举
49+
50+
我们用一个哈希表 $cnt$ 记录数组 $nums$ 中每个元素出现的次数。对于每个元素 $x$,我们可以将其不断平方,直到其值在哈希表 $cnt$ 中的出现次数小于 $2$ 为止。此时,我们判断 $x$ 在哈希表 $cnt$ 中的出现次数是否为 $1$,如果是则说明 $x$ 仍然可以被选入子集中,否则我们需要从子集中删除一个元素,确保子集个数为奇数。然后我们更新答案。继续枚举下一个元素。
51+
52+
注意我们需要特殊处理 $x = 1$ 的情况。
53+
54+
时间复杂度 $O(n \times \log \log M)$,空间复杂度 $O(n)$。其中 $n$ 和 $M$ 分别是数组 $nums$ 的长度和数组 $nums$ 中的最大值。
4955

5056
<!-- tabs:start -->
5157

5258
```python
5359
class Solution:
5460
def maximumLength(self, nums: List[int]) -> int:
55-
d = {}
56-
for num in sorted(nums)[::-1]:
57-
if num**2 in d and num in d and num != 1:
58-
d[num] = d[num**2] + 2
59-
else:
60-
d[num] = 1
61-
ones = nums.count(1)
62-
return max(max(d.values()), ones - (ones % 2 == 0))
63-
61+
cnt = Counter(nums)
62+
ans = cnt[1] - (cnt[1] % 2 ^ 1)
63+
del cnt[1]
64+
for x in cnt:
65+
t = 0
66+
while cnt[x] > 1:
67+
x = x * x
68+
t += 2
69+
t += 1 if cnt[x] else -1
70+
ans = max(ans, t)
71+
return ans
6472
```
6573

6674
```java
6775
class Solution {
6876
public int maximumLength(int[] nums) {
69-
TreeMap<Integer, Integer> map = new TreeMap<>();
70-
for (int i : nums) {
71-
map.put(i, map.getOrDefault(i, 0) + 1);
77+
Map<Long, Integer> cnt = new HashMap<>();
78+
for (int x : nums) {
79+
cnt.merge((long) x, 1, Integer::sum);
7280
}
73-
int max = 0;
74-
75-
for (Map.Entry<Integer, Integer> i : map.entrySet()) {
76-
System.out.println(i.getValue());
77-
if (i.getValue() >= 2 && i.getKey() != 1) {
78-
int x = i.getKey();
79-
int c = 2;
80-
while (map.containsKey(x * x)) {
81-
if (map.get(x * x) == 1) {
82-
max = Math.max(max, c + 1);
83-
break;
84-
} else if (map.get(x * x) >= 2) {
85-
max = Math.max(max, c + 1);
86-
x = x * x;
87-
}
88-
c += 2;
89-
}
81+
Integer t = cnt.remove(1L);
82+
int ans = t == null ? 0 : t - (t % 2 ^ 1);
83+
for (long x : cnt.keySet()) {
84+
t = 0;
85+
while (cnt.getOrDefault(x, 0) > 1) {
86+
x = x * x;
87+
t += 2;
9088
}
89+
t += cnt.getOrDefault(x, -1);
90+
ans = Math.max(ans, t);
9191
}
92-
if (map.containsKey(1) && map.get(1) - 1 > max) {
93-
return (map.get(1) % 2 != 0) ? map.get(1) : map.get(1) - 1;
94-
}
95-
return max == 0 ? 1 : max;
92+
return ans;
9693
}
9794
}
9895
```
@@ -101,90 +98,70 @@ class Solution {
10198
class Solution {
10299
public:
103100
int maximumLength(vector<int>& nums) {
104-
long long ans = 0;
105-
map<int, int> freq;
106-
for (auto n : nums) {
107-
freq[n]++;
101+
unordered_map<long long, int> cnt;
102+
for (int x : nums) {
103+
++cnt[x];
108104
}
109-
for (auto [k, f] : freq) {
110-
long long t = k, count = 0;
111-
if (t == 1) {
112-
count += freq[t];
113-
freq[t] = 0;
105+
int ans = cnt[1] - (cnt[1] % 2 ^ 1);
106+
cnt.erase(1);
107+
for (auto [v, _] : cnt) {
108+
int t = 0;
109+
long long x = v;
110+
while (cnt.count(x) && cnt[x] > 1) {
111+
x = x * x;
112+
t += 2;
114113
}
115-
while (t < INT_MAX && freq[t] > 0) {
116-
count += 2;
117-
if (freq[t] == 1) {
118-
break;
119-
}
120-
freq[t] = 0;
121-
t = t * t;
122-
}
123-
if (count % 2 == 0) {
124-
count--;
125-
}
126-
ans = max(ans, count);
114+
t += cnt.count(x) ? 1 : -1;
115+
ans = max(ans, t);
127116
}
128117
return ans;
129118
}
130119
};
131120
```
132121
133122
```go
134-
func minExp(x, c int) (int, int) {
135-
d := math.Sqrt(float64(x))
136-
if d < 2 || float64(int(d)) < d {
137-
return x, c
138-
}
139-
return minExp(int(d), c+1)
140-
}
141-
func maximumLength(nums []int) int {
142-
m := make(map[int][]int)
143-
for i := range nums {
144-
base, c := minExp(nums[i], 1)
145-
m[base] = append(m[base], c)
146-
}
147-
max := 1
148-
for _, v := range m {
149-
v := matchPattern(v)
150-
max = Max(max, v)
123+
func maximumLength(nums []int) (ans int) {
124+
cnt := map[int]int{}
125+
for _, x := range nums {
126+
cnt[x]++
151127
}
152-
_, ok := m[1]
153-
if ok {
154-
if len(m[1])%2 > 0 {
155-
max = Max(max, len(m[1]))
128+
ans = cnt[1] - (cnt[1]%2 ^ 1)
129+
delete(cnt, 1)
130+
for x := range cnt {
131+
t := 0
132+
for cnt[x] > 1 {
133+
x = x * x
134+
t += 2
135+
}
136+
if cnt[x] > 0 {
137+
t += 1
156138
} else {
157-
max = Max(max, len(m[1])-1)
139+
t -= 1
158140
}
141+
ans = max(ans, t)
159142
}
160-
return max
143+
return
161144
}
162-
func Max(i, j int) int {
163-
if i > j {
164-
return i
165-
}
166-
return j
167-
}
168-
func matchPattern(arr []int) int {
169-
sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })
170-
start := arr[0]
171-
bin := 2
172-
for i := range arr {
173-
if bin == 0 {
174-
start++
175-
bin = 2
176-
}
177-
if arr[i] == start {
178-
bin--
179-
}
180-
}
181-
if bin == 1 {
182-
return 2*(start-arr[0]) + 1
183-
} else if bin == 0 {
184-
return 2*(start-arr[0]) + 1
185-
} else {
186-
return 2*(start-arr[0]) - 1
187-
}
145+
```
146+
147+
```ts
148+
function maximumLength(nums: number[]): number {
149+
const cnt: Map<number, number> = new Map();
150+
for (const x of nums) {
151+
cnt.set(x, (cnt.get(x) ?? 0) + 1);
152+
}
153+
let ans = cnt.has(1) ? cnt.get(1)! - (cnt.get(1)! % 2 ^ 1) : 0;
154+
cnt.delete(1);
155+
for (let [x, _] of cnt) {
156+
let t = 0;
157+
while (cnt.has(x) && cnt.get(x)! > 1) {
158+
x = x * x;
159+
t += 2;
160+
}
161+
t += cnt.has(x) ? 1 : -1;
162+
ans = Math.max(ans, t);
163+
}
164+
return ans;
188165
}
189166
```
190167

0 commit comments

Comments
 (0)