LeetCode Sliding Window Maximum

Description:

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.


Solution1:

We can use a PriorityQueue to maintain all the current data in sliding window. So the priority queue has a size of k. Everytime it moves to the next step, just remove the first of the list then add a new one. And remember to write a new comparator with a bigger number has higher priority, so the peek of priority queue can be the largest of current window.

<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*;

public class Solution {
	public int[] maxSlidingWindow(int[] nums, int k) {
		int length = nums.length;
		if (length == 0 || k == 0)
			return new int[0];
		if (k == 1)
			return nums;

		int ans[] = new int[length - k + 1];

		PriorityQueue<Integer> queue = new PriorityQueue<Integer>(
				new neoIntComparator());

		for (int i = 0; i < k - 1; i++) 
			queue.add(nums[i]);

		for (int i = k - 1; i < length; i++) {
			if (i >= k) {
				queue.remove(nums[i - k]);
			}
			queue.add(nums[i]);
			ans[i - k + 1] = queue.peek();
		}

		return ans;
	}

	public static void main(String[] args) {
		int a[] = new int[] { 1, -1, -1 };
		Solution s = new Solution();
		int[] ans = s.maxSlidingWindow(a, 2);
		for (int i = 0; i < ans.length; i++)
			System.out.print(ans[i] + "  ");
		System.out.println();
	}
}

class neoIntComparator implements Comparator<Integer> {

	@Override
	public int compare(Integer arg0, Integer arg1) {
		return arg1 - arg0;
	}

}</span></span>


Solution2:

We may still want to figure out a much less time-consuming method, because a a priority queue is still a little bit complex. So here comes another  solution.

1. We can store all the data into a stack-like data structure, with the attribute that lower/earlier one has a bigger value. So every time we face with a new number, we need to maintain this attribute: poll the stack until the uppermost one is bigger or equal to this number, then push this number to the top of this stack.

2. Check if the lowest one in the stack is out of the range of the window. This requires we make an if-statement.

3. The current lowest one in the stack is what we want in the current window which ends in nums[i].


Tip: for this sentence --- "the uppermost one is bigger or equal to this number", why equal is also OK here? Because in order to get rid of the case that the lowest number is out of the window range, we simply use one if-statement to check. So in case there are multiple numbers with different positions but same value, and we only keep the earliest one, if it is out of range and we may eliminate it which is absolutely not we want. So we may as well keep all the numbers with same value but different positions.


java

<span style="font-size:18px;">import java.util.*;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

public class Solution {
	public int[] maxSlidingWindow(int[] nums, int k) {
		int length = nums.length;
		if (length == 0 || k == 0)
			return new int[0];
		if (k == 1)
			return nums;

		int ans[] = new int[length - k + 1];

		LinkedList<Integer> dualLinkedList = new LinkedList<Integer>();

		for (int i = 0; i < k - 1; i++)
			keepTheDualLinkedList(dualLinkedList, nums[i]);

		// System.out.println("original one");
		// print(dualLinkedList);

		for (int i = k - 1; i < length; i++) {
			keepTheDualLinkedList(dualLinkedList, nums[i]);
			if (i >= k && dualLinkedList.getLast() == nums[i - k])
				dualLinkedList.removeLast();
			ans[i - k + 1] = dualLinkedList.getLast();
			// System.out.println(i + "th step");
			// print(dualLinkedList);
		}

		return ans;
	}

	void print(LinkedList<Integer> list) {
		for (Iterator<Integer> ite = list.iterator(); ite.hasNext();) {
			int temp = ite.next();
			System.out.printf("%3d", temp);
		}
		System.out.println();
		System.out.println();
	}

	void keepTheDualLinkedList(LinkedList<Integer> dualList, int num) {
		int temp;
		while (!dualList.isEmpty()) {
			temp = dualList.peek();
			if (temp >= num)
				break;
			dualList.poll();
		}
		dualList.addFirst(num);
	}

	public static void main(String[] args) {
		int a[] = new int[] { 7, 2, 4 };
		Solution s = new Solution();
		int[] ans = s.maxSlidingWindow(a, 2);
		for (int i = 0; i < ans.length; i++)
			System.out.print(ans[i] + "  ");
		System.out.println();
	}
}
</span>

python

<span style="font-size:18px;">class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        length = len(nums)
        if (length==0 or k==0):
            return []
        if (k==1):
            return nums

        dualLinkedList = []
        ans = []
        
        for i in range(0,k-1):
            self.keepInStack(dualLinkedList, nums[i])

        for i in range(k-1, length):
            self.keepInStack(dualLinkedList, nums[i])
            if (i>=k and dualLinkedList[0]==nums[i-k]):
                dualLinkedList.remove(nums[i-k])
            ans.append(dualLinkedList[0])

        return ans


    def keepInStack(self, linkedList, num):
        while (len(linkedList)>0):
            topNum = linkedList.pop()
            if (topNum>=num):
                linkedList.append(topNum)
                break;

        linkedList.append(num)
</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值