【Leetcode 二分】 滑动窗口中位数(480)

题目

中位数是有序序列最中间的那个数。如果序列的大小是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。

例如:
[2,3,4],中位数是 3

[2,3],中位数是 (2 + 3) / 2 = 2.5

给出一个数组 nums,有一个大小为 k 的窗口从最左端滑动到最右端。窗口中有 k 个数,每次窗口移动 1 位。你的任务是找出每次窗口移动后得到的新窗口中元素的中位数,并输出由它们组成的数组。

例如:

给出?nums = [1,3,-1,-3,5,3,6,7],以及?k = 3

窗口位置                      中位数
---------------               -----
[1  3  -1] -3  5  3  6  7       1
 1 [3  -1  -3] 5  3  6  7      -1
 1  3 [-1  -3  5] 3  6  7      -1
 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]      6

因此,返回该滑动窗口的中位数数组 [1,-1,-1,3,5,6]。

提示:
假设k是合法的,即:k 始终小于输入的非空数组的元素个数.

解答

题目和滑动窗口最大值异常相似

前几天写这道题时一直超时,用的对每个窗口都排序再找中位数,中间每次快排N·log(N) 。。

AC:cur表示当前窗口,每次向右滑动时加入一个新元素,并删除左边元素,再计算中位数。窗口滑动过程中不必每次都重新排序,维护cur有序,新元素用bisect二分插入,删除也用二分查找删。二分复杂度log(N),加上外层遍历,整体复杂度Time: N·log(N),Space: O(N)

这种方法要先排序第一个窗口,记录已排序的cur

2,窗口求中位数用BFPRT应该也能做出来,时间复杂度O(N),窗口数为偶数时,应该要两次BFPRT,复杂度O(2N),总复杂度O(N·K),待更ing...

代码如下:

import bisect

class Solution:
    def medianSlidingWindow(self, nums, k):
        length = len(nums)
        ans = []

        cur = nums[:k]
        left = nums[0]
        cur.sort()
        ans.append(self.getmedian(cur))

        for i in range(1, length - k + 1):
            del_index = bisect.bisect(cur, left) - 1  # 二分找删除元素的位置
            cur.pop(del_index)

            left = nums[i]  # 记录左边元素
            bisect.insort(cur, nums[i + k - 1])  # 二分插入
            ans.append(self.getmedian(cur))
            # print(ans)
        return ans

    def getmedian(self, nums):
        if len(nums) % 2 == 0:
            return (nums[len(nums) // 2] + nums[len(nums) // 2 - 1]) / 2
        return nums[len(nums) // 2]

s = Solution()
print(s.medianSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3))

原文地址:https://www.cnblogs.com/ldy-miss/p/12074326.html

时间: 2024-07-30 16:11:01

【Leetcode 二分】 滑动窗口中位数(480)的相关文章

Leetcode 480.滑动窗口中位数

滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) / 2 = 2.5 给出一个数组 nums,有一个大小为 k 的窗口从最左端滑动到最右端.窗口中有 k 个数,每次窗口移动 1 位.你的任务是找出每次窗口移动后得到的新窗口中元素的中位数,并输出由它们组成的数组. 例如: 给出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3

[Swift]LeetCode480. 滑动窗口中位数 | Sliding Window Median

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value. Examples: [2,3,4] , the median is 3 [2,3], the median is (2 + 3) / 2 = 2.5 Given an a

leetcode 239. 滑动窗口最大值(单调队列)

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 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

leetcode ---双指针+滑动窗口

一:Minimum Size Subarray Sum 题目: Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead. For example, given the array [2,3,1,2,4,3] and s = 7, th

【leetcode 239. 滑动窗口最大值】解题报告

思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> res; if (nums.size()==0) return res; int i=0; deque<int> dq; for (i=0;i<nums.size();++i) { while(!dq.empty()&

Leetcode 239. 滑动窗口最大值

class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> ret; if(nums.size()==0) return ret; deque<int> q; for(int i=0; i<nums.size(); ++i) { if(q.empty() || nums[q.back()] > nums[i] )

堆的相关题目—滑动窗口

1.数据流滑动窗口平均值 描述 给出一串整数流和窗口大小,计算滑动窗口中所有整数的平均值. 样例 样例1 : MovingAverage m = new MovingAverage(3); m.next(1) = 1 // 返回 1.00000 m.next(10) = (1 + 10) / 2 // 返回 5.50000 m.next(3) = (1 + 10 + 3) / 3 // 返回 4.66667 m.next(5) = (10 + 3 + 5) / 3 // 返回 6.00000来源

滑动窗口的中位数

2017年8月7日 19:46:26 难度:困难 描述:给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数.(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字.) 样例: 对于数组 [1,2,7,8,5], 滑动大小 k = 3 的窗口时,返回 [2,7,7] 最初,窗口的数组是这样的: [ | 1,2,7 | ,8,5] , 返回中位数 2; 接着,窗口继续向前滑动一次. [1, | 2,7,8 | ,5],

算法-滑动窗口的中位数(堆)

今天在网上刷了一道关于堆的题,感觉有所收获.因为在这里之前,之前从来没有接触过关于堆的题目. 题意: 给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中 滑动这个窗口,找到数组中每个窗口内的中位数.(如果数组个数是偶数,则在 该窗口排序数字后,返回第 N/2 个数字.) 样例: 对于数组 [1,2,7,8,5], 滑动大小 k = 3 的窗口时,返回 [2,7,7] 最初,窗口的数组是这样的: [ | 1,2,7 | ,8,5] , 返回中位数 2; 接着,窗口继续向