滑动窗口最值

算法练习

滑动窗口最值问题:

给定一个数组 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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值