
算法
labuladong
这个作者很懒,什么都没留下…
展开
-
回溯算法详解
这篇文章是很久之前的一篇《回溯算法详解》的进阶版,之前那篇不够清楚,就不必看了,看这篇就行。把框架给你讲清楚,你会发现回溯算法问题都是一个套路。废话不多说,直接上回溯算法框架。解决一个回溯问题,实际上就是一个决策树的遍历过程。你只需要思考 3 个问题:1、路径:也就是已经做出的选择。2、选择列表:也就是你当前可以做的选择。3、结束条件:也就是到达决策树底层,无法再做选择的条件。如果你不理...原创 2019-12-02 12:59:12 · 706 阅读 · 0 评论 -
一行代码解决的智力题
下文是我在 LeetCode 刷题过程中总结的三道有趣的「脑筋急转弯」题目,可以使用算法编程解决,但只要稍加思考,就能找到规律,直接想出答案。一、Nim 游戏游戏规则是这样的:你和你的朋友面前有一堆石子,你们轮流拿,一次至少拿一颗,最多拿三颗,谁拿走最后一颗石子谁获胜。假设你们都很聪明,由你第一个开始拿,请你写一个算法,输入一个正整数 n,返回你是否能赢(true 或 false)。比如现...原创 2019-11-11 14:41:06 · 374 阅读 · 0 评论 -
最长公共子序列
最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经典的面试题目,因为它的解法是典型的二维动态规划,大部分比较困难的字符串问题都和这个问题一个套路,比如说编辑距离。而且,这个算法稍加改造就可以用于解决其他问题,所以说 LCS 算法是值得掌握的。题目就是让我们求两个字符串的 LCS 长度:输入: str1 = "abcde", str2 = "ace"...原创 2019-11-11 14:17:49 · 7937 阅读 · 0 评论 -
动态规划设计:最长递增子序列
很多读者反应,就算看了前文动态规划详解,了解了动态规划的套路,也不会写状态转移方程,没有思路,怎么办?本文就借助「最长递增子序列」来讲一种设计动态规划的通用技巧:数学归纳思想。最长递增子序列(Longest Increasing Subsequence,简写 LIS)是比较经典的一个问题,比较容易想到的是动态规划解法,时间复杂度 O(N^2),我们借这个问题来由浅入深讲解如何写动态规划。比较难想...原创 2019-11-11 14:16:26 · 1192 阅读 · 0 评论 -
贪心算法之区间调度问题
什么是贪心算法呢?贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高。比如说一个算法问题使用暴力解法需要指数级时间,如果能使用动态规划消除重叠子问题,就可以降到多项式级别的时间,如果满足贪心选择性质,那么可以进一步降低时间复杂度,达到线性级别的。什么是贪心选择性质呢,简单说就是:每一步都做出一个局部最优的选择,最终的结...原创 2019-11-11 14:14:14 · 1292 阅读 · 0 评论 -
动态规划之编辑距离
前几天看了一份鹅场的面试题,算法部分大半是动态规划,最后一题就是写一个计算编辑距离的函数,今天就专门写一篇文章来探讨一下这个问题。我个人很喜欢编辑距离这个问题,因为它看起来十分困难,解法却出奇得简单漂亮,而且它是少有的比较实用的算法(是的,我承认很多算法问题都不太实用)。下面先来看下题目:为什么说这个问题难呢,因为显而易见,它就是难,让人手足无措,望而生畏。为什么说它实用呢,因为前几天我就...原创 2019-11-11 14:11:18 · 345 阅读 · 0 评论 -
KMP 算法详解
KMP 算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法,效率很高,但是确实有点复杂。很多读者抱怨 KMP 算法无法理解,这很正常,想到大学教材上关于 KMP 算法的讲解,也不知道有多少未来的 Knuth、Morris、Pratt 被提前劝退了。有一些优秀的同学通过手推 KMP 算法的过程来辅助理解该算法,这是一种办法,不过本文要从逻辑层面帮助读者理解算法的原理。十行...原创 2019-11-11 14:02:21 · 719 阅读 · 0 评论 -
动态规划算法实现正则表达匹配
之前的文章【动态规划详解】收到了普遍的好评,今天写一个动态规划的实际应用:正则表达式。如果有读者对「动态规划」还不了解,建议先看一下上面那篇文章。正则表达式匹配是一个很精妙的算法,而且难度也不小。本文主要写两个正则符号的算法实现:点号「.」和星号「*」,如果你用过正则表达式,应该明白他们的用法,不明白也没关系,等会会介绍。文章的最后,介绍了一种快速看出重叠子问题的技巧。本文还有一个重要目的,就...原创 2019-07-29 10:17:08 · 425 阅读 · 0 评论 -
几道一行代码就能解决的智力题
下文是我在 LeetCode 刷题过程中总结的三道有趣的「脑筋急转弯」题目,可以使用算法编程解决,但只要稍加思考,就能找到规律,直接想出答案。一、Nim 游戏游戏规则是这样的:你和你的朋友面前有一堆石子,你们轮流拿,一次至少拿一颗,最多拿三颗,谁拿走最后一颗石子谁获胜。假设你们都很聪明,由你第一个开始拿,请你写一个算法,输入一个正整数 n,返回你是否能赢(true 或 false)。比如现...原创 2019-07-29 09:51:51 · 478 阅读 · 0 评论 -
一文读懂动态规划算法原理,由浅入深
动态规划详解本文转载自微信公众号:labuladong动态规划算法似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步。而且,当你去看用动态规划解决某个问题的代码时,你会觉得这样解决问题竟然如此巧妙,但却难以理解,你可能惊讶于人家是怎么想到这种解法的。实际上,动态规划是一种常见的「算法设计技...原创 2019-07-29 09:47:07 · 4645 阅读 · 10 评论 -
动态规划设计方法详解最长递增子序列
很多读者反应,就算看了前文动态规划详解,了解了动态规划的套路,也不会写状态转移方程,没有思路,怎么办?本文就借助「最长递增子序列」来讲一种设计动态规划的通用技巧:数学归纳思想。最长递增子序列(Longest Increasing Subsequence,简写 LIS)是比较经典的一个问题,比较容易想到的是动态规划解法,时间复杂度 O(N^2),我们借这个问题来由浅入深讲解如何写动态规划。比较难想...原创 2019-07-29 09:38:46 · 3538 阅读 · 1 评论 -
数据结构和算法学习的框架思维
转载自微信公众号:labuladong本文是对整个数据结构及算法的总体框架认识,旨在教会读者从整体到细节,自顶向下,从抽象到具体地认识数据结构,这种思维也是递归思维的精华所在。希望通过本文读者在对数据结构的学习和理解上能有更高层的认识。先声明一下:首先,这里讲的都是普通的数据结构,咱不是搞算法竞赛的,野路子出生,很多厉害的知识我不会,我只会解决常规的问题。另外,以下是我个人的经验的总结,没有哪...原创 2019-05-23 20:16:12 · 1980 阅读 · 1 评论 -
LeetCode 算法学习指南
本文来自微信公众号:labuladong之前发的那篇关于 框架性思维 的文章,我也发到了不少其他圈子,受到了大家的普遍好评,这一点我真的没想到,首先感谢大家的认可,我会更加努力,写出通俗易懂的算法文章。有很多朋友问我数据结构和算法到底该怎么学,尤其是很多朋友说自己是「小白」,感觉这些东西好难啊,就算看了之前的「框架思维」,也感觉自己刷题乏力,希望我能聊聊我从一个非科班小白一路是怎么学过来的。...原创 2019-05-23 20:22:03 · 7420 阅读 · 2 评论 -
团灭 LeetCode 股票问题
本文截取自公众号 labuladong 的文章:团灭 LeetCode 股票问题,建议点击链接获得更好的阅读体验。上篇文章 一种通用思路 用递归的方法实现了一套简单易懂的可行解,但是时间复杂度略高,不能通过全部测试用例,这篇文章用状态机的技巧来解决,可以全部提交通过。不要觉得这个名词高大上,文学词汇而已,实际上就是 DP table,看一眼就明白了。先看看别人的解法...原创 2019-06-07 12:49:03 · 1019 阅读 · 1 评论 -
二分查找细节详解
二分查找真的很简单吗?并不简单。看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的:Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky…这句话可以这样理解:思路很简单,细节是魔鬼。本文就来探究几个最常用的二分查...原创 2019-07-29 09:20:09 · 464 阅读 · 0 评论 -
二叉搜索树操作集锦
二叉树算法的设计的总路线:明确一个节点要做的事情,然后剩下的事抛给框架。void traverse(TreeNode root) { // root 需要做什么?在这做。 // 其他的不用 root 操心,抛给框架 traverse(root.left); traverse(root.right);}PS:关于写算法的框架,是很重要的,直接决定了我们思考的方...原创 2019-07-29 09:21:23 · 281 阅读 · 0 评论 -
LRU 算法策略详解
如果只想看代码的读者可以直接翻到最后,有 Java 和 C++ 的解法代码。一、什么是 LRU 算法就是一种缓存淘汰策略。计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置。但问题是,删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?LRU 缓存淘汰算法就是一种常用策略。LR...原创 2019-07-29 09:23:30 · 5858 阅读 · 1 评论 -
随机乱置算法(洗牌算法)详解
我知道大家会各种花式排序算法,但是如果叫你打乱一个数组,你是否能做到胸有成竹?即便你拍脑袋想出一个算法,怎么证明你的算法就是正确的呢?乱序算法不像排序算法,结果唯一可以很容易检验,因为「乱」可以有很多种,你怎么能证明你的算法是「真的乱」呢?所以我们面临两个问题:什么叫做「真的乱」?设计怎样的算法来打乱数组才能做到「真的乱」?这种算法称为「随机乱置算法」或者「洗牌算法」。本文分两部分,...原创 2019-07-29 09:24:37 · 1815 阅读 · 0 评论 -
一些有趣有用的位操作
本文分两部分,第一部分列举几个有趣的位操作,第二部分讲解算法中常用的 n & (n - 1) 操作,顺便把用到这个技巧的算法题列出来讲解一下。因为位操作很简单,所以假设读者已经了解与、或、异或这三种基本操作。位操作(Bit Manipulation)可以玩出很多奇技淫巧,但是这些技巧大部分都过于晦涩,没必要深究,读者只要记住一些有用的操作即可。一、几个有趣的位操作利用或操作 | 和...原创 2019-07-29 09:34:01 · 243 阅读 · 0 评论 -
详解递归,带 LeetCode 例题
首先说明一个问题,简单阐述一下递归,分治算法,动态规划,贪心算法这几个东西的区别和联系,心里有个印象就好。递归是一种编程技巧,一种解决问题的思维方式;分治算法和动态规划很大程度上是递归思想基础上的(虽然动态规划的最终版本大都不是递归了,但解题思想还是离不开递归),解决更具体问题的两类算法思想;贪心算法是动态规划算法的一个子集,可以更高效解决一部分更特殊的问题。分治算法将在这节讲解,以最经典的归...原创 2019-04-30 09:32:51 · 633 阅读 · 0 评论