美文网首页程序员
利口 480 滑动窗口中位数

利口 480 滑动窗口中位数

作者: zhaojinhui | 来源:发表于2020-11-19 02:55 被阅读0次

    题意:给定一个数组和一个滑动窗口,返回每一个滑动窗口的中位数

    思路:遍历数组

    1. 维护一个最小的treeset,和一个最大的treeset,记录当前节点的index
    2. 每次根据奇偶返回当前的中位数

    思想:treeset

    复杂度:时间O(nlgk),空间O(k)

    class Solution {
        public double[] medianSlidingWindow(int[] nums, int k) {
            TreeSet<Integer> set1 = new TreeSet(new Comparator<Integer>(){
               public int compare(Integer n1, Integer n2) {
                   if(nums[n2] == nums[n1])
                       return n1 - n2;
                   return Integer.compare(nums[n1], nums[n2]);
               } 
            });
            TreeSet<Integer> set2 = new TreeSet(new Comparator<Integer>(){
               public int compare(Integer n1, Integer n2) {
                   if(nums[n2] == nums[n1])
                       return n1 - n2;
                   return Integer.compare(nums[n2], nums[n1]);
               } 
            });
            
            double[] res = new double[nums.length - k + 1];
            
            for(int i=0;i<nums.length;i++) {
                if(i>=k) {
                    res[i - k] = get(set1, set2, nums);
                    remove(i-k, set1, set2, nums);
                }
                add(i, set1, set2, nums);
            }
            res[nums.length - k] = get(set1, set2, nums);
            return res;
        }
        
        void add(int n1, TreeSet<Integer> set1, TreeSet<Integer> set2, int[] nums) {
            if(set1.isEmpty() || nums[n1] >= nums[set1.first()]) {
                set1.add(n1);
            } else {
                set2.add(n1);
            }
            if(set1.size() < set2.size())
                set1.add(set2.pollFirst());
            
            if(set1.size() - set2.size() > 1)
                set2.add(set1.pollFirst());
        }
            
        void remove(int n1, TreeSet<Integer> set1, TreeSet<Integer> set2, int[] nums) {
            if(set1.contains(n1)) {
                set1.remove(n1);
            } else {
                set2.remove(n1);
            }
            if(set1.size() < set2.size())
                set1.add(set2.pollFirst());
            
            if(set1.size() - set2.size() > 1)
                set2.add(set1.pollFirst());
        }
        
        double get(TreeSet<Integer> set1, TreeSet<Integer> set2, int[] nums) {
            if(set1.size() == set2.size()) {
                return ((double)nums[set1.first()] + (double)nums[set2.first()]) / 2;
            } else {
                return (double)nums[set1.first()];
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:利口 480 滑动窗口中位数

        本文链接:https://www.haomeiwen.com/subject/rwtqiktx.html