《编程之美》第三章--结构之法
- 字符串移位包含的问题
若要判断s1=ABCDA是否通过循环移位包含字符串s2=CDAA,其实只需要判断字符串s1s1是否包含s2,一个小trick!相当于用空间换时间。
- 电话号码对应英语单词
手机上号码盘可以用来输入字母,如“2”可以输入A、B和C,这样给定一串数字,就可以通过循环给出这串数字所能表达的所有单词。书中主要介绍如何怎么遍历的问题,循环和递归两种方式。
- 计算字符串的相似度
对两个字符串进行修改、增加和删除操作,使之变得相同,通过此种方案计算它们的相似度。其实就是编辑距离啦~书中是以递归的形式进行的介绍,并且发现了递归程序中的重叠子问题,留给了读者后续完成---其实就是动态规划:-)
- 从无头单链表中删除结点
若…->A->B->C->D->…,给定指针为pCurrent, Node *pNext = pCurrent->Next
若给定的指针pCurrent指向B,即想要把B删除。直接删除B可以,但是找不到A,也就不能把A->B->C换成A->C,所以作证想到了一招狸猫换太子~~~威武!!
既然有B的指针,那么删除C是可以的,即用C的数据取代B的数据,最后删除C将B->C->D换成B->D,done!
pCurrent->Next=pNext->Next;
pCurrent->Data=pNext->data;
delete pNext;
- 最短摘要的生成
就是snippet是怎么生成出来的。作者的核心观点在下标的移动,如一篇文档S分词后可以表示为W[1..n],一个查询可以表示为Q[1..m],摘要就是要满足一个S的子串,其中包含Q中的所有元素,这就导致了遍历W时多次的重复查找,作者指出在第一次查找到满足全部查询的下标后,第二次的起始位置不是简单的index+1,而是上一次满足查询的第一个元素(是指在S中下标最小的那个位置)的index+1,这样就避免了重复查找,下标的跳转也很明显,提高了效率。
- 编程判断两个链表是否相交
最笨的方法是判断第一个链表的每个节点是否在第二个链表中,O(Length1 * Length2)
在最笨的基础上,可以将链表1映射为hash值,并排序,对链表2中每个元素映射并比较,复杂度为O(Length1+Length2)
转化思想后,若将第一个链表尾指向第二个链表头,则可将问题转换为是否存在圈;在这个转换的思想上,进一步思考,即若两个链表相交,那么最后一个节点一定是共有的,所以就转换为判断最后一个元素是否相同。
- 队列中取最大值操作问题
有待细看,不同数据结构实现同样的底层数据存储
- 求二叉树中节点的最大距离
距离最远的两个节点,一定是两个叶子节点,或者是一个叶子到它的跟节点。
转化为在子输上的解,动态规划解决!
- 重建二叉树
给定一颗二叉树的先序遍历和中序遍历结果,要求还原出该二叉树。
- 分层遍历二叉树