算法练习
滑动窗口最值问题:
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
解题参考: https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/solution/mian-shi-ti-59-i-hua-dong-chuang-kou-de-zui-da-1-6/
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0 || k == 0) {
return new int[0];
}
Deque<Integer> deque = new LinkedList<>();
int[] res = new int[nums.length - k + 1];
int i = 1 - k;
for(int j = 0; j < nums.length; j++) {
if(i > 0 && deque.peekFirst() == nums[i - 1]) {
deque.removeFirst(); // 删除 deque 中对应的 nums[i-1]
}
while (!deque.isEmpty() && deque.peekLast() < nums[j]) {
deque.removeLast(); // 保持 deque 递减
}
deque.addLast(nums[j]);
if(i >= 0) {
res[i] = deque.peekFirst(); // 记录窗口最大值
}
i++;
}
return res;
}
核心思想使用单调队列将获取窗口中最值的时间复杂度从O(n) 降低到 O(1)
K个一组反转链表
//给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
//
// k 是一个正整数,它的值小于或等于链表的长度。
//
// 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
//
//
//
// 示例:
//
// 给你这个链表:1->2->3->4->5
//
// 当 k = 2 时,应当返回: 2->1->4->3->5
//
// 当 k = 3 时,应当返回: 3->2->1->4->5
//
//
//
// 说明:
//
//
// 你的算法只能使用常数的额外空间。
// 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
//
// Related Topics 链表
// 👍 880 👎 0
//leetcode submit region begin(Prohibit modification and deletion)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
// 示例:
//
// 给你这个链表:1->2->3->4->5
//
// 当 k = 2 时,应当返回: 2->1->4->3->5
//
// 当 k = 3 时,应当返回: 3->2->1->4->5
public ListNode reverseKGroup(ListNode head, int k) {
ListNode sentinal = new ListNode(-1);
sentinal.next = head;
ListNode before = sentinal;
ListNode end = sentinal;
while (end.next != null) {
for (int i = 0; i < k && end != null; i++) {
end = end.next;
}
if (end == null) {
break;
}
ListNode start = before.next;
ListNode after = end.next;
end.next = null;
before.next = reverse(start);
start.next = after;
before = start;
end = start;
}
return sentinal.next;
}
public ListNode reverse(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
//leetcode submit region end(Prohibit modification and deletion)