IT公司100题-5-查找最小的k个元素

问题描述:

输入n 个整数,输出其中最小的k 个。

例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1。

问题分析:

时间复杂度O(nlogn)方法:

对n个整数升序排序,取数组前面k个数就是最小的k个数,时间复杂度为O(nlogn),空间复杂度为O(1)。

大顶堆,时间复杂度为O(nlogk):

我们可以采用大顶堆来保存最小的k个数,堆顶元素就是k个最小的数中最大的。新来一个元素的时候,与堆顶元素进行比较,如果比堆顶元素大,则直接丢弃。如果比堆顶元素小,则替换堆顶元素,并且进行大顶推的调整,需要O(logk)的时间。所以总的时间复杂度为O(nlogk),空间复杂度为O(k)。

TreeSet,时间复杂度为O(nlogk):

TreeSet容器的内部结构通常由红黑树来实现,所以查找、删除和插入操作都只需要O(logk)的时间。

代码实现:

package oschina.mianshi;
/**
 * @project: oschina
 * @filename: IT5.java
 * @version: 0.10
 * @author: JM Han
 * @date: 10:52 2015/11/2
 * @comment: 输入n 个整数,输出其中最小的k 个。
 * @comment: 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1。
 * @result:
 */

import java.util.*;

import static tool.util.*;

public class IT5 {
   public static final int NUM = 3;
   public static boolean sorted = false;

   public static void find3least(List<Integer> lst){
      TreeSet<Integer> innerlst = new TreeSet<Integer>();

      for (int i = 0; i < lst.size(); i++) {
         int x = lst.get(i);

         if(innerlst.size() < NUM) {
            innerlst.add(x);
         } else {
            int max = innerlst.last();
            if(x < max){
               innerlst.add(x);
               innerlst.remove(max);
            }
         }
      }

      if(innerlst.size() != 0){
         printGenericIterator(innerlst.iterator());
      }
   }

   public static void main(String[] args) {
      Integer[] testArray = new Integer[]{8, 7, 6, 5, 4, 3, 2, 1};
      List<Integer> lst = Arrays.asList(testArray);
      find3least(lst);
   }
}

代码输出:

1
2
3
时间: 2024-07-31 00:32:49

IT公司100题-5-查找最小的k个元素的相关文章

【编程题目】查找最小的 k 个元素

5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学过查找第k小的元素的O(n)算法 试着实现了一下: 注意new 初始化二维数组的方式 int (* a)[5] = new int[8][5]; /* 5.查找最小的 k 个元素(数组) 题目:输入 n 个整数,输出其中最小的 k 个. 例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,

5.查找最小的k个元素

http://zhedahht.blog.163.com/blog/static/2541117420072432136859/ http://blog.csdn.net/liangbopirates/article/details/9377105 http://blog.csdn.net/v_JULY_v/article/details/6370650 题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析: 这道题

查找最小的k个元素

题目: 输入n个整数,输出其中最小的k个数 例如: 1 2 3 4 5 6 7 8 这8个数字,则最小的4个数字为1,2,3,4, 第一种:直接对其先排序,再取头几个数 这样最快是nlogn(快排或者堆排) #include <iostream> using namespace std; void partsort(int a[], int l, int r); void QuickSort(int a[], int n) { partsort(a,0,n-1); } void partsor

IT公司100题-15-求二元查找树的镜像

问题描述: 输入一颗二元查找树,将该树转换为它的镜像树,即对每一个节点,互换左右子树. 例如输入: 6/    \4     12/ \   /   \2  5 8   16 输出: 6/     \12     4/   \   / \16  8 5  2 定义二元查找树的结点为: typedef struct BSTree { int data; BSTree* left; BSTree* right; } Node; 分析: 方法1:递归交换左右子树. // 15_1.cc #includ

IT公司100题-9-判断整数序列是不是二元查找树的后序遍历结果

问题描述: 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入4, 8, 6, 12, 16, 14, 10,由于这一整数序列是如下树的后序遍历结果: 10/     \6      14/  \    /   \4   8 12    16 因此返回true. 如果输入6, 5, 8, 5, 7 ,则返回false. 分析: 在后续遍历得到的序列中,最后一个元素为树的根结点.根节点元素将数组分为两部分,左边都小于根节点,右边都大

IT公司100题-13-求链表中倒数第k个结点

问题描述: 输入一个单向链表,输出该链表中倒数第k个结点.链表倒数第0个节点为NULL. struct list_node { int data; list_node* next; }; 分析: 方法1: 首先计算出链表中节点的个数n,然后倒数第k个节点,为正数n-k+1个节点. 需要遍历链表2次. 方法1代码实现: 1 // 13_1.cc 2 #include <iostream> 3 using namespace std; 4 5 struct list_node { 6 int da

IT公司100题-11-求二叉树中节点的最大距离

问题描述: 写程序,求一棵二叉树中相距最远的两个节点之间的距离. 10/     \6      14/   \   /   \4    8 12    16 分析: 二叉树中最远的两个节点,要么是根和一个叶子节点,要么是两个叶子节点. 代码实现: 1 // 11.cc 2 #include <iostream> 3 using namespace std; 4 5 typedef struct BSTreeNode { 6 int data; 7 BSTreeNode *left; 8 BS

IT公司100题-2

1 // 定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素. 2 // 要求函数min.push 以及pop 的时间复杂度都是O(1). 3 #include <iostream> 4 #include "../data/own/c2_list.h" 5 using namespace std; 6 7 template <typename object> 8 class miniStack{ 9 public: 10 bool isEmpty(

IT公司100题-17-第一个只出现一次的字符

问题描述: 在一个字符串中找到第一个只出现一次的字符.例如输入asdertrtdsaf,输出e. 分析: 最简单的方法是直接遍历,时间复杂度为O(n^2). 进一步思考: 字符串中的字符,只有256种可能性,使用字符的为下标,扫描一遍,存储各个字符在字符串中的出现.第二次扫描字符串,查看每个字符在字符串中的出现次数,如果为1,输出即可. 代码实现: // 17.cc #include #include #include using namespace std; char find_char(co