Skip to content

Commit c770a94

Browse files
author
lucifer
committed
feat: $1521
1 parent 47a8145 commit c770a94

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
421421
- [1255. 得分最高的单词集合](./problems/1255.maximum-score-words-formed-by-letters.md)
422422
- [1345. 跳跃游戏 IV](./problems/1435.jump-game-iv.md)
423423
- [1449. 数位成本和为目标值的最大数字](./problems/1449.form-largest-integer-with-digits-that-add-up-to-target.md) 🆕
424+
- [1521. 找到最接近目标值的函数值](./problems/1521.find-a-value-of-a-mysterious-function-closest-to-target.md) 🆕
424425
- [1526. 形成目标数组的子数组最少增加次数](./problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md) 🆕
425426
- [1649. 通过指令创建有序数组](./problems/1649.create-sorted-array-through-instructions.md) 🆕
426427
- [1707. 与数组中元素的最大异或值](./problems/5640.maximum-xor-with-an-element-from-array.md) 🆕

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@
257257
* [1203. 项目管理](../problems/1203.sort-items-by-groups-respecting-dependencies.md) 🆕
258258
* [1255. 得分最高的单词集合](problems/1255.maximum-score-words-formed-by-letters.md)
259259
* [1345. 跳跃游戏 IV](problems/1435.jump-game-iv.md) 🆕
260-
* [1449. 数位成本和为目标值的最大数字](problems/1449.form-largest-integer-with-digits-that-add-up-to-target.md)
260+
* [1449. 数位成本和为目标值的最大数字](problems/1449.form-largest-integer-with-digits-that-add-up-to-target.md) 🆕
261+
* [1521. 找到最接近目标值的函数值](./problems/1521.find-a-value-of-a-mysterious-function-closest-to-target.md) 🆕
261262
* [1526. 形成目标数组的子数组最少增加次数](./problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md) 🆕
262263
* [1649. 通过指令创建有序数组](./problems/1649.create-sorted-array-through-instructions.md) 🆕
263264
* [1707. 与数组中元素的最大异或值](./problems/5640.maximum-xor-with-an-element-from-array.md) 🆕
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
## 题目地址(1521. 找到最接近目标值的函数值)
2+
3+
https://leetcode-cn.com/problems/find-a-value-of-a-mysterious-function-closest-to-target/
4+
5+
## 题目描述
6+
7+
![](https://tva1.sinaimg.cn/large/008eGmZEly1gmvco08jr1j30hn08owex.jpg)
8+
9+
```
10+
Winston 构造了一个如上所示的函数 func 。他有一个整数数组 arr 和一个整数 target ,他想找到让 |func(arr, l, r) - target| 最小的 l 和 r 。
11+
12+
请你返回 |func(arr, l, r) - target| 的最小值。
13+
14+
请注意, func 的输入参数 l 和 r 需要满足 0 <= l, r < arr.length 。
15+
16+
 
17+
18+
示例 1:
19+
20+
输入:arr = [9,12,3,7,15], target = 5
21+
输出:2
22+
解释:所有可能的 [l,r] 数对包括 [[0,0],[1,1],[2,2],[3,3],[4,4],[0,1],[1,2],[2,3],[3,4],[0,2],[1,3],[2,4],[0,3],[1,4],[0,4]], Winston 得到的相应结果为 [9,12,3,7,15,8,0,3,7,0,0,3,0,0,0] 。最接近 5 的值是 7 和 3,所以最小差值为 2 。
23+
示例 2:
24+
25+
输入:arr = [1000000,1000000,1000000], target = 1
26+
输出:999999
27+
解释:Winston 输入函数的所有可能 [l,r] 数对得到的函数值都为 1000000 ,所以最小差值为 999999 。
28+
示例 3:
29+
30+
输入:arr = [1,2,4,8,16], target = 0
31+
输出:0
32+
 
33+
34+
提示:
35+
36+
1 <= arr.length <= 10^5
37+
1 <= arr[i] <= 10^6
38+
0 <= target <= 10^7
39+
40+
41+
```
42+
43+
## 前置知识
44+
45+
- 位运算
46+
- 动态规划
47+
48+
## 公司
49+
50+
- 暂无
51+
52+
## 思路
53+
54+
首先我们要知道一个前提,那就是对于一个数组 arr,对 arr 的子数组 arr[l:r] 进行与操作满足单调性,也就是说 arr[l:r] >= arr[l+1:r] >= arr[l+2:r] ... 。其中的依据是**一个数异或另外一个数的结果一定不会比这两个数大**
55+
56+
为了更好的理解本题。我们可以从一个简单的例子入手。
57+
58+
题目描述:
59+
60+
```
61+
如果让你求一个数组的连续子数组总个数,你会如何求?其中连续指的是数组的索引连续。 比如 [1,3,4],其连续子数组有:[1], [3], [4], [1,3], [3,4] , [1,3,4],你需要返回 6。
62+
```
63+
64+
一种思路是总的连续子数组个数等于:以索引为 0 结尾的子数组个数 + 以索引为 1 结尾的子数组个数 + … + 以索引为 n - 1 结尾的子数组个数,这无疑是完备的。
65+
66+
> 关于这点不熟悉的,也可以看下我的 [【西法带你学算法】一次搞定前缀和](https://lucifer.ren/blog/2020/09/27/atMostK/)
67+
68+
![](https://tva1.sinaimg.cn/large/008eGmZEly1gmvd7r6v4tj306u06g3yl.jpg)
69+
70+
我们也可以采用同样的思路进行枚举。
71+
72+
总的连续子数组按位与操作等于:以索引为 0 结尾的子数组按位与操作的结果, 以索引为 1 结尾的子数组按位与操作的结果 + … + 以索引为 n - 1 结尾的子数组按位与操作的结果,这无疑是完备的。
73+
74+
而题目我求的不是总和,而是与 target 最接近的,不过这不难,使用一个全局变量记录即可。
75+
76+
以索引为 i 结尾的子数组按位与操作的结果 sub[i] 其实就等于 `sub[i-1] & A[i]`。这提示我们使用滚动数组来完成。而由于重复数字是没有意义的,因此可使用 hashset 来优化,而不是普通的数组,这样可以同时降低时间和空间复杂度。
77+
78+
> 关于滚动数组可以参考我之前写的动态规划章节
79+
80+
这种解法其实就是暴力求解,和动态规划没有啥区别。
81+
82+
## 关键点
83+
84+
- 识别出函数 func 满足某种单调性
85+
- 采用合适的枚举方法
86+
87+
## 代码
88+
89+
代码支持:Python3
90+
91+
```python
92+
class Solution:
93+
def closestToTarget(self, A: List[int], target: int) -> int:
94+
seen = set()
95+
ans = float('inf')
96+
for a in A:
97+
seen.add(a)
98+
t = set()
99+
# 类似滚动数组 此时的 seen 相当于 sub[i-1]
100+
for b in seen:
101+
yu = a & b
102+
ans = min(ans, abs(yu - target))
103+
t.add(yu)
104+
# 此时的 t 就是 sub[i],我们需要更新回 seen
105+
seen = t
106+
return ans
107+
```
108+
109+
**复杂度分析**
110+
令 N 为数组长度, C 为 seen 的大小。C 的大小和数据范围有关,在这里 C 不会超过 32。
111+
112+
- 时间复杂度:$O(N*C)$
113+
- 空间复杂度:$O(C)$
114+
115+
更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
116+
117+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
118+
119+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)

0 commit comments

Comments
 (0)