LeetCode(703)--数据流中的第 K 大元素

数据流中的第 K 大元素

设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。

请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。

示例:

输入: [“KthLargest”, “add”, “add”, “add”, “add”, “add”] [[3, [4, 5, 8,2]], [3], [5], [10], [9], [4]]
输出: [null, 4, 5, 5, 8, 8]

解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4 kthLargest.add(5); // return 5
kthLargest.add(10); // return 5 kthLargest.add(9); // return 8
kthLargest.add(4); // return 8

提示:
1 <= k <= 104 0 <= nums.length <= 104
-104 <= nums[i] <= 104
-104 <= val <= 104

最多调用 add 方法 104 次
题目数据保证,在查找第 k 大元素时,数组中至少有 k 个元素

题解(c++)

class KthLargest {
public:
    priority_queue<int,vector<int>,greater<int>> pq;
    int k;
    KthLargest(int k, vector<int>& nums) {
        this->k = k;
        for(auto num:nums)
        {
            pq.push(num);
        }
    }
    
    int add(int val) 
    {
        pq.push(val);
        while(pq.size() > k)
        {
            pq.pop();
        }
        return pq.top();
    }
};

总结

一开始我采用快速排序,结果显示超时,后来发现其它人都是用优先级队列做的
错误示例(Java):
我个人认为超时的原因是因为在add方法中我利用for循环将nums数组复制到temp数组中,耗费了比较多的时间

class KthLargest {

    private int k;
    private int[] nums;
    private static int[] leftArray;
    public KthLargest(int k, int[] nums)
    {
        this.k = k;
        this.nums = nums;
        leftArray = new int[nums.length / 2];
    }
    public void swap(int index1, int index2, int[] array)
    {
        int temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }
    public int pivotIndex(int begin, int end, int[] array)
    {
        swap(begin, begin + (int) (Math.random() * (end - begin)), array);
        //默认让第一个元素成为节点元素
        int pivot = array[begin];
        end--;
        //快速排序
        while(begin < end)
        {
            //从右向左扫描
            while(begin < end)
            {
                //右边元素大于轴点元素
                if(array[end] > pivot)
                {
                    //右边元素索引左移
                    end--;
                }
                //右边元素小于轴点元素
                else
                {
                    array[begin++] = array[end];
                    break;
                }
            }
            //从左向右扫描
            while(begin < end)
            {
                //左边元素小于轴点元素
                if(array[begin] < pivot)
                {
                    begin++;
                }
                //左边元素>轴点元素
                else
                {
                    array[end--] = array[begin];
                    break;
                }
            }
        }
        //将备份元素放入原来的位置
        array[begin] = pivot;
        return begin;
    }
    //快速排序
    public void sort(int begin, int end, int[] array)
    {
        //如果元素小于2,将中止快排
        if (end - begin < 2) 
        {
            return;
        }
        //确定轴点的位置
        int mid = pivotIndex(begin, end, array);
        sort(begin, mid, array);
        sort(mid + 1, end, array);
    }
    public int add(int val) 
    {
        int[] temp = new int[nums.length + 1];
        temp[0] = val;
        for(int index = 1;index < temp.length;index++)
        {
            temp[index] = nums[index - 1];
        }
        sort(0, temp.length,temp);
        this.nums = temp;
        return temp[temp.length - k];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值