1、字符串移位包含问题:给定两个字符串s1和s2,要求判定s2是否被s1做循环移位得到
解法一:对s1进行移位,再进行判定
解法二:s1s1字符串包含了s1循环移位的所有可能性,只要检测s2是否为s1s1的子串即可,牺牲空间换时间。
解法三:不需要额外空间?解决这个问题。可以用指针的方法做到
- int ptr_contain(char *src, char *des){
- char *p = NULL;
- char *q = NULL;
- char *r = NULL;
- p = q = src;
- r = des;
- char *tmp = NULL;
- while(*p != '\0' )
- {
- while (*p != *r)
- p++;
- tmp = p;
- tmp++;
- while(*(++r) != '\0')
- {
- if(*(++p) == '\0')
- p = q;
- if(*r != *p)
- {
- r = des;
- p = tmp;
- break;
- }
- }
- if(*r == '\0')
- return 1;
- }
- return 0;
- }
2、电话号码对应英文单词,例如2对应abc,3对应def,输入一串数字,找到对应的单词。
解法一:构造排列树,将所有可能结果输出,然后跟单词集合比对
解法二:递归方法,找到所有可能的结果
解法三:将字典从单词转换为数字串,查询时只需要使用数字串跟数字词典进行比对,对于多次查询适应。
3、计算字符串的相似度,给定任意两个字符串,计算他们相似度。字符串距离
解法:将问题转化为小问题,如果两个字符串相同,则需要计算a[2,....n],b【2,...,n】的距离即可。若不同,则进行变换,删除a或b中的第一个字符串,或者修改a、b中的第一个字符串,或者增加字符。由于修改字符串或者增加字符串的行为可以理解为删除a或b的1个,或者两个都删除,因此只需计算一边删除一个,或者两个都删除。由此可以得到一个递程序。
为了减少计算,可以将计算结果保存在数组中
4、从无头链表中删除节点(不是第一个也不是最后一个)
解法:可以将下一个节点覆盖本节点,然后删去下一个节点
5、最短摘要生成
给定一个已经分好词的词语数组W[0]、W[1]、...,给定一个查询关键词数组Q[0],Q[1]...
解法一:从w中遍历,找到一个包含q的最短序列,记录长度,然后从w的第二个元素重新计算,复杂度O(N^2*M)
解法二:基于一的优化,不用每次向后移动一位,而是移到第一个q中元素出现的后面,然后移动尾指针,直到有一个在数列q中的元素出现
6、判断两个链表是否相交
--变形判断一个链表是否有环: 两个指针用不同的步长进行遍历,若有相交,则存在环
--找到这个环的起始点:两个指针交点一定在环上,从该交点断开环,就成了两个链表相交问题。
7、队列中取最大值操作问题
8、求二叉树中节点的最大距离
解法:两个距离最大的节点一定是叶子节点,可以采用动态划归的方法,先计算每个子树中距离最大的两个节点,并记录下他们的距离d1,以及其中深度最深的节点到子树根的距离h1,这个子树的父亲节点的最大距离为max{d1,d2,h1+h2+2},因为之需要遍历所有节点1次,因此复杂度为O([V]– 1)V是点的集合.
定义的节点信息中保存了左右子树的最长距离,使用全局变量记录最长节点距离。
优化:以上解法有三个缺点:1、加入侵入式数据,即每个节点多加入的信息量:左右节点最长距离. 2、使用全局变量,使得多个线程无法同时计算。3、代码复杂,条件判断多
改进,设计独立的结构,保存每个子树的最长深度,和最大节点距离,然后在计算长度的函数中返回这个结构体。
#include <iostream>
using
namespace
std;
struct
NODE
{
NODE *pLeft;
NODE *pRight;
};
struct
RESULT
{
int
nMaxDistance;
int
nMaxDepth;
};
{
if
(!root)
{
RESULT empty = { 0, -1 };
// trick: nMaxDepth is -1 and then caller will plus 1 to balance it as zero.
return
empty;
}
RESULT lhs = GetMaximumDistance(root->pLeft);
RESULT rhs = GetMaximumDistance(root->pRight);
RESULT result;
result.nMaxDepth = max(lhs.nMaxDepth + 1, rhs.nMaxDepth + 1);
result.nMaxDistance = max(max(lhs.nMaxDistance, rhs.nMaxDistance), lhs.nMaxDepth + rhs.nMaxDepth + 2);
return
result;
}
9、重建二叉树
10、分层遍历二叉树
使用游标记录每一层的开始和结尾,这样就不需要额外开辟空间,记录每一个点所在层次。也可以选择在队列中插入元素作为分隔
11、程序改错
注意:程序mid= (max+min)/2,有可能因为max+min导致溢出,可以写成min= min + (max-min)/2
二分查找,循环结束的条件应该为min<max-1否则可能进入死循环,例如2和3