精华内容
下载资源
问答
  • leetcode最小的K个数

    2021-01-08 22:05:29
    思路一:最直观解法,应用排序算法将数组进行排序,返回前K个值 class Solution { public int[] getLeastNumbers(int[] arr, int k) { quickSort(arr, 0, arr.length-1); return Arrays.copyOf(arr,k);

    题目:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    思路一:最直观的解法,应用排序算法将数组进行排序,返回前K个值

    	class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            quickSort(arr, 0, arr.length-1);
            return Arrays.copyOf(arr,k);
    
        }
        public void quickSort(int[] arr, int left, int right){
        	if(left<right){
        		int q = partition(arr,left, right);
                quickSort(arr, left, q-1);
                quickSort(arr,q+1,right);
        	}
        }
        public int partition(int[] arr, int p, int r){
            int index = new Random().nextInt(r-p+1) + p;
            swap(arr,index,r);
            int x = arr[r];
            int i = p-1;
            for(int j = p;j<r;j++){
                if(arr[j]<=x){
                    i++;
                    swap(arr,i,j);
                }
            }
            swap(arr, i+1,r);
            return i+1;
        }
        public void swap(int[] A, int index1,int index2){
    	int temp = A[index1];
    	A[index1] = A[index2];
    	A[index2] = temp;
    }
    }
    
    展开全文
  • leetcode:最小的k个数

    2020-04-05 16:12:13
    对于TopM问题,当数据量较小时,可以直接对数据进行排序,然后选择前k个数值即可.而对于海量大数据,例如十亿,百亿数据量,如果要找出前10个数值,则使用排序算法是不现实.因为海量数据时可能无法一次性装进内存,更...

    题目来源:力扣

    题目描述:

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    审题:

    对于TopM问题,当数据量较小时,可以直接对数据进行排序,然后选择前k个数值即可.而对于海量大数据,例如十亿,百亿的数据量,如果要找出前10个数值,则使用排序算法是不现实的.因为海量的数据时可能无法一次性装进内存,更别提后续的排序过程了.

    TopM问题的经典处理方法是基于优先队列进行解决.如果要出道最小的k个数,我们可以向向最大优先队列依次插入数值,如果插入后队列中元素个数大于k,则弹出最大的元素.最终当插入完所有元素后,队列中剩余的k个元素即是最小的k个值. 对上述步骤可以略做调整,如果当前队列中元素个数等于:如果当前元素小于队列中最大元素,则插入该元素,然后删除最大元素,如果当前元素大于最大元素,则不插入该元素.

    优先队列通常使用堆结构实现,在该篇文章中,我们将使用数组构建最大堆,以实现最大优先队列.

    java算法:

    class Solution {
        //基于最大堆实现优先队列
        //为了选择最小的k个数,我们需要保存所有k+1个值
        //为了便于计算父节点下标与子节点下标,我们从下标1开始存储元素
        private int[] pq;
        int pqSize;
        
        //插入最底部,然后上浮
        private void insert(int x){
            pq[++pqSize] = x;
            int i = pqSize;
            while(i > 1){
                if(pq[i] > pq[i/2]){
                    int tmp = pq[i];
                    pq[i] = pq[i/2];
                    pq[i/2] = tmp;
                    i = i/2;
                }
                else
                    break;
            }
        }
    
    	//下沉
        private int delMax(){
            int max = pq[1];
            pq[1] = pq[pqSize--];
            if(pqSize > 0){
                int i = 1;
                while(i <= pqSize / 2){
                    //选择最大的子节点
                    if(pq[2*i] < pq[2*i+1]){
                        if(pq[i] < pq[2*i+1]){
                            int tmp = pq[i];
                            pq[i] = pq[2*i+1];
                            pq[2*i+1] = tmp;
                            i = 2*i+1;
                        }
                        else
                            break;
                    }
                    else if(pq[i] < pq[2*i]){
                        int tmp = pq[i];
                        pq[i] = pq[2*i];
                        pq[2*i] = tmp;
                        i = 2*i;
                    }
                    else
                        break;
                }
            }
            return max;
        }
    
        public int[] getLeastNumbers(int[] arr, int k) {
            pq = new int[k+2];
            for(int val: arr){
                if(pqSize < k){
                    insert(val);
                }
                else{
                    if(val < pq[1]){
                        insert(val);
                        delMax();
                    }
                }
            }
            int[] minK = new int[k];
            System.arraycopy(pq, 1, minK, 0, k);
            return minK;
        }
    }
    
    展开全文
  • 题目 题目链接 输入整数组 arr ,找出其中最小的 k 个。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。...根据数组的前k个数建立一个大顶堆,对,是大顶堆,然后数组...
    题目

    题目链接
    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    示例 1:
    输入:arr = [3,2,1], k = 2
    输出:[1,2] 或者 [2,1]

    示例 2:
    输入:arr = [0,1,2,1], k = 1
    输出:[0]

    题解

    根据数组的前k个数建立一个大顶堆,对,是大顶堆,然后数组后面一次更新这个顶堆。

    class Solution {
    public:
        void sink(int i, int k, vector<int> &res)
        {
            while ((2 * i + 1) <= (k - 1))
            {
                int child = 2 * i + 1;
                if ((child + 1) < k && res[child] < res[child + 1])
                {
                    child++;
                }
                if (res[i] >= res[child])
                    break;
                int tmp = res[i];
                res[i] = res[child];
                res[child] = tmp;
                i = child;
            }
        }
        vector<int> getLeastNumbers(vector<int>& arr, int k) {
            vector<int> res(k);
            if(!k)
                return res;
            for (int i = 0; i < k; i++)
            {
                res[i] = arr[i];
            }
            // 构建节点个数为k的大顶堆
            for (int i = k / 2 - 1; i >= 0; i--)
            {
                sink(i, k, res);
            }
            for (unsigned int i = k; i < arr.size(); i++)
            {
                 if (arr[i] < res[0])
                 {
                     res[0] = arr[i];
                     sink(0, k, res);
                 }
            }
            return res;
        }
    };
    
    展开全文
  • 首先想到的是先排序,再输出前k个,但是不管用什么排序,效果都不是很好。 由于只要找到最小的k个就好,这k个不需要从小到大排序,所有快排不需要将所有数字都排序。因为我们是要找下标为k的元素,第一次切分的...

    题目描述
    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    首先想到的是先排序,再输出前k个,但是不管用什么排序,效果都不是很好。
    由于只要找到最小的k个数就好,这k个数不需要从小到大排序,所有快排不需要将所有数字都排序。因为我们是要找下标为k的元素,第一次切分的时候需要遍历整个数组 (0 ~ n) 找到了下标是 j 的元素,假如 k 比 j 小的话,那么我们下次切分只要遍历数组 (0~k-1)的元素就行,反之如果 k 比 j 大的话,那下次切分只要遍历数组 (k+1~n) 的元素就行。

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if(k == 0 || arr.length == 0){
                return new int[0];
            }
            return sort(arr,0,arr.length-1,k-1);
        }
            public int partition(int[] arr,int startIndex,int endIndex){
                int pivot = arr[startIndex];
                int left = startIndex;
                int right = endIndex;
                while(left != right){
                    while(left<right && arr[right]>pivot){
                        right --;
                    }
                    while(left < right && arr[left] <= pivot){
                        left ++;
                    }
                    if(left < right){
                        int p = arr[left];
                        arr[left] = arr[right];
                        arr[right] = p;
                    }
                }
                arr[startIndex] = arr[left];
                arr[left] = pivot;
                return left;
    
            }
            public int[] sort(int[] arr,int startIndex,int endIndex,int k ){
                
                int pivotIndex = partition(arr,startIndex,endIndex);
                if(pivotIndex == k){
                   return Arrays.copyOf(arr, pivotIndex+1) ;
                
                }
                return pivotIndex > k? sort(arr, startIndex, pivotIndex - 1, k): sort(arr, pivotIndex + 1, endIndex, k);          
            }
        
    }
    

    计数排序:
    数据范围有限的情况下可以使用计数排序

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if(k==0 || arr.length == 0){
                return new int[0];
            }
            int counter[] = new int[10001];
            for(int a:arr){
                counter[a]++;
            }
            int res[] = new int[k];
            int index = 0;
            for(int i = 0;i<counter.length;i++){
                while(counter[i] > 0 && index <k){
                    res[index++] = i;
                    counter[i] --;
                }
        }
        return res;
    }
    }
    

    PriorityQueue:
    本题是求前 K 小,因此用一个容量为 K 的大根堆,每次 poll 出最大的数,那堆中保留的就是前 K 小。

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
           if(k == 0 || arr.length == 0){
               return new int[0];
           }
            
            Queue<Integer> q = new PriorityQueue<>((v1,v2)->v2-v1);
            for(int num:arr){
                if(q.size()<k){
                    q.offer(num);
                }else if(num<q.peek()){
                    q.poll();
                    q.offer(num);
                }
            }
            int[] res = new int[q.size()];
            int index = 0;
            for(int num:q){
                res[index++] = num;
            }
            return res;
        }    
    }
    
    展开全文
  • 解题思路:这道题可以有多种实现方法,下面介绍主要三种(1)堆排序(2)快排(3)全排序,然后取前k个最小值 (1)堆排序:先用数组前k个数构建一个大顶堆,然后依次遍历后size-k个,如果当前元素小于堆顶,则删除...
  • 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。 示例 1: 输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的 3 对数: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],...
  • 给定一非空整数组,返回其中出现频率 k元素。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 思路: 主要是记录一下这生成最小队列 PriorityQueue 通过最小堆队列实现取最大值 代码: ...
  • nc119 最小的k个: 给定一个数组,找出其中最小的K个。例如数组元素是4,5,1,6,2...第二种方法是可以适用于海量数据的方法,该方法基于二叉树或者堆来实现,首先把数组前k个数字构建一个最大堆,然后从第k+1个数字开
  • 使用最大堆,堆中保存前k个最小的元素对,且堆顶元素最大,当新的元素对大于堆顶元素时,则将新的元素入队,删除堆顶元素。 因为是元素堆,则需要自定义排序。 代码如下: class Solution { public: struct ...
  • 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。 示例 1: 输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的 3 对数: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2
  • 设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。 示例: 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4] 提示: 0 <= len(arr) <= 100000 0 <= k <= min(100000, len(arr)...
  • 今日打卡,排序+返回前k个数即可。主要就是考察排序。 本来尝试自己写了一个冒泡排序法,可是超出时间限制,于是直接用了内置排序。 冒泡排序: for(int i = 0 ; i < arr.size() - 1; i++) { for(int j = i ...
  • 查找和最小的K对数字 题目 给定两以升序排列的整形数组 nums1 和 nums2, 以及一整数 k。 定义一对值 (u,v),其中第一元素来自 nums1,第二元素来自 nums2。 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk...
  • 利用快排思想,找到能够区分 k 个 和 n-k 个元素轴值下标k,输出 k个元素即可。 代码分三部分写,分段、判断分段结果函数、初始函数。 注意地方是 partition 函数中判断是否要继续 --right 或者 ++left ...
  • 对数组元素进行快速排序,再顺序遍历前k个数即为所求 class Solution { public int[] getLastNumbers(int[] arr,int k) { if(arr.length==0 || k==0) { return new int[0]; } int[] nums = new int[k]; ...
  • 前k个数放入结果数组; 返回结果数组。 代码 class Solution { public: vector<int> getLeastNumbers(vector<int>& arr, int k) { sort(arr.begin(), arr.end()); vector
  • 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。 示例 1: 输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的 3 对数: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7...
  • 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。 示例 1: 输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的 3 对数: [1,2],[1,4],[1,6],[7,2],[7,4],
  • Leetcode题目对应位置: 面试题40:最小的k个数 思路 1:对原数组从小到大排序后取出 k 个即可。emmm 时间复杂度:O(nlogn),数组长度为 n,排序所需的额外时间复杂度 空间复杂度:O(logn),排序所需的额外空间...
  • 查找和最小的K对数字 1 题目描述(Leetcode题目链接)   给定两以升序排列的整形数组 nums1 和 nums2, 以及一整数 k。 定义一对值 (u,v),其中第一元素来自 nums1,第二元素来自 nums2。 找到和最小的 k ...
  • 算法-leetcode-最小K个数且排序输出 1 概述 1.1 题目出处 https://leetcode-cn.com/problems/top-k-frequent-words/ 1.2 题目描述 给一非空单词列表,返回 k 个出现次数最多单词。 返回答案应该按单词出现...
  • ——————————————————————...方法1:排序之后取 k class Solution { public int[] getLeastNumbers(int[] arr, int k) { if(k == 0 || arr.length == 0) return new int[0]; Arrays.s...
  • 对原数组从小到大排序后取出 k 个数即可。 复杂度分析: 时间复杂度:O(nlogn),其中 n 是数组 arr 长度。算法时间复杂度即排序时间复杂度。 空间复杂度:O(logn),排序所需额外空间复杂度为 O(logn)。 ...
  • * 首先将前k个元素生成一个大根堆,然后对后面元素进行处理,将堆顶和每个元素进行比较,若比堆顶小,则将其替换给堆顶。然后进行向上进行整理。 * 这样,整理完了之后这个大根堆就存放着前k小个元素了。 * ...
  • 题目 最大堆 priority_queue vector 答题 参考来源:...对原数组从小到大排序后取出 k个数即可。 class Solution { public: vector<int> getLeastNumbers(vector<int>&
  • 解题思路: 使用最大堆来存储k个和最小的数组组合,然后每进来一个数组组合,只需要和最大堆的堆顶进行...在循环中的一个trick在于,限制为访问nums1和nums2的前k个数即可。所以那一部分的时间复杂度为O(k*k)。 ...
  • 题目描述: 思路:两种常用方法:1.先存储k个,当后续数字大于其中...如果正好相等,则复制到当前前k个数并返回。 采用最大堆 class Solution { public int[] getLeastNumbers(int[] arr, int k) { if (k==0)re
  • 描述:设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4] 解题思路: 这题因为不要求排序,所以思路很多,我自己想的思路有下面的两...
  • 找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。 示例 1: 输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的 3 对数: [1,2],[1,4],[1,6],[7,2],[7,4],
  • (1)解法1直接调用了Arrays.sort()方法,使用了快排对其排序,然后取前k个元素。没什么好说。 (2) 解法1-API class Solution { public int[] getLeastNumbers(int[] arr, int k) { if(arr.length == 0 || ...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 151
精华内容 60
关键字:

leetcode前k个最小的数