示例
nums = [8, 3, 12, 5, 1, 10, 7, 13]
indexDifference = 3
valueDifference = 6
答案
[maxIdx, j] = [0, 4]
我的思路是直接枚举写,但这题是中等题,一定不会让你好过的,所以也是喜提了超时,先说一下我的做题思路吧。
其实很简单就是双指针,先初始化l=0和r=l+indexDifference
,然后当r++
后,同时l++
,然后设置一个循环条件,当l>=0,l--
,代码如下所示,短是真的短,但是没有维护,一般碰到这种类型的题目一定是需要维护的,减少复杂度,将最大值最小值记录下来的同时也不破环原有的规则
class Solution {
public int[] findIndices(int[] nums, int indexDifference, int valueDifference) {
int n = nums.length;
int l=0;
int r=0;
for(int i=indexDifference;i<n;i++){
l = i-indexDifference;
while(l>=0){
if(Math.abs(nums[i]-nums[l])>=valueDifference){
return new int[]{i,l};
}
else l--;
}
}
return new int[]{-1,-1};
}
}
然后再来看看灵神的做法与其对该代码的维护和优化
来说说灵神的思路:通过一遍遍历,当然也是双指针,但是可以通过维护最大最小值,然后优化掉我的l--
,避免重复遍历,毕竟重复遍历以后,时间复杂度最坏可以到o(n*n)
。
还是画一个图可能比用言语去说更清晰一些。
画的还是有点难以理解,所以结合文字在看一遍
先初始化变量
maxIdx = 0
minIdx = 0
从 j = 3 开始遍历:
我们每次取 i = j - indexDifference
🔁 第 1 步:j = 3
, i = 0
-
nums[i] = 8
-
maxIdx = 0
,minIdx = 0
(保持) -
检查:
-
nums[maxIdx] - nums[j] = 8 - 5 = 3 < 6
❌ -
nums[j] - nums[minIdx] = 5 - 8 = -3 < 6
❌ ➡️ 不满足,继续
-
🔁 第 2 步:j = 4
, i = 1
-
nums[i] = 3
-
比较:
-
nums[1] > nums[maxIdx]
→3 > 8
❌ -
nums[1] < nums[minIdx]
→3 < 8
✅ →minIdx = 1
-
-
检查:
nums[maxIdx] - nums[4] = 8 - 1 = 7 ✅
→ 满足!
返回结果
[maxIdx, j] = [0, 4]
代码如下
class Solution {
public int[] findIndices(int[] nums, int indexDifference, int valueDifference) {
int maxIdx = 0;
int minIdx = 0;
for (int j = indexDifference; j < nums.length; j++) {
int i = j - indexDifference;
if (nums[i] > nums[maxIdx]) {
maxIdx = i;
} else if (nums[i] < nums[minIdx]) {
minIdx = i;
}
if (nums[maxIdx] - nums[j] >= valueDifference) {
return new int[]{maxIdx, j};
}
if (nums[j] - nums[minIdx] >= valueDifference) {
return new int[]{minIdx, j};
}
}
return new int[]{-1, -1};
}
}