精华内容
下载资源
问答
  • 2019-10-24 21:04:22

    五分钟学算法:

    https://www.cxyxiaowu.com/

    通过动画来理解算法,我觉得很有意思。

    然后祝程序员生日快乐,永不加班!

     

    更多相关内容
  • 点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。转自面向大象编程,作者nettee题目描述这是一道经典的面试题了,也叫做 “Top K 问题”。解决这个问题有两种常用...

    点击关注上方“五分钟学算法”,

    设为“置顶或星标”,第一时间送达干货。

    转自面向大象编程,作者nettee

    题目描述

    这是一道经典的面试题了,也叫做 “Top K 问题”。解决这个问题有两种常用的方法:堆方法、分治法。分治法的思想和快速排序相同。

    本篇题解分别讲解了两种方法,并比较了它们的适用场景。

    题目解析

    这道题是一个经典的 Top K 问题,是面试中的常客。Top K 问题有两种不同的解法,一种解法使用堆(优先队列),另一种解法使用类似快速排序的分治法。这两种方法各有优劣,最好都掌握。本文用图解的形式讲解这道问题的两种解法,包括三个部分:

    • 方法一:堆,时间复杂度

    • 方法二:快排变形,(平均)时间复杂度

    • 两种方法的优劣比较

    方法一:堆

    比较直观的想法是使用堆数据结构来辅助得到最小的 k 个数。堆的性质是每次可以找出最大或最小的元素。我们可以使用一个大小为 k 的最大堆(大顶堆),将数组中的元素依次入堆,当堆的大小超过 k 时,便将多出的元素从堆顶弹出。我们以数组 为例展示元素入堆的过程,如下面动图所示:

    入堆出堆的过程

    这样,由于每次从堆顶弹出的数都是堆中最大的,最小的 k 个元素一定会留在堆里。这样,把数组中的元素全部入堆之后,堆中剩下的 k 个元素就是最大的 k 个数了。

    注意在动画中,我们并没有画出堆的内部结构,因为这部分内容并不重要。我们只需要知道堆每次会弹出最大的元素即可。在写代码的时候,我们使用的也是库函数中的优先队列数据结构,如 Java 中的 PriorityQueue。在面试中,我们不需要实现堆的内部结构,把数据结构使用好,会分析其复杂度即可。

    以下是题解代码。感谢评论区提醒,这里的代码可以做一些优化,如果当前数字不小于堆顶元素,数字可以直接丢掉,不入堆。下方的代码已更新:

    public int[] getLeastNumbers(int[] arr, int k) {
        if (k == 0) {
            return new int[0];
        }
        // 使用一个最大堆(大顶堆)
        // Java 的 PriorityQueue 默认是小顶堆,添加 comparator 参数使其变成最大堆
        Queue<Integer> heap = new PriorityQueue<>(k, (i1, i2) -> Integer.compare(i2, i1));
    
        for (int e : arr) {
            // 当前数字小于堆顶元素才会入堆
            if (heap.isEmpty() || heap.size() < k || e < heap.peek()) {
                heap.offer(e);
            }
            if (heap.size() > k) {
                heap.poll(); // 删除堆顶最大元素
            }
        }
    
        // 将堆中的元素存入数组
        int[] res = new int[heap.size()];
        int j = 0;
        for (int e : heap) {
            res[j++] = e;
        }
        return res;
    }
    

    算法的复杂度分析:

    • 由于使用了一个大小为 k 的堆,空间复杂度为

    • 入堆和出堆操作的时间复杂度均为 ,每个元素都需要进行一次入堆操作,故算法的时间复杂度为

    方法二:快排变形

    Top K 问题的另一个解法就比较难想到,需要在平时有算法的积累。实际上,“查找第 k 大的元素”是一类算法问题,称为选择问题。找第 k 大的数,或者找前 k 大的数,有一个经典的 quick select(快速选择)算法。这个名字和 quick sort(快速排序)看起来很像,算法的思想也和快速排序类似,都是分治法的思想。

    让我们回顾快速排序的思路。快速排序中有一步很重要的操作是 partition(划分),从数组中随机选取一个枢纽元素 v,然后原地移动数组中的元素,使得比 v 小的元素在 v 的左边,比 v 大的元素在 v 的右边,如下图所示:

    partition 示意图

    这个 partition 操作是原地进行的,需要 的时间,接下来,快速排序会递归地排序左右两侧的数组。而快速选择(quick select)算法的不同之处在于,接下来只需要递归地选择一侧的数组。快速选择算法想当于一个“不完全”的快速排序,因为我们只需要知道最小的 k 个数是哪些,并不需要知道它们的顺序。

    我们的目的是寻找最小的 个数。假设经过一次 partition 操作,枢纽元素位于下标 ,也就是说,左侧的数组有 个元素,是原数组中最小的 个数。那么:

    • ,我们就找到了最小的 个数,就是左侧的数组;

    • ,则最小的 个数一定都在左侧数组中,我们只需要对左侧数组递归地 partition 即可;

    • ,则左侧数组中的 个数都属于最小的 个数,我们还需要在右侧数组中寻找最小的 个数,对右侧数组递归地 partition 即可。

    这种方法需要多加领会思想,如果你对快速排序掌握得很好,那么稍加推导应该不难掌握 quick select 的要领。

    以下是题解代码:

    public int[] getLeastNumbers(int[] arr, int k) {
        if (k == 0) {
            return new int[0];
        } else if (arr.length <= k) {
            return arr;
        }
        
        // 原地不断划分数组
        partitionArray(arr, 0, arr.length - 1, k);
        
        // 数组的前 k 个数此时就是最小的 k 个数,将其存入结果
        int[] res = new int[k];
        for (int i = 0; i < k; i++) {
            res[i] = arr[i];
        }
        return res;
    }
    
    void partitionArray(int[] arr, int lo, int hi, int k) {
        // 做一次 partition 操作
        int m = partition(arr, lo, hi);
        // 此时数组前 m 个数,就是最小的 m 个数
        if (k == m) {
            // 正好找到最小的 k(m) 个数
            return;
        } else if (k < m) {
            // 最小的 k 个数一定在前 m 个数中,递归划分
            partitionArray(arr, lo, m-1, k);
        } else {
            // 在右侧数组中寻找最小的 k-m 个数
            partitionArray(arr, m+1, hi, k);
        }
    }
    
    // partition 函数和快速排序中相同,具体可参考快速排序相关的资料
    // 代码参考 Sedgewick 的《算法4》
    int partition(int[] a, int lo, int hi) {
        int i = lo;
        int j = hi + 1;
        int v = a[lo];
        while (true) {
            while (a[++i] < v) {
                if (i == hi) {
                    break;
                }
            }
            while (a[--j] > v) {
                if (j == lo) {
                    break;
                }
            }
    
            if (i >= j) {
                break;
            }
            swap(a, i, j);
        }
        swap(a, lo, j);
    
        // a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
        return j;
    }
    
    void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    

    上述代码中需要注意一个细节(评论区有好几个小伙伴问到,这里补充说明一下):

    partitionArray 函数中,两次递归调用传入的参数为什么都是 k?特别是第二个调用,我们在右侧数组中寻找最小的 k-m 个数,但是对于整个数组而言,这是最小的 k 个数。所以说,函数调用传入的参数应该为 k。

    该代码的成绩还是非常好的:

    算法的复杂度分析:

    • 空间复杂度 ,不需要额外空间。

    • 时间复杂度的分析方法和快速排序类似。由于快速选择只需要递归一边的数组,时间复杂度小于快速排序,期望时间复杂度为 ,最坏情况下的时间复杂度为

    两种方法的优劣性比较

    在面试中,另一个常常问的问题就是这两种方法有何优劣。看起来分治法的快速选择算法的时间、空间复杂度都优于使用堆的方法,但是要注意到快速选择算法的几点局限性:

    第一,算法需要修改原数组,如果原数组不能修改的话,还需要拷贝一份数组,空间复杂度就上去了。

    第二,算法需要保存所有的数据。如果把数据看成输入流的话,使用堆的方法是来一个处理一个,不需要保存数据,只需要保存 k 个元素的最大堆。而快速选择的方法需要先保存下来所有的数据,再运行算法。当数据量非常大的时候,甚至内存都放不下的时候,就麻烦了。

    所以当数据量大的时候还是用基于堆的方法比较好。

    END


    ● 二叉树问题太复杂?「三步走」方法解决它!

    ● 五分钟学算法:什么是堆?

    ● 一个我超喜欢的动态博客系统,五分钟即可部署上线!

    五分钟学算法:什么是线段树?

    点“在看”你懂得 

    展开全文
  • 点击蓝色“五分钟学算法”关注我哟加个“星标”,天天中午 12:15,一起学算法作者 | 程序员小吴来源 | 五分钟学算法今天分享一道简单的笔试题,题目来源于京东校园招聘笔...

    点击蓝色“五分钟学算法”关注我哟

    加个“星标”,天天中午 12:15,一起学算法

    640?wx_fmt=jpeg

    作者 | 程序员小吴

    来源 | 五分钟学算法

    今天分享一道简单的笔试题,题目来源于京东校园招聘笔试真题。你做出这道简单的题目需要花费多少东分钟呢?

    题目描述

    有一个有序表为 {1,5,8,11,19,22,31,35,40,45,48,49,50} ,当二分查找值为 48 的结点时,查找成功需要比较的次数( )

    • A、4

    • B、3

    • C、2

    • D、1

    题目分析

    一道送分题。

    有序表的长度为 13,根据 二分查找法 查找数的特性,每次都  n/2 进行折半查找。

    13 / 2 = 6
    
    6 / 2 = 3
    
    3 / 2 = 1
    
    1 / 2 = 0
    

    最多需要 4 次就能得出结果。

    这道题目需要查找的是 48 ,列表下标索引从零开始标记。

    第一次,求出 [0,12] 中间节点。

    0 + (12 - 0) / 2 = 6 
    
    a[6] = 31 < 48
    

    区间变为 [7,12]。

    第二次,求出 [7,12] 中间节点。

    7 + (12 - 7) / 2 = 9 
    
    a[9] = 45 < 48
    

    区间变为 [10,12]。

    第三次,求出 [10,12] 中间节点。

    10 + (12 - 10) / 2 = 11 
    
    a[11] = 49 > 48
    

    区间变为 [10,11]。

    第四次,求出 [10,11] 中间节点。

    10 + (11 - 10) / 2 = 10
    
    a[10] = 48 = 48
    

    找到啦!

    ---
    以上,便是今日分享,觉得不错,还请点个在看,谢谢~
    推荐阅读:



    啦,欢迎点击阅读原文进行访问~

    640?wx_fmt=jpeg

    展开全文
  • 密码学算法

    2018-04-03 15:18:32
    该内容为AES密码算法、MD5和背包公钥密码算法等文档内容,希望对大家在密码方面有所帮助
  • 学算法必备的一个网站与 app

    千次阅读 2020-12-05 16:00:00
    公众号关注“五分钟学算法”设为 “星标”,带你挖掘更多开发神器!大家好,我是小 G。众所周知,程序员都需要翻越数据结构与算法这座大山,有的大神可以到达山顶领略更美好的风景,有的则在半山...

    公众号关注 “五分钟学算法”

    设为 “星标”,带你挖掘更多开发神器!

    大家好,我是小 G。

    众所周知,程序员都需要翻越数据结构与算法这座大山,有的大神可以到达山顶领略更美好的风景,有的则在半山腰停下了绝不,而有的则在山底徘徊找不到上山的路径。

    如果想要舒服的入门学习数据结构与算法,那我这两个辅助工具,一个是网站,一个是 app,它们的作用都是可以帮助你更加形象的理解数据结构与算法,因为它们都具备可视化的功能,再也不用担心在山底无助的摸索。

    网站是 VisuAlgo,app 是算法动画图解。

    1、VisuAlgo

    VisuAlgo 是由 Steven Halim 博士在 2011 年发布的一款可视化学习算法的工具,用于帮助其学生更好地理解数据结构和算法, 它具备暂停、单步、回退等功能,可以实时的帮助学生更直观的理解代码的执行过程。

    打开 https://visualgo.net/zh  一探究竟(是的,这个网站支持中文)。

    直接映入眼帘的便是程序员常用的数据结构与算法,像排序、位掩码、链表、哈希表、二叉堆、二叉搜索树等常见算法动画应有尽有,就连高级的数据结构比如图、并查集、线段树等也安排的明明白白。

    以我们第一个接触的算法冒泡排序为例,看看 VisuAlgo 是如何帮助学生更直观的理解数据结构与算法的。

    首先进入冒泡排序的页面,在左下角创建模拟的排序数组,根据需要,可以将排序数组的数据具备一定的特殊性,比如是否近乎有序(一般情况下,近乎有序的时候采取插入排序效果最好)。

    创建好数组好,点击 排序 --> 执行,可以看到上方的矩形开始运动交换,相应的,右下角也在跳动着代码,期间,你可以随时的暂停仔细琢磨代码与动画对应的逻辑。

    2、算法动画图解

    「算法动画图解」是一款可以在手机上运行的应用,可以在 App Store 以及各大应用市场下载,它用动画的形式帮你把基础算法捋一遍,每个算法动画的操作都是可以暂停、回退。

    依旧以我们第一个接触的算法冒泡排序为例,看看 「算法动画图解」 是如何帮助学生更好的理解数据结构与算法的。

    以上,便是今天的分享,觉得内容对你有所帮助的,还请点个「在看」支持,谢谢各位啦~

    推荐阅读:

    他,生物系毕业,刚入职连 Java 都没听过,却在马云的要求下,三周写出淘宝网雏形

    再见,Visio!

    神器 Typora !

    展开全文
  • 信息奥赛一本通-教程PPT课件(第版)算法部分
  • 零基础学算法(第2版)(零基础学编程)(光盘源码) 本书分为上、下两篇,共10章,上篇用5章的篇幅介绍了算法和数据结构的基础知识,包括基础算法思想、简单数据结构、复杂数据结构、排序和查找算法等内容;下篇用5...
  • 信息奥赛一本通-教程PPT课件(第版)算法部分
  • 算法和数据结构》学习路线指引

    万次阅读 多人点赞 2021-07-01 11:16:15
    前 WorldFinal 选手对学习算法的一点总结。张思维导图解决你的困惑
  • 《零基础学编程:零基础学算法(第3版)》分为上、下两篇,共10章,上篇用5章的篇幅介绍了算法和数据结构的基础知识,包括基础算法思想、简单数据结构、复杂数据结构、排序和查找算法等内容;下篇用4章的篇幅介绍了用...
  • 运筹大作业,用算法解决经典tsp问题,选取某地一次定向越野比赛,使用模拟退火算法,蚁群算法,遗传算法,hopfiled神经网络,和lingo来解决问题。包括源代码和课程大报告
  • 常见密码学算法

    千次阅读 2020-06-22 16:15:21
    常见密码学算法:DES,AES; RSA, ECC; Hash; Signature等。 分类 对称密码 流密码 分组密码 非对称密码 不同阶段 古典/经典密码(凯撒密码),(1949 Shannon)近代密码(DES/AES),(1976 Diffie-Hellman, ...
  • 机器学习算法 无监督学习 算法

    千次阅读 2019-06-26 14:51:22
    本文介绍无监督学习算法: 聚类算法 Apriori算法 FP-growth 算法 1 聚类算法 2 Apriori算法 3 FP-growth 算法
  • 信息奥赛一本通-教程PPT课件(第版)算法部分
  • 如何学习算法

    千次阅读 多人点赞 2019-09-14 15:34:26
    今天在群里刚好看到有人在讨论算法的问题,刚好自己曾经也有一个算法大神的梦,来说说自己对算法的理解。算法怎么?什么样程度才算把算法学透?算法学会了有什么用?算法的学习是非...
  • 计算机图形学算法总结

    千次阅读 多人点赞 2020-12-16 23:49:40
    图形学算法总结 文章目录图形学算法总结直线生成算法数值微分法(DDA)中点画线法Bresenham算法圆弧生成算法中点Bresenham画圆法多边形填充算法逐点判断法1)射线法2)累计角度法扫描线算法(YX)改进的扫描线算法(Y-...
  • 算法如何学习?别想太多,两个字

    千次阅读 多人点赞 2022-02-24 07:20:59
    当然,如果直接开始学算法,也不是不可以,只要坚持把该专栏的 100 讲 攻克完毕,基本上语言那关也可以过了。 、算法进阶 1、「 画解数据结构 」   以动图的形式,更加生动形象的阐释每个数据结构的思想和实现。...
  • 运筹中的tsp问题,利用蚁群算法,遗传算法,hopfield神经网络, lingo软件等种方案解决
  • 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以我认为本文题目是合理的。 原文作者:...
  • 如何学习算法的相关文章,大家估计也见过不少,每个人的学习方法都不尽相同,这很正常,并且,对于不同的选手,例如打 ACM 的玩家和不打比赛的玩家来说,训练的方式也会有所差异,所以别人所说的学习方式,更多的是...
  • 如何入门学算法

    万次阅读 多人点赞 2017-11-23 17:13:20
    随着科学技术的发展,人工智能已渗透到各个行业,算法工程师非常火爆,急缺大量人才,年薪也越来越高。很多人想入手学习算法,那么多算法,究竟该如何下手呢?
  • DES算法 DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。 明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、...
  • 尹成老师带你学算法

    千人学习 2019-07-09 14:14:59
    语言有很多,开发框架更是日新月异3个月不就落后 我们可以学习很多语言,很多框架,但招聘不会考你用5种语言10种框架实现同一个功能。真正让程序员有区分度,企业招聘万年不变的重点 —— 算法与数据结构。本课程...
  • 大经典算法

    2018-04-22 19:27:31
    主要讲解分治法、动态规划、贪心法、回溯法以及分支限界法等几种种经典的算法, 让同学们能够更进步了解算法的魅力所在。 在本章对每一种算法都是从...让读者能够综合运用前面几章所知识,进一步加深对算法的理解。
  • 先说答案建议先C语言,掌握基本的语法基础后,再数据结构与算法,C语言编程与数据结构和算法这两个完全是两个东西了。 学习数据结构和算法有一个很重要的前提,就是至少熟练掌握一门编程语言,编程语言掌握肯定...
  • 按照我下面整理的思路学习,保证能让你大幅提升数据结构与算法实践能力! 许多人有这样的疑问,《数据结构与算法》理论学习完了,但是做题还是不会;有的同学感觉数据结构与算法不知道怎么学习。那看这篇文章就对了...
  • 环检测应该是一个非常常见的算法问题,怎么判断是否有环的问题呢? 一个很简单的做法就是用HashSet来保存要遍历的数据,如果出现了重复就知道这个链表是有环的。但是这个方法需要保存遍历过的所有的元素,所以其...
  • 为什么要学习算法

    千次阅读 2018-02-11 09:58:53
    在我学习JVM的时候,有一个5~6年开发经验的coder说:学习这个有什么用啊,在工作中又用不到,还这么难。 这句话引起了我的思考,这个问题和我今天想说的,为什么要学习算法其实是同一个问题,也是不少IT从业者不解...
  • 机器学习必十大算法

    千次阅读 2021-10-03 01:08:08
    点击上方“小白视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达本文介绍了 10 大常用机器学习算法,包括线性回归、Logistic 回归、线性判别分析、朴素贝叶斯、KNN、随机森林...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 953,034
精华内容 381,213
关键字:

五分钟学算法

友情链接: polncyjcircuit.rar