1652. 拆炸弹Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。
为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。
- 如果 k > 0 ,将第 i 个数字用 接下来 k 个数字之和替换。
- 如果 k < 0 ,将第 i 个数字用 之前 k 个数字之和替换。
- 如果 k == 0 ,将第 i 个数字用 0 替换。 由于 code 是循环的, code[n-1] 下一个元素是 code[0] ,且 code[0] 前一个元素是 code[n-1] 。
给你 循环 数组 code 和整数密钥 k ,请你返回解密后的结果来拆除炸弹!
示例 1:
输入:code = [5,7,1,4], k = 3
输出:[12,10,16,13]
解释:每个数字都被接下来 3 个数字之和替换。解密后的密码为 [7+1+4, 1+4+5, 4+5+7, 5+7+1]。注意到数组是循环连接的。
示例 2:
输入:code = [1,2,3,4], k = 0
输出:[0,0,0,0]
解释:当 k 为 0 时,所有数字都被 0 替换。
示例 3:
输入:code = [2,4,9,3], k = -2
输出:[12,5,6,13]
解释:解密后的密码为 [3+9, 2+3, 4+2, 9+4] 。注意到数组是循环连接的。如果 k 是负数,那么和为 之前 的数字。
提示:
- n == code.length
- 1 <= n <= 100
- 1 <= code[i] <= 100
- -(n - 1) <= k <= n - 1
# 思路
一个套了定长滑窗的解密游戏!!!
# 解法
class Solution {
/**
* 10 拆炸弹 1652
* 分析:
* 这题是一个套了定长滑窗的解密题
* 这里比较新颖的一点是数组是“循环数组”
* 看一看题目的解密规则:
* 若 k == 0,那么解密后的结果全是0,特殊处理一下即可。
* 若 k > 0,那么code[i] 要被替换为接下来的k个数字之和【包括i自己么?看了下示例是不包括的】
* k < 0就无需多盐了。
* 并且通过观察示例我发现是基于code计算新code,因此开新数组是没得跑了。
* 思路大概理清楚了,接下开开始干代码咯咯咯咯~
*/
public int[] decrypt(int[] code, int k) {
int n = code.length;
if(n == 1 && k != 0){
// 盐豆不盐了
return code;
}
int[] newCode = new int[n];
if(k == 0){
// 盐豆不盐了
return newCode;
}
// 特殊情况过滤完毕
// 如何初始化窗口?
/*
从code[0]开始
Ⅰ 若k > 0,那么left = 1【这就是为什么我要提前排除n == 1的原因】,right则要从left开始往右走k步(注意循环数组边界),期间收集统计量【窗口内元素和】
Ⅱ 若k < 0,那么right = 0,然后left从right开始往左走|k|步,期间收集统计量。
之后就简单了,code[0]的下一个code[1],只需要让窗口整体右移一位。
*/
// 初始化窗口
int left, right;
// 统计量
int sum = 0;
if(k > 0){
// 按照Ⅰ的流程初始化窗口
right = left = 1;
while (k-- > 0){
// 让循环体执行k次就够了
sum += code[right];
// 循环数组下标右移的核心公式
right = (right + 1) % n;
}
}else {
// 按照Ⅱ的流程初始化窗口
left = right = 0;
while (k++ < 0){
// 让循环体执行k次就够了
// 循环数组下标左移的核心公式,建议自己推一遍
left = (left - 1 + n) % n;
sum += code[left];
}
}
// 开始解密
for (int i = 0; i < n; i++) {
newCode[i] = sum;
sum += code[right];
right = (right + 1) % n;
sum -= code[left];
left = (left + 1) % n;
}
return newCode;
}
}
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
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
# 总结
- 分析出几种情况,然后分别对各个情况实现


