自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

李威威的博客

快乐生活每一天!

  • 博客(72)
  • 资源 (2)
  • 收藏
  • 关注

原创 LeetCode 题解之 147. Insertion Sort List

本章内容概要并查集的内容非常简单,代码可以一气呵成敲打完。并且每个方法的实现都很短。

2017-09-16 23:49:14 700

原创 5-11 树形问题和更多树

(多看看,学会思想)虽然没有创建树。递归方法天然地具有递归的性质。归并排序法和快速排序法的思想它们像极了对一棵树进行后序遍历和前序遍历。搜索问题一条龙游戏8 数码8皇后数独搬运工人工智能:搬运工,树形搜索机器学习更多树:KD 树,区间树,哈夫曼树

2017-09-16 23:47:54 520

原创 5-10 二分搜索树的局限性

二分查找树的性能。二分查找树在一些极端情况下性能并不好。我们首先要认识下面一个事实:同样的数据,可以对应不同的二分搜索树。看下面的例子。二分搜索树可以退化为链表。此时时间复杂度变成了 O(n)。极端测试:如果把 key 排序好以后,依次插入到二分搜索树中,此时二分搜索树的高度就会变得非常高。解决方案:平衡二叉树,使用红黑树(红黑树是一种平衡二叉树的实现,其它平衡二叉树的实现还有 2-3 tree,A

2017-09-16 23:47:10 692

原创 5-9 二分搜索树的顺序性

二分搜索树当做查找表的一种实现。我们使用二分搜索树的目的是通过查找 key 马上得到 value。二分搜索树还能回答哪些问题呢?这些问题都和顺序相关。minimum,maximumsuccessor,predecessor(这两个元素在二分搜索树的 key 中必须存在)floor(地板),ceil(天花板)(这两个元素在二分搜索树的 key 中可以存在,也可以不存在)rank(58 是排名第几的元素

2017-09-16 23:46:26 542

原创 5-8 二分搜索树的删除,删除一个节点的步骤2

基本性质1: 最小值所在的节点只会有右孩子; 最大值所在的节点只会有左孩子。利用基本性质1:我们删除了二分搜索树中最小的节点和最大的节点。 其实这个基本性质1还可以用于删除二分搜索树中只有1个孩子的节点。此时二分搜索树的性质是保持不变的。下面考虑最难的情况:删除左右都有孩子的节点。1962年,由 Hibbard 提出,Hubbard Deletion。思路:我们应该考虑拿一个已经有的节点出来来

2017-09-16 23:44:20 620

原创 5-7 删除一个节点:步骤1-删除最大值,最小值

把握下面的这个最基本且简单的性质: 最小值:从根节点开始,不停地沿着左边节点的方向找,直到再也没有左节点为止; 最大值:从根节点开始,不停地沿着右边节点的方向找,直到再也没有右节点为止。试着用非递归的方式实现一下。下面的逻辑,虽然简单,但是有陷阱,自己要关注一下细节。删除最小值的节点 关键把握一点: 如果最小值的节点没有右孩子,很好办,直接删除,如果最小值的节点有右孩子,让右孩子代替自己(自

2017-09-16 23:43:48 1287

原创 5-6 层序遍历(广度优先遍历)

重点把握:我们首先将每一层的节点优先遍历完毕。之前的遍历叫做深度优先遍历,我们尝试先走到最深。这一节我们学习广度优先遍历。要想完成广度优先遍历,我们要借助队列(先进先出,后进后出)的概念。思想 :当队列中的队首出队的时候,要从二叉搜索树中找到它的两个孩子入队。队列出队为空的时候,就将二叉树遍历完成了。我们再归纳一下广度优先遍历的步骤:1、将根节点入队(入队的时候不做别的操作);2、队列非空,所以接下

2017-09-16 23:43:10 1086

原创 5-5 二分搜索树的遍历(深度优先遍历)

深度优先遍历的含义首先尝试走到最深。前序、中序、后序遍历的定义 遍历方式 对遍历方式解释 前序遍历 先访问当前节点,再依次递归访问左右子树。 中序遍历 先递归访问左子树,再访问自身、再递归访问右子树。 后序遍历 先递归访问左右子树,再访问自身节点。释放整个二叉树的时候会使用到后序遍历。把握要点:访问当前节点的顺序是在前面、中间还是在后面。其实,代码的实现是异常简单的!

2017-09-16 23:42:27 399

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 61-68 题

查找专注于找到这个元素。我们思考一下,在 search 这个方法中,我们应该将什么返回回去,一个好的数据结构应该将内部的数据对外隐藏。二分查找树的包含 contain(返回 true 或者 false) 和查找 search(返回相应的 vlaue 值) 同质。考虑查找成功和失败这两种情况。1、首先实现 contain 方法/** * 在整个二叉树中是否包含 key * * @param ke

2017-09-16 23:41:41 566

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 51-60 题

思路:我们应该充分利用二分搜索树的性质来完成 insert 操作的编写。 /** * 向一棵二分搜索树中插入一个节点 * 千万不要忘记把返回值赋给 root ,这样才符合 root 的定义 * * @param key * @param value */public void insert(K key, V value) { root = insert(root, key, v

2017-09-16 23:40:46 862

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 41-50 题

二分搜索树这个数据结构的提出,是自来于“查找表”或者说“字典”这种数据结构的。实现查找表,可以通过“普通数组”“顺序数组”“二分搜索树”来实现。其中,最有效的方式就是实现二分搜索树。图:普通数组、顺序数组、二分搜索树对查找、插入、删除元素的时间复杂度分析对于上表的说明:普通数组的插入操作:要先查找有没有这个元素,然后插入或者覆盖。普通数组的删除操作:要先查找有没有这个元素,然后删除或者什么都不做。顺

2017-09-15 23:23:24 812

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 31-40 题

我们使用数据结构的核心是为了解决问题。使用的数据结构可以高效地解决一类问题。而不是为了使用数据结构而使用数据结构。查找问题是计算机中非常重要的一类基础的问题。使用二分查找法的前提对于有序的数列才能使用二分查找法。小故事 二分查找法的思想在 1946 年就被提出来了。但是第 1 个没有 bug 的二分查找法在 1962 年才出现。二分查找法的时间复杂度是 O(logn) 。注意二分查找法有一个坑

2017-09-15 23:22:48 750

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 21-30 题

(1)使用堆实现优先队列动态选择优先级最高的任务执行(2)从 100万个元素中选择前 100每次新放入一个元素之后,把最小堆中的第 1 个元素请出去。(3)多路归并排序(这个思路听起来好像很有意思)如果一个数组有 n 个元素,对这个数组的元素进行 n 路归并排序,此时归并排序就退化成了堆排序。(4)d 叉堆一般的任务使用二叉堆是可以实现的。我们的例子实现的均是最大堆、最大索引堆。可以试着实现以下最小

2017-09-15 23:21:03 647

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 11-20 题

我们引入了反向查找表。(这一节的内容和思想很重要,要多看。)reverse[i] 表示索引 i 在 indexes(堆)中的位置。引入 reveres 数组的意义是,可以在执行 change 这个方法的时候,使用 O(1) 这个时间复杂度,直接找到性质:性质1:如果indexes[i]=j,那么reveres[j]=i性质2:indexes[reveres[i]]=i,reveres[index[i

2017-09-15 23:20:14 1025

原创 《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 01-10 题

最大索引堆change 操作:首先我们来解释一下 change 操作,在实际应用中,我们除了有 insert 和 extract 这两个操作以外,我们数组中的元素很可能是动态变化的,在变化的过程中,如何保持最大堆的性质,这就是我们要讨论的问题。最大索引堆的特性1、最大索引堆的内部维护了一个索引数组,这个索引数组构成了一个最大堆;2、使用最大索引堆的时候,可以很好地支持 change 这个操作,即我们

2017-09-15 23:18:54 1679

原创 《算法与数据结构》学习笔记 4-7 排序算法总结

平均时间复杂度。快速排序相对会更快一些。一般系统级别的排序,是用快速实现的。如果有大量重复排序,可以使用三路快速排序。排序算法的稳定性:学生成绩单初始:按照学生姓名。然后:按照学生成绩,相同成绩的同学按照学生姓名。可以通过自定义比较函数,让排序算法不存在稳定性问题。系统级别的排序算法,如果要求稳定性的话,一般使用归并排序。是不是存在一种神秘的排序算法?所有指标达到最优。

2017-09-15 23:18:04 546

原创 《算法与数据结构》学习笔记 4-6 优化的堆排序(原地堆排序)

(1)大体思路一个数组可以看成是一个堆。我们在上一节也可以看到,我们将一个数组通过 shift down 的方式逐渐地整理成一个最大堆。主要用到了 shift down 和 heapify 两个算法。此时,因为用到了索引,我们就须要将最大堆中数组的索引从 0 开始计算。parent(i)=(i-1)/2left child(i) = 2*i +1right child(i) = 2*i+2(上面公式

2017-09-15 23:17:19 681

原创 4-5 基础堆排序和Heapify(两个版本的基于堆的排序算法)

1、第 1 个版本的基于堆排序的排序算法思路:借助最大堆这个数据结构,依次往里面放元素,然后再依次倒序取出。性能比较:100 万个元素。合并排序,快速排序,3路快速排序,堆排序1(1)随机(2)近乎有序(3)含有大量相同元素的数组堆排序的时间复杂度是 O(nlogn)。代码实现:/** * 第 1 个版本的堆排序算法 * Created by liwei on 17/5/15. */publ

2017-09-15 23:16:01 2335

原创 Python 爬虫模块 bs4 实战一:获取百度贴吧内容

getCommentInfo.py:from bs4 import BeautifulSoupimport requestsfrom mylog import MyLog as mylog# 《Python 网络爬虫实战》胡松涛著 P196class Item(): title = None firstAuthor = None firstTime = None

2017-09-15 20:10:23 1694

原创 4-4 Shift Down如何从堆中取出一个元素(对应优先队列中出队这个操作)

Shift Down 的具体操作步骤只能取出根节点处的元素,即第 1 个元素(索引为 1)。步骤:将最后一个元素放到第1个元素的位置,这样做交换和移动的次数最少,并且保持了完全二叉树的性质,但是此时并不满足最大堆的性质。(想清楚为什么要这么做)保持了完全二叉树的性质,但是此时 完全二叉树不满足最大堆的性质,我们就须要将第1 个元素逐层下移来进行判断。具体的步骤:如果存在右孩子,就把右孩子和左孩子比较

2017-09-15 08:02:00 1448

原创 《算法与数据结构》学习笔记 4-3 在最大堆中添加元素,Shift Up

这一小节,我们解决这样一个问题,向最大堆中添加一个元素,同时还要保持最大堆的性质,即根元素是堆中最大的元素。什么是 Shift Up?新加的元素,放在数组的末尾;进行一系列的操作维护最大堆的定义;新加入的元素调整元素的位置:只与父节点比较(不与兄弟孩子比较);如果比父节点大,就交换位置,否则,可以停止了,这个元素就放在当前位置。为什么要在数组的末尾添加一个元素呢?可不可以在开头、中间?首先

2017-09-14 23:24:16 1896

原创 4-2 堆的基本实现

时间复杂度是 O(nlogn) 级别的时间复杂度,它的形状一定看起来像是一棵树一样,所以堆在形式上就像一棵树一样。二叉堆 Binary Heap 的特点堆中某个节点的值总是不大于其父节点的值堆总是一棵完全二叉树(最大堆:顶上的元素是堆中所有元素的最大值)从形状上看,除了最后一层之外,其它层节点的数量应该是最大值,并且最后一层的节点应该集中在左侧。使用数组实现二叉堆因为最大堆是一颗完全二叉树,我

2017-09-14 23:23:41 444

原创 4-1 堆排序简介,为什么要使用堆

这一章开始我们介绍堆排序 Heap Sort。首先,我们应该认识到这样一个问题:O(nlogn) 比 O(n^2) 快多少?结论:快很多。理解这一步是我们理解算法重要性的基础。堆的非常典型的应用堆的一个典型的应用是优先队列(Priority Queue)。 普通队列 优先队列 先进先出,后进后出。由进入队列的时间顺序决定。 出队顺序与入队顺序无关,只与队列中元素的优先级有关,优先级最高

2017-09-14 23:15:30 4136

原创 3-9 归并排序和快速排序的衍生问题

O(nlogn)算法设计思想。归并排序和快速排序都使用了分治算法。归并排序:分没有太多考虑。快速排序:如何分,我们在分上花了很多时间。应用1:逆序对,使用归并排序的思路。应用2:取出数组中第 n 大的元素

2017-09-14 23:14:46 355

原创 3-8 三路快速排序法

三路快排在双路快排的基础之上,把与标定点元素等值的元素排在了数组的中间位置。比较从第 1 版的快速排序,到两个优化,再到指针对撞的快速排序,在到三路快速排序,它们在思路上的变化。三路快速排序的思路展示:代码实现:/** * 三路快速排序 * Created by liwei on 17/6/8. */public class QuickSortTest03 { @Test pu

2017-09-14 23:14:08 1320

原创 3-7 双路快速排序法

在有很多重复元素的情况下,放在中间的那个 j 的位置也会使得递归的过程变得很不平衡,这个时候我们也可以采取一定的优化措施。双路快速排序的思想有的时候又叫“指针碰撞”。双路快排的思想有点不好描述,还包括其中的一些细节,所以可以试着自己多写几遍,其实很好理解的。双路快排使得在有很多键值重复的情况下,重复的键值能够比较“均匀地”分布在数组的前后。Java 代码实现:public class QuickSo

2017-09-14 23:13:31 1239

原创 3-6 随机化快速排序法

优化角度1:在第 1 版快速排序的实现上,结合我们对第 1 版归并排序的讨论,我们可以知道:在待排序区间长度比较短的时候可以使用插入排序来提升排序效率,同样,我们使用 16 作为临界值。测试用例:近乎有序的数组,100万,归并排序,快速排序。优化角度2:因为快速排序的平衡度在近乎有序的时候会非常差,因此此时,递归的深度会增加。此时快速排序的算法就退化为 O(n^2)。解决办法,随机选择一个元素作为标

2017-09-14 23:12:32 417

原创 3-5 快速排序法

学习目标深刻理解 quick sort 的 partition 的过程才有可能做出很好的实现。快速排序在历史上的地位Quick Sort,一段对于快速排序的描述:可能是二十世纪最伟大的排序算法之一。我们首先先写一个基本的快速排序算法,后面我们再对这个基本的快速排序算法进行优化。快速排序第 1 版的思路从标定点后面一个一个地比较到底,(1)如果遇到比标定元素大的,就放过;(2)如果遇到比标定元素小的,

2017-09-14 09:45:54 533

原创 3-4 自底向上的归并排序算法

自底向上的归并排序下面我们使用一种全新的思路来实现归并排序算法。待排序的数组为,8,6,2,3,1,5,7,4。图:自底向上的归并排序算法以上我们使用的是“自顶向下”的归并排序,下面我们介绍“自底向上”的归并排序算法。我们并不须要递归调用,只须要迭代就可以了。下面展示了这种算法的一个框架。for(int size = 1;size,+n;size+=size){ // 1 个元素,2 个元素

2017-09-14 09:44:38 1177

原创 3-3 归并排序法的优化

3-3 归并排序法的优化本节介绍上一节实现的归并排序的两个优化:1、在 mergeOfTwoSortArray 对两个有序的数组进行归并的时候,如果两个数组合并之前就是有序的数组,就不用再复制来复制去的了;2、在归并的子过程中,如果待排序的数组元素个数很少的情况下,可以使用插入排序,因为插入排序对于近乎有序的数组而言,可以提前终止循环,从而提高整体排序的效率。下面我们具体来说明:1、归并排序写好以后

2017-09-14 00:02:14 479

原创 【算法日积月累】8-三路快排

归并排序算法的基本实现(第 1 版)在归并算法的学习中,我们第 1 次接触到递归算法的实现。第 1 版归并排序算法:下面我将一步一步展示在归并排序算法中,是如何编写递归函数的。第 1 步:先写出框架。我们对下标在 [0,length−1][0,length-1] ,左闭且右闭的这个区间里的元素使用递归的“归并排序”算法。/** * 第 1 步:写出归并排序的外层框架 */@Testpubli

2017-09-13 07:54:36 372

原创 【算法日积月累】7-两路快排

归并排序简介归并排序的一种实现方式是:将两个有序数组归并成一个更大的有序数组。归并排序的时间复杂度是 O(nlogn)。归并排序是我们接触的第 1 个时间复杂度为 O(logn) 级别的排序算法。归并排序的基本方法是递归,而且一层一层的递归总是均衡地“一分为二”进行的。

2017-09-13 07:43:59 446

原创 【算法日积月累】6-快速排序

(本节内容仅占位,具体内容待以后补充)。shell 排序实际上是插入排序的优化,shell 排序的代码一开始并不好理解,但是 shell 排序的思想是非常清晰的。shell 排序一次一次地把数组向着近乎有序的数组方向靠拢,直到近乎这件事情取了极限。

2017-09-13 07:43:01 371

原创 【算法日积月累】5-自底向上的归并排序

冒泡排序的基本思想1、相邻的两个元素进行比较,把比较大的元素排在后面,这样一轮循环下来,就可以找到这一轮循环中最大的那个元素,我们把这个过程形象地称之为“冒泡”。2、由于每一轮循环都“冒泡”出一个这一轮循环最大的元素,所以上一轮循环的最后一个元素,不应该参加下一轮循环的比较了,这就是为什么内层循环的结束条件是 j < arr.length -i -1 的原因了。代码实现:public class B

2017-09-13 06:58:38 551

原创 【算法日积月累】4-归并排序的 3 个优化角度

关于插入排序优化版的说明插入排序的优化版因为有赋值的操作,很可能出现的一种结果是,最后得到的数组是排序正确的,但是由于边界值,临界点的选择不对,导致数组的元素被更改。这一点要极为小心。因此,我们要注意,在我们的排序算法实现中不应该改变数组中的元素。这一点可能一开始看起来觉得是“理所当然”,然在我们真正去实现算法的时候,很可能会踩到这个坑。比较下面这两版插入排序:版本1:@Overridepubli

2017-09-13 06:56:14 400

原创 【算法日积月累】3-归并排序

问题来源在我们 “第 1 版”插入排序的版本中,内层循环多次交换元素这个过程其实是可以优化的。代码实现下面我们给出两种一模一样的针对插入排序的优化方案,供大家仔细比对:须要说明的地方:1、与原来的插入排序比,少了一系列交换元素的位置的操作,而是使用了一个临时变量先把这个元素存起来,然后依次与它前面元素比较,如果前面的元素大,就将前面的元素后移,然后再将这个临时存储起来的元素与再一个前面的元素比较,如

2017-09-13 06:53:09 542

原创 【算法日积月累】2-插入排序

插入排序算法第 1 讲插入排序的大体思路代码实现插入排序与选择排序比较插入排序算法第 1 讲插入排序的大体思路下面展示了插入排序的大体思想:由此,我们可以观察到插入排序算法的特点:每 1 次循环,都能保证红色部分(排好序的部分)的数组元素个数多 1 ,未排序的数组元素个数少 1。代码实现我们首先先给出插入排序的算法实现(第 1 版,Java 代码实现):Java 代码实现:/** * 插入排

2017-09-13 06:46:29 415

原创 【算法日积月累】1-选择排序

选择排序是一种最简单的排序算法。选择排序的简单描述选择排序的过程简而言之,就是不断地选择剩余元素之中的最小者。选择排序的外层循环在开始的时候总是认为第 1 个元素是最小的元素,这肯定是不对的,于是选择最小元素的索引的修订过程就在内层循环中完成,内层循环完成以后,与外层循环中的第 1 个元素交换位置。选择排序的过程简述如下:首先,在第 1 轮循环中找到数组中最小的那个元素,将它和数组的第 1 个元素交

2017-09-13 06:31:27 573

原创 第2章 排序基础

O(n^2)的算法虽然简单,但也实用!让我们从最简单的基础排序算法开始,打开我们的算法大门!作为算法的入门知识,排序的作用无疑是重要的,对于各种排序算法的学习,可以让我们体会到算法的威力,让我们知道算法无处不在,如果我们的工作中没有用到算法,我们是不是应该考虑一下重新定义我们的工作?在所有的算法中,O(nlogn) 复杂度的算法是最优算法,但 O(n^2) 级别的算法在一定程度下(例如在对近乎有序的

2017-09-13 06:30:43 343

原创 第1章 当我们谈论算法的时候,我们在谈论什么?

无论是BAT,还是FLAG,但凡有点儿水平的技术公司,面试都要面算法。为什么算法这么重要?在工作中,真的会使用算法吗?学了算法到底有什么用?当我们谈论算法的时候,我们在谈论什么? 《大话数据结构》第 1 章绪论结尾语 既然无数的人都已经掌握了《数据结构与算法》,你凭什么不行? 只有真正掌握技术的人,才有可能去享用它。 如果我们中途放弃了,之前所有的努力和付出都会变得

2017-09-13 06:29:27 1320

Eclipse插件之MyBatisLink

使用说明:Eclipse插件——MyBatisLink_百度经验 http://jingyan.baidu.com/article/922554468e2d6a851648f402.html

2015-03-28

myeclipse-svn-site-1.6.16.zip

该插件适用于MyEclipse8.6,欢迎下载使用,交流心得。

2013-09-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除