Skip to content

Commit ae1ca48

Browse files
authored
feat: add solutions to lc problem: No.1521 (#1767)
1 parent a18ee09 commit ae1ca48

File tree

7 files changed

+323
-2
lines changed

7 files changed

+323
-2
lines changed

solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README.md

+115-1
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,136 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53+
**方法一:哈希表 + 枚举**
54+
55+
根据题目描述,我们知道,函数 $func(arr, l, r)$ 实际上就是数组 $arr$ 下标 $l$ 到 $r$ 的元素的按位与运算的结果,即 $arr[l] \& arr[l + 1] \& \cdots \& arr[r]$。
56+
57+
如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[0, r]$。由于按位与之和随着 $l$ 的减小而单调递减,并且 $arr[i]$ 的值不超过 $10^6$,因此区间 $[0, r]$ 最多只有 $20$ 种不同的值。因此,我们可以用一个集合来维护所有的 $arr[l] \& arr[l + 1] \& \cdots \& arr[r]$ 的值。当我们从 $r$ 遍历到 $r+1$ 时,以 $r+1$ 为右端点的值,就是集合中每个值与 $arr[r + 1]$ 进行按位与运算得到的值,再加上 $arr[r + 1]$ 本身。因此,我们只需要枚举集合中的每个值,与 $arr[r]$ 进行按位与运算,就可以得到以 $r$ 为右端点的所有值,将每个值与 $target$ 相减后取绝对值,就可以得到以 $r$ 为右端点的所有值与 $target$ 的差的绝对值,其中的最小值就是答案。
58+
59+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$。其中 $n$ 和 $M$ 分别是数组 $arr$ 的长度和数组 $arr$ 中的最大值。
60+
5361
<!-- tabs:start -->
5462

5563
### **Python3**
5664

5765
<!-- 这里可写当前语言的特殊实现逻辑 -->
5866

5967
```python
60-
68+
class Solution:
69+
def closestToTarget(self, arr: List[int], target: int) -> int:
70+
ans = abs(arr[0] - target)
71+
s = {arr[0]}
72+
for x in arr:
73+
s = {x & y for y in s} | {x}
74+
ans = min(ans, min(abs(y - target) for y in s))
75+
return ans
6176
```
6277

6378
### **Java**
6479

6580
<!-- 这里可写当前语言的特殊实现逻辑 -->
6681

6782
```java
83+
class Solution {
84+
public int closestToTarget(int[] arr, int target) {
85+
int ans = Math.abs(arr[0] - target);
86+
Set<Integer> pre = new HashSet<>();
87+
pre.add(arr[0]);
88+
for (int x : arr) {
89+
Set<Integer> cur = new HashSet<>();
90+
for (int y : pre) {
91+
cur.add(x & y);
92+
}
93+
cur.add(x);
94+
for (int y : cur) {
95+
ans = Math.min(ans, Math.abs(y - target));
96+
}
97+
pre = cur;
98+
}
99+
return ans;
100+
}
101+
}
102+
```
103+
104+
### **C++**
105+
106+
```cpp
107+
class Solution {
108+
public:
109+
int closestToTarget(vector<int>& arr, int target) {
110+
int ans = abs(arr[0] - target);
111+
unordered_set<int> pre;
112+
pre.insert(arr[0]);
113+
for (int x : arr) {
114+
unordered_set<int> cur;
115+
cur.insert(x);
116+
for (int y : pre) {
117+
cur.insert(x & y);
118+
}
119+
for (int y : cur) {
120+
ans = min(ans, abs(y - target));
121+
}
122+
pre = move(cur);
123+
}
124+
return ans;
125+
}
126+
};
127+
```
128+
129+
### **Go**
130+
131+
```go
132+
func closestToTarget(arr []int, target int) int {
133+
ans := abs(arr[0] - target)
134+
pre := map[int]bool{arr[0]: true}
135+
for _, x := range arr {
136+
cur := map[int]bool{x: true}
137+
for y := range pre {
138+
cur[x&y] = true
139+
}
140+
for y := range cur {
141+
ans = min(ans, abs(y-target))
142+
}
143+
pre = cur
144+
}
145+
return ans
146+
}
147+
148+
func min(a, b int) int {
149+
if a < b {
150+
return a
151+
}
152+
return b
153+
}
154+
155+
func abs(x int) int {
156+
if x < 0 {
157+
return -x
158+
}
159+
return x
160+
}
161+
```
68162

163+
### **TypeScript**
164+
165+
```ts
166+
function closestToTarget(arr: number[], target: number): number {
167+
let ans = Math.abs(arr[0] - target);
168+
let pre = new Set<number>();
169+
pre.add(arr[0]);
170+
for (const x of arr) {
171+
const cur = new Set<number>();
172+
cur.add(x);
173+
for (const y of pre) {
174+
cur.add(x & y);
175+
}
176+
for (const y of cur) {
177+
ans = Math.min(ans, Math.abs(y - target));
178+
}
179+
pre = cur;
180+
}
181+
return ans;
182+
}
69183
```
70184

71185
### **...**

solution/1500-1599/1521.Find a Value of a Mysterious Function Closest to Target/README_EN.md

+115-1
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,132 @@
4747

4848
## Solutions
4949

50+
**Solution 1: Hash Table + Enumeration**
51+
52+
According to the problem description, we know that the function $func(arr, l, r)$ is actually the bitwise AND result of the elements in the array $arr$ from index $l$ to $r$, i.e., $arr[l] \& arr[l + 1] \& \cdots \& arr[r]$.
53+
54+
If we fix the right endpoint $r$ each time, then the range of the left endpoint $l$ is $[0, r]$. Since the sum of bitwise ANDs decreases monotonically with decreasing $l$, and the value of $arr[i]$ does not exceed $10^6$, there are at most $20$ different values in the interval $[0, r]$. Therefore, we can use a set to maintain all the values of $arr[l] \& arr[l + 1] \& \cdots \& arr[r]$. When we traverse from $r$ to $r+1$, the value with $r+1$ as the right endpoint is the value obtained by performing bitwise AND with each value in the set and $arr[r + 1]$, plus $arr[r + 1]$ itself. Therefore, we only need to enumerate each value in the set, perform bitwise AND with $arr[r]$, to obtain all the values with $r$ as the right endpoint. Then we subtract each value from $target$ and take the absolute value to obtain the absolute difference between each value and $target$. The minimum value among them is the answer.
55+
56+
The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log M)$. Here, $n$ and $M$ are the length of the array $arr$ and the maximum value in the array $arr$, respectively.
57+
5058
<!-- tabs:start -->
5159

5260
### **Python3**
5361

5462
```python
55-
63+
class Solution:
64+
def closestToTarget(self, arr: List[int], target: int) -> int:
65+
ans = abs(arr[0] - target)
66+
s = {arr[0]}
67+
for x in arr:
68+
s = {x & y for y in s} | {x}
69+
ans = min(ans, min(abs(y - target) for y in s))
70+
return ans
5671
```
5772

5873
### **Java**
5974

6075
```java
76+
class Solution {
77+
public int closestToTarget(int[] arr, int target) {
78+
int ans = Math.abs(arr[0] - target);
79+
Set<Integer> pre = new HashSet<>();
80+
pre.add(arr[0]);
81+
for (int x : arr) {
82+
Set<Integer> cur = new HashSet<>();
83+
for (int y : pre) {
84+
cur.add(x & y);
85+
}
86+
cur.add(x);
87+
for (int y : cur) {
88+
ans = Math.min(ans, Math.abs(y - target));
89+
}
90+
pre = cur;
91+
}
92+
return ans;
93+
}
94+
}
95+
```
96+
97+
### **C++**
98+
99+
```cpp
100+
class Solution {
101+
public:
102+
int closestToTarget(vector<int>& arr, int target) {
103+
int ans = abs(arr[0] - target);
104+
unordered_set<int> pre;
105+
pre.insert(arr[0]);
106+
for (int x : arr) {
107+
unordered_set<int> cur;
108+
cur.insert(x);
109+
for (int y : pre) {
110+
cur.insert(x & y);
111+
}
112+
for (int y : cur) {
113+
ans = min(ans, abs(y - target));
114+
}
115+
pre = move(cur);
116+
}
117+
return ans;
118+
}
119+
};
120+
```
121+
122+
### **Go**
123+
124+
```go
125+
func closestToTarget(arr []int, target int) int {
126+
ans := abs(arr[0] - target)
127+
pre := map[int]bool{arr[0]: true}
128+
for _, x := range arr {
129+
cur := map[int]bool{x: true}
130+
for y := range pre {
131+
cur[x&y] = true
132+
}
133+
for y := range cur {
134+
ans = min(ans, abs(y-target))
135+
}
136+
pre = cur
137+
}
138+
return ans
139+
}
140+
141+
func min(a, b int) int {
142+
if a < b {
143+
return a
144+
}
145+
return b
146+
}
147+
148+
func abs(x int) int {
149+
if x < 0 {
150+
return -x
151+
}
152+
return x
153+
}
154+
```
61155

156+
### **TypeScript**
157+
158+
```ts
159+
function closestToTarget(arr: number[], target: number): number {
160+
let ans = Math.abs(arr[0] - target);
161+
let pre = new Set<number>();
162+
pre.add(arr[0]);
163+
for (const x of arr) {
164+
const cur = new Set<number>();
165+
cur.add(x);
166+
for (const y of pre) {
167+
cur.add(x & y);
168+
}
169+
for (const y of cur) {
170+
ans = Math.min(ans, Math.abs(y - target));
171+
}
172+
pre = cur;
173+
}
174+
return ans;
175+
}
62176
```
63177

64178
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public:
3+
int closestToTarget(vector<int>& arr, int target) {
4+
int ans = abs(arr[0] - target);
5+
unordered_set<int> pre;
6+
pre.insert(arr[0]);
7+
for (int x : arr) {
8+
unordered_set<int> cur;
9+
cur.insert(x);
10+
for (int y : pre) {
11+
cur.insert(x & y);
12+
}
13+
for (int y : cur) {
14+
ans = min(ans, abs(y - target));
15+
}
16+
pre = move(cur);
17+
}
18+
return ans;
19+
}
20+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
func closestToTarget(arr []int, target int) int {
2+
ans := abs(arr[0] - target)
3+
pre := map[int]bool{arr[0]: true}
4+
for _, x := range arr {
5+
cur := map[int]bool{x: true}
6+
for y := range pre {
7+
cur[x&y] = true
8+
}
9+
for y := range cur {
10+
ans = min(ans, abs(y-target))
11+
}
12+
pre = cur
13+
}
14+
return ans
15+
}
16+
17+
func min(a, b int) int {
18+
if a < b {
19+
return a
20+
}
21+
return b
22+
}
23+
24+
func abs(x int) int {
25+
if x < 0 {
26+
return -x
27+
}
28+
return x
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public int closestToTarget(int[] arr, int target) {
3+
int ans = Math.abs(arr[0] - target);
4+
Set<Integer> pre = new HashSet<>();
5+
pre.add(arr[0]);
6+
for (int x : arr) {
7+
Set<Integer> cur = new HashSet<>();
8+
for (int y : pre) {
9+
cur.add(x & y);
10+
}
11+
cur.add(x);
12+
for (int y : cur) {
13+
ans = Math.min(ans, Math.abs(y - target));
14+
}
15+
pre = cur;
16+
}
17+
return ans;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Solution:
2+
def closestToTarget(self, arr: List[int], target: int) -> int:
3+
ans = abs(arr[0] - target)
4+
s = {arr[0]}
5+
for x in arr:
6+
s = {x & y for y in s} | {x}
7+
ans = min(ans, min(abs(y - target) for y in s))
8+
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function closestToTarget(arr: number[], target: number): number {
2+
let ans = Math.abs(arr[0] - target);
3+
let pre = new Set<number>();
4+
pre.add(arr[0]);
5+
for (const x of arr) {
6+
const cur = new Set<number>();
7+
cur.add(x);
8+
for (const y of pre) {
9+
cur.add(x & y);
10+
}
11+
for (const y of cur) {
12+
ans = Math.min(ans, Math.abs(y - target));
13+
}
14+
pre = cur;
15+
}
16+
return ans;
17+
}

0 commit comments

Comments
 (0)