1438. 绝对差不超过限制的最长连续子数组
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
如果不存在满足条件的子数组,则返回 0 。
思路
1.一开始思考找到全局的最值作差,但是符合题意的数组位置不能进行确定,因此滑动窗口寻找。
2.滑动窗口,需要存储窗口数组内的最值,作差。
3.每个滑动窗口对应一个数组,每次移动增加或者删除一个数。可以用treemap来维护。
4.Treemap底层是红黑树实现,实现了sortedmap接口和navigablemap接口,所以有序而且能根据顺序查找到不同的键(比如第一个和最后一个)。
5.滑动窗口其实就是双指针。用两个指针来维护滑动窗口的大小
错误
1.忽视了TreeMap是一个去重的有序集合。(好像在java中没有集合即能有序又能保留所有的元素)
2.如果能排序滑动窗口,方便获取第一以及最后一个元素,还能保留所有元素,这个题就很好做。
3.用Treemap解题有一个点就是,存储的值不是位置,而是值的出现次数。对right指针来说如果出现了两次以及以上,说明对结果没有影响,可以继续。如果没有出现,则添加。对于left指针来说,如果在添加了之后发现超过了limit的值,那么需要将left对应出现的次数减1(结果为0则删除该键,说明已经不存在窗口中)。做完判断之后,left右移。
完整代码
public int longestSubarray(int[] nums, int limit) {
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
int left = 0;
int right = 0;
int ans= 0;
while(right < nums.length) {
if(map.containsKey(nums[right])) {
map.put(nums[right],map.get(nums[right]) + 1);
}else {
map.put(nums[right], 1);
}
while(map.lastKey() - map.firstKey() > limit) {
map.put(nums[left], map.get(nums[left]) - 1);
if(map.get(nums[left]) == 0) {
map.remove(nums[left]);
}
left++;
}
ans = Math.max(ans, right - left + 1);//当插值小于等于limit-
right++;
}
return ans;
}
973. 最接近原点的 K 个点
我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。
(这里,平面上两点之间的距离是欧几里德距离。)
你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。
思路
1.寻找K个最接近的点,维护一个大根堆,大小为k,最后剩下的K个值就是距离最小的K个点
语法
将小根堆转换成大根堆,需要给集合PriorityQueue传入一个新的比较器。
PriorityQueue<int[]> maxheap = new PriorityQueue<int[]>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// TODO Auto-generated method stub
return o2[0] - o1[0];//按照距离排序
}
});
完整代码
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> maxheap = new PriorityQueue<int[]>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// TODO Auto-generated method stub
return o2[0] - o1[0];//按照距离排序
}
});
for (int i = 0; i < K; i++) {
maxheap.offer(new int[]{points[i][0] * points[i][0] + points[i][1] * points[i][1],i});
}
for (int j = K; j < points.length; j++) {
int dist = points[j][0] * points[j][0] + points[j][1] * points[j][1];
if(dist < maxheap.peek()[0]) {
maxheap.poll();
maxheap.offer(new int[] {dist, j});
}
}
int[][] ans = new int[K][2];
for (int i = 0; i < K; i++) {
ans[i] = points[maxheap.poll()[1]];
}
return ans;
}