-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3670-MaximumProductOfTwoIntegersWithNoCommonBits.go
More file actions
224 lines (206 loc) · 6.09 KB
/
3670-MaximumProductOfTwoIntegersWithNoCommonBits.go
File metadata and controls
224 lines (206 loc) · 6.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package main
// 3670. Maximum Product of Two Integers With No Common Bits
// You are given an integer array nums.
// Your task is to find two distinct indices i and j such that the product nums[i] * nums[j] is maximized,
// and the binary representations of nums[i] and nums[j] do not share any common set bits.
// Return the maximum possible product of such a pair.
// If no such pair exists, return 0.
// Example 1:
// Input: nums = [1,2,3,4,5,6,7]
// Output: 12
// Explanation:
// The best pair is 3 (011) and 4 (100). They share no set bits and 3 * 4 = 12.
// Example 2:
// Input: nums = [5,6,4]
// Output: 0
// Explanation:
// Every pair of numbers has at least one common set bit. Hence, the answer is 0.
// Example 3:
// Input: nums = [64,8,32]
// Output: 2048
// Explanation:
// No pair of numbers share a common bit, so the answer is the product of the two maximum elements, 64 and 32 (64 * 32 = 2048).
// Constraints:
// 2 <= nums.length <= 10^5
// 1 <= nums[i] <= 10^6
import "fmt"
import "math/bits"
import "slices"
type Tree struct {
Left *Tree
Right *Tree
Num int
NumRest int
}
func (t *Tree) Calc(arr []int, cnt int) (res int) {
if cnt == 0 { return t.NumRest }
if len(arr) == 0 {
return t.Num
}
if arr[0] == 1 && t.Left == nil {
return 0
} else if arr[0] == 1 {
return t.Left.Calc(arr[1:], cnt-1)
}
if t.Left != nil {
res = max(res, t.Left.Calc(arr[1:], cnt))
}
if t.Right != nil {
res = max(res, t.Right.Calc(arr[1:], cnt))
}
return res
}
func (t *Tree) Insert(arr []int, num int) *Tree {
if len(arr) == 0 {
t.Num = max(t.Num, num)
return t
}
if arr[0] == 1 && t.Right == nil {
t.Right = &Tree{}
t.Right = t.Right.Insert(arr[1:], num)
} else if arr[0] == 1 {
t.Right = t.Right.Insert(arr[1:], num)
} else if t.Left == nil {
t.Left = &Tree{}
t.Left.NumRest = max(t.Left.NumRest, num)
t.Left = t.Left.Insert(arr[1:], num)
} else {
t.Left.NumRest = max(t.Left.NumRest, num)
t.Left = t.Left.Insert(arr[1:], num)
}
return t
}
func maxProduct(nums []int) (res int64) {
bits := make(map[int][]int)
for i, n := range nums {
bit := make([]int, 0)
for n > 0 {
bit = append(bit, n&1)
n >>= 1
}
bits[nums[i]] = bit
}
t := &Tree{}
for k := range bits {
temp := make([]int, 20)
for i := 0; i < len(bits[k]); i++ {
temp[len(temp)-1-i] = bits[k][i]
}
bits[k] = temp
}
arr, visited := make([]bool, 1_000_001), make([]bool, 1_000_001)
for _, n := range nums {
if arr[n] { continue }
arr[n] = true
t = t.Insert(bits[n], n)
if visited[n] {continue }
visited[n] = true
count := 0
for i := 0; i < len(bits[n]); i++ {
if bits[n][i] == 1 { count++ }
}
temp := t.Calc(bits[n], count)
res = max(res, int64(temp) * int64(n))
}
return res
}
func maxProduct1(nums []int) int64 {
w := bits.Len(uint(slices.Max(nums)))
res, u := 0, 1 << w
dp := make([]int, u)
for _, v := range nums {
dp[v] = v
}
max := func (x, y int) int { if x > y { return x; }; return y; }
for i := 0; i < w; i++ {
for s := 3; s < u; s++ {
s |= 1 << i // 快速跳到第 i 位是 1 的 s
dp[s] = max(dp[s], dp[s^1<<i])
}
}
for _, v := range nums {
res = max(res, v * dp[u-1^v])
}
return int64(res)
}
func maxProduct2(nums []int) int64 {
if len(nums) < 2 {
return 0
}
// Determine how many bits are actually needed
res, bits, mx := 0, 0, 0
for _, v := range nums {
if v > mx {
mx = v
}
}
for (1 << bits) <= mx {
bits++
}
if bits == 0 {
bits = 1
}
size := 1 << bits
dp := make([]int, size)
// For each exact mask, keep the largest value with that mask
for _, v := range nums {
if v > dp[v] {
dp[v] = v
}
}
// SOS DP: for every mask store the maximum value among all of its submasks
for bit := 0; bit < bits; bit++ {
bitMask := 1 << bit
for mask := 0; mask < size; mask++ {
if mask&bitMask != 0 {
sub := mask ^ bitMask
if dp[sub] > dp[mask] {
dp[mask] = dp[sub]
}
}
}
}
allMask := size - 1
for _, v := range nums {
best := dp[allMask^v]
if best > 0 {
product := v * best
if product > res {
res = product
}
}
}
return int64(res)
}
func main() {
// Example 1:
// Input: nums = [1,2,3,4,5,6,7]
// Output: 12
// Explanation:
// The best pair is 3 (011) and 4 (100). They share no set bits and 3 * 4 = 12.
fmt.Println(maxProduct([]int{1,2,3,4,5,6,7})) // 12
// Example 2:
// Input: nums = [5,6,4]
// Output: 0
// Explanation:
// Every pair of numbers has at least one common set bit. Hence, the answer is 0.
fmt.Println(maxProduct([]int{5,6,4})) // 0
// Example 3:
// Input: nums = [64,8,32]
// Output: 2048
// Explanation:
// No pair of numbers share a common bit, so the answer is the product of the two maximum elements, 64 and 32 (64 * 32 = 2048).
fmt.Println(maxProduct([]int{64,8,32})) // 2048
fmt.Println(maxProduct([]int{1,2,3,4,5,6,7,8,9})) // 56
fmt.Println(maxProduct([]int{9,8,7,6,5,4,3,2,1})) // 56
fmt.Println(maxProduct1([]int{1,2,3,4,5,6,7})) // 12
fmt.Println(maxProduct1([]int{5,6,4})) // 0
fmt.Println(maxProduct1([]int{64,8,32})) // 2048
fmt.Println(maxProduct1([]int{1,2,3,4,5,6,7,8,9})) // 56
fmt.Println(maxProduct1([]int{9,8,7,6,5,4,3,2,1})) // 56
fmt.Println(maxProduct2([]int{1,2,3,4,5,6,7})) // 12
fmt.Println(maxProduct2([]int{5,6,4})) // 0
fmt.Println(maxProduct2([]int{64,8,32})) // 2048
fmt.Println(maxProduct2([]int{1,2,3,4,5,6,7,8,9})) // 56
fmt.Println(maxProduct2([]int{9,8,7,6,5,4,3,2,1})) // 56
}