精华内容
下载资源
问答
  • 数组中找最小的k

    千次阅读 2018-04-20 16:30:39
    那么这篇博文我就来和大家深入探讨一下怎样从数组中找最小的k数吧,这是阿里一面的时候问我的一道算法题,后来又翻了一下书发现是剑指offer上的原题,但当时候因为电面答的也不是很好,有点懊悔呃呃~刚听到...

           这两天因为一直有面试,所以没有更新博客,不过每天还是会保持做几道算法题,但时间问题没能和大家交流,今天我会多分享一些知识希望对大家能有所帮助。那么在这篇博文中我就来和大家深入探讨一下怎样从数组中找出最小的k个数吧,这是阿里一面的时候问我的一道算法题,后来又翻了一下书发现是剑指offer上的原题,但当时候因为电面答的也不是很好,有点懊悔呃呃~刚听到这道题的时候,想了想直接排序然后查找就好了不是么,然后无脑的说了被问时间复杂度是多少,我回答了O(nlogn),面试官问时间复杂度还能再小么,后来想想要这么简单面试官又怎么会问呀,苦逼了几分钟后胡乱讲了莫名其妙的一些解法都被否认了,然后转向了下一个提问......因此结束了面试,赶快去查阅了资料才明白了其中的奥秘,唉,进步的空间还是忒大了~

           首先,我们可以基于快速排序的算法来调整,当然这种排序会修改我们输入的数组,寻找最小的k个数,那么如果k左边的数都小于k位置的数,k右边的数都大于k位置的数,则找到k的位置即可,具体实现如下:

    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
            ArrayList<Integer> res = new ArrayList<Integer>();
            if (input==null||input.length==0||input.length<k||k<=0) {
                return res;
            }
            int start  = 0;
            int end = input.length-1;
            int index = partition(input, start, end);
            while (index != k - 1) {
                if (index > k - 1) {
                    end = index-1;
                    index = partition(input, start, end);
                } else {
                    start = index+1;
                    index = partition(input, start, end);
                }
            }
            for (int i = 0; i < k; i++) {
                res.add(input[i]);
            }
            return res;
        }
       static int partition(int input[], int start, int end) {
            int tmp = input[start];
            while (start < end) {
                while (start < end && input[end] >= tmp) {
                    end--;
                }
                input[start] = input[end];
                while (start < end && tmp >= input[start]) {
                    start++;
                }
                input[end] = input[start];
            }
            input[start] = tmp;
            return start;
        }

           也许很多人会问,这种算法的时间复杂度是多少呢,答案是O(n),为什么~

           我们都知道快排是向下递归的,那么在平均或者说是期望情况下它找到的永远是中间位置,这就有点类似折半查找了,所以第一次它会对n个数进行划分,第二次循环它只会进入一边,然后对n/2个数进行划分,以此类推,总共需要对n+n/2+n/4+...+2+1=n(1+1/2+1/4+...)+2+1个数进行操作,1+1/2+1/4+...<2,因此该表达式小于2n,所以它的期望时间复杂度为O(n)。

           前面我也说了,这种方法会改变原数组中元素的位置,如果面试官不允许改变数组元素的位置呢,那么我们就只能使用另外一种算法了,这种算法可以处理大量数据,此时大家应该会想到这种算法和堆有关了吧,我们可以先创建一个大小为k的数据容器来存储最小的k个数字,接下来每次从输入的n个整数中读入一个数,如果容器中已有的数字少于k个,则直接把这次读入的整数放入容器之中,如果容器中已有k个数字了,也就是容器已满,此时我们不能再插入新的数字而只能替换已有的数字,找出这已有的k个数中的最大值,然后拿这次待插入的整数和最大值进行比较,小则替换当前最大值,大则不可能是最小的k个整数之一,于是我们可以抛弃这个整数。

           因此,当容器满了之后,我们需要进行3步操作:一是在k个整数中找到最大数;二是有可能从这个容器中删除最大值;三是可能插入一个新的数字。如果用一颗二叉树来实现这个数据容器,那么我们能在O(logk)时间内实现这三步操作,因此,对于n个输入数字而言,总的时间效率就是O(nlogk)。

           我们可以选择用不同的二叉树来实现这个数据容器。由于每次都需要找到k个整数中的最大数字,我们很容易想到最大堆,在最大堆中,根节点的值总是大于它的子树中任意结点的值。于是我们每次可以在O(1)时间内的到已有的k个数字的最大值,但需要O(logk)时间完成删除即插入操作。

           下面是代码实现:

    static public ArrayList<Integer> GetLeastNumbers_Solution1(int[] input, int k) {
            ArrayList<Integer> res = new ArrayList<Integer>();
            if (input==null||input.length==0||input.length<k) {
                return res;
            }
            int []maxHeap = new int[k];
            for (int i = 0; i < maxHeap.length; i++) {
                maxHeap[i] = input[i];
            }
            for (int i = (maxHeap.length-1)/2; i >=0 ; i--) {
                adjustHeap(maxHeap, i);
            }
            for (int i = k; i <input.length ; i++) {
                if (maxHeap[0]>input[i]) {
                    maxHeap[0] = input[i];
                    adjustHeap(maxHeap, 0);
                }
            }
            for (int i = 0; i < maxHeap.length; i++) {
                res.add(maxHeap[i]);
            }
            return res;
        }
        static void adjustHeap(int maxHeap[],int i){
            int index = i;
            int lchild=2*i+1;       //i的左孩子节点序号 
            int rchild=2*i+2;     //i的右孩子节点序号 
            if(index<=(maxHeap.length-1)/2) {
                //寻找子节点中最大的节点
                if (lchild<maxHeap.length&&maxHeap[index]<maxHeap[lchild]) {
                    index = lchild;
                }
                if (rchild<maxHeap.length&&maxHeap[index]<maxHeap[rchild]) {
                    index = rchild;
                }
                if (i!=index) {
                    //将节点与最大的子节点交换
                    int tmp = maxHeap[index];
                    maxHeap[index] = maxHeap[i];
                    maxHeap[i] = tmp;
                    //交换后,子树可能不满足最大推,递归调整。
                    adjustHeap(maxHeap, index);
                }
            }

           那么在这里我同样解释一下时间复杂度吧,从主函数中循环可以看出循环次数为n-k,当n特别大且k特别小时,n-k近似为n,然后在每次循环中进行上述时间复杂度为O(logk)的三个步骤,所以总的时间复杂度为O(nlogk)。

           至此相信大家已经理解这个问题了哈,在面试时,如果遇到的问题有多种解法,每种解法都有自己的优缺点,那么我们首先应该向面试官问清楚题目的要求,输入的特点,从而选择最合适的解法。

    展开全文
  • 当左子数组和右子数组的长度为1时,最大最小元素均为本身,当左子数组和右子数组的长度为2时,直接进行次比较分别得出两数组最大最小元素,然后将子问题合并,数组中寻找到更大的元素作为大元素,更...

    Java实现利用分治法找到数组中的最大最小元素

    基本思路:

    不断的寻找数组的左子数组和右子数组,当左子数组和右子数组的长度为1时,最大最小元素均为本身,当左子数组和右子数组的长度为2时,直接进行一次比较分别得出两个子数组的最大最小元素,然后将子问题合并,在两个子数组中寻找到更大的元素作为大元素,更小的元素作为小元素,递归完成后,即可获得正确结果。

    Java代码如下:

    
    public class FindMaxAndMin {
        public static void main(String[] args) {
            int[] ans = {6, 8, 4, 4, 6, 36, 673, 13, 6, 7, 3, 4, 6, 8, 3, 7, 5, 7, 9, 5};
            int[] res = find(ans, 0, ans.length - 1);
            System.out.println("最小元素为"+res[0]);
            System.out.println("最大元素为"+res[1]);
        }
    
        private static int[] find(int[] ans, int left, int right) {
            int mid = (left + right) / 2;
            //当left == right 时,最大最小元素均为ans[left]
            if (left == right) {
                int[] res = new int[2];
                res[0] = ans[left];
                res[1] = ans[right];
                return res;
            }
            //当left + 1 == right时,比较得出最大最小元素
            if (right - left == 1) {
                int[] res = new int[2];
                res[0] = Math.min(ans[left], ans[right]);
                res[1] = Math.max(ans[left], ans[right]);
                return res;
            }
            //分别找出左子数组和右子数组的最大最小元素
            int[] Lres = find(ans, left, mid);
            int[] Rres = find(ans, mid + 1, right);
            //将子问题合并,找出两个子数组中的最小元素和最大元素
            int[] res = merge(ans, Lres, Rres, left, mid, right);
            return res;
        }
    
        private static int[] merge(int[] ans, int[] Lres, int[] Rres, int mid, int left, int right) {
            int[] res = new int[2];
            res[0] = Math.min(Lres[0], Rres[0]);
            res[1] = Math.max(Lres[1], Rres[1]);
            return res;
        }
    }
    
    

    运行结果如下:

    在这里插入图片描述

    展开全文
  • Python查找列表数组N个最大最小元素

    千次阅读 2019-04-22 23:36:19
    数组中最大和最小的三个元素: import heapq nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] print(heapq.nlargest(3, nums)) print(heapq.nsmallest(3, ...第一个参数3是说最大最小的三个值。 所...

    找出数组中最大和最小的三个元素:

    import heapq
    nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
    print(heapq.nlargest(3, nums))
    print(heapq.nsmallest(3, nums))
    

    输出:

    [42, 37, 23]
    [-4, 1, 2]

    第一个参数3是说找出最大最小的三个值。

     

    所要查找的数组列表元素可以是更复杂的Python字典:

    import heapq
    
    portfolio = [
        {'name': 'IBM', 'shares': 100, 'price': 91.1},
        {'name': 'AAPL', 'shares': 50, 'price': 543.22},
        {'name': 'FB', 'shares': 200, 'price': 21.09},
        {'name': 'HPQ', 'shares': 35, 'price': 31.75},
        {'name': 'YHOO', 'shares': 45, 'price': 16.35},
        {'name': 'ACME', 'shares': 75, 'price': 115.65}
    ]
    
    cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
    expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
    
    print(cheap)
    print(expensive)

    以'price'作为key,查找最大和最小的三个元素。

    输出:

    [{'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}]
    [{'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'ACME', 'shares': 75, 'price': 115.65}, {'name': 'IBM', 'shares': 100, 'price': 91.1}]
    
    

     

     

    展开全文
  • 一维数组中找出值最小的元素,并将其与第一个元素的值对调 思路: 每次比较过程,若一个数比最小的数还要小。那它就是最小的数 // 找最小,并和第一个元素的值互换 #include &amp;lt;stdio.h&amp;gt; #...

    因本人才疏学浅,见识浅薄,有不当之处望指正,谢谢!
    在一维数组中找出值最小的元素,并将其与第一个元素的值对调
    思路:
    每次比较过程中,若一个数比最小的数还要小。那它就是最小的数

    // 找最小,并和第一个元素的值互换
    #include <stdio.h>
    #define N 10
    int main(void)
    {
    	int a[N], i, t, min = 0;
    	
    	printf("input %d number:\n",N);
    	for (i = 1; i < N; i++)// 从第一项开始通过for循环求出最小元素的数组下标
    	{
    		scanf("%d", &a[i]);
    		if (a[min] > a[i])
    			min = i;
    	}
    	printf("min number:a[%d] = %d\n",min,a[min]);
    	{t = a[min]; a[min] = a[0]; a[0] = t;}//和第一个元素的值互换
    	for(i = 0; i < N; i++)
    		printf("%4d", a[i]);
    	printf("\n");
    	
    	return 0;
    }
    

    附图:
    在这里插入图片描述

    展开全文
  • /** ... * @Description 给定一个数组,输出这个数组中最大值和最小值 */ public class BigAndSmall4 { public static void main(String[] args) { int a[] = {6,34,23,41,87,3,7}; minMa...
  • 数组中有10个数,分别为0、10、20、…、90从键盘输入一个1-100之间的整数,从数组中找一个与该数差值最小的元素并且输出。若两个元素同时满足要求,输出其中之一即可。 #include&amp;lt;iostream&amp;gt; #...
  • c语言查找数组中最小的元素Here is the C program to find the largest and smallest ... 这是C语言程序,用于在一维(1-D)数组中查找最大最小的元素。 #include<stdio.h> int main() { int a[50],i,n,lar...
  • 1.认为数组的第一个就是最大或则最小。 2.依次遍历数组进行和第一个值进行比较。 3.大于最大值就是最大,小于最小就是最小。 4.所有比较结束后,最大值和最小值就拿到了。
  • 获取numpy数组中最大最小的几

    千次阅读 2020-07-09 14:58:07
    #!/usr/local/bin/python # -*- coding: UTF-8 -*... 获取numpy数值中最大最小的几数 :param np_arr: numpy数组 :param several: 最大最小的个数(负数代表求最大,正数代表求最小) :return: several_min_or
  • ①int maxmin(int arr[ ],int n)//定义了一个整形数组数组的名称叫arr // { int i,min; ② max=min=arr[0]; for(i=1;i<n;i++) { ③ if(arr[i]>max) max=arr[i]; if(arr[i]<min) m
  • 给定一个长度为n的无序数组出这个数组中第k个最小或者最大的元素,其中0 最简单的方法就是先对数组进行排序,然后返回第k个元素。代码如下: // Simple C++ program to find k'th smallest element #include...
  • 数组-----数组中最大最小的数

    千次阅读 2018-07-27 11:20:25
    取双元素法,维持两变量max 和min ,min 标记最小,max标记最大,每次比较相邻两数,较大者与max比较,较小者与min比较,最大最小值,比较次数为1.5N次  ...
  • 给定一个数组a,含有n,寻找这个数组中最大元素和最小元素,刚看到这个题目的时候,觉得这个问题没什么思考性,因为这个问题很简单,就是设定一个初始最大值和初始最小值,然后循环遍历数组,进行比较,至多会2(n...
  • ,调用函数Find,该函数通过趟循环,找到数组中的第1个最大元素及对应下标,第1个最小元素及对应下标。 说明:(1)查找函数的原型为:void Find(int *a,int n,int *max,int *maxPos,int *min,int *minPos);...
  • 编写组求数组中最大最小元素的函数。该组函数的原型为 int imax(int array[], int count); // 求整型数组的最大元素 int imin(int array[], int count); // 求整型数组的最小元素 其中参数count为数组的元素...
  • 数组中找最大的和最小的数

    千次阅读 2014-06-08 10:05:41
    数组中找最大的和最小的数 给定整形数组a,要求从中最大的数和最小的数,并计算时间复杂度。 实现1: 遍历数组,每次取数组中一元素, 分别与当前最大值和最小值进行比较,时间复杂度O(2n) ...
  • 一个数组中没有出现的最小正数

    千次阅读 2017-12-31 14:08:59
    一个数组中没有出现的最小正数,要求时间复杂度O(n),空间复杂度O(1)。 给出方法思路,算法代码。
  • 给定一个数组获取数组中最大

    千次阅读 2013-03-12 23:19:22
    /** 给定一个数组{3,5,6,457,23,5,} ...让数组中的每一个元素都和这个变量的值进行比较. 如果大于了变量的值,就用该变量记录较大的值. 3.当所有的元素都比较完成,那么该变量存储的就是数组中最大
  • //给定一个整型数组, 找到其中的最大元素 (找最小元素同理) public class Test4_arryMax { public static void main(String[] args){ int[] arr={1,2,3,4,5,6}; System.out.print(max(arr)); } public static int ...
  • #include <stdio.h> #include <stdlib.h> void AdjustArray(int a[], int n){ int i; int tmp = a[0]; int tmp1 = a[n - 1]; int pos, pos1; for (i = 1; i < n; ++i){ ......
  • #include &lt;iostream&gt;#include &lt;stdlib.h&gt;using namespace std;namespace A{ int getMaxOrMin(int *arr,int num,bool isMax) { int temp=arr[0]; for(int i=1;...i++) ...
  • BAT面试题——找一个无序实数数组中最大差值 (基于桶排序思想的方法)
  • C#获取一个数组中最大值、最小值、平均值

    万次阅读 多人点赞 2018-09-19 09:49:18
    C#获取一个数组中最大值、最小值、平均值 1.给出一个数组 int[] array = new int[] { 1,2,4,3,0,-1,34,545,2,34}; 2.数组Array自带方法 本身是直接可以调用Min(),Max(),Average()方法来求出 最小值、最大值...
  • 一个排序数组中绝对值最小的数

    千次阅读 2016-10-11 09:29:51
    题意描述:给定一个已排好序的数组,求数组中绝对值最小的元素 解题思路一:直接遍历,时间复杂度为O(n),求得数组中绝对值最小的元素 int getMinAbs(int[] num){ //当数组只有一个元素的情况直接返回 if(num....
  • public int[] maxcost() { int [] maxnum=new int[2]; //长度2的数组保存最大和次大数的索引 int maxcost1,maxcost2;... if(group_cost[0]>=group_cost[1]) //先将数组前两数比较大小后赋
  • C语言 查找数组中最大最小元素

    万次阅读 2017-10-11 17:56:18
    查找数组中最大最小的元素。 */ #include #include #include void main() {  int array[10];//  int Y=100;  int X=0;//随机数范围:[X,Y]  int i;  int maxIndex=0;//最大元素的下标  int
  • javascript 返回数组中 最大 最小 平均值多种方法分析比较 by FungLeo前言一组数字全部是数字,我们需要返回数组中最大或者最小的数字,这是常见的需求.当然,求数组中所有数字的平均值,也是一个很常见的需求.今天我...
  • 给定一个整型数组在数组中找出由三个数组成的最大乘积,并输出这个乘积。 示例 1: 输入: [1,2,3] 输出: 6 示例 2: 输入: [1,2,3,4] 输出: 24 注意: 给定的整型数组长度范围是[3,104],数组中所有的元素范围是[-...
  • js vue获取一个日期数组中最小的日期或者最大的日期: 代码用IE,FF,Chrome测试并正常工作: var dates=[]; dates.push(new Date("2011/06/25")) dates.push(new Date("2011/06/26")) dates.push(new Date("2011/...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 316,157
精华内容 126,462
关键字:

在一个数组中找最大最小