您的位置:首页 > 其它

一些算法思想

2014-04-23 00:52 148 查看
关于解算法题,一定不要漫无边际,一定要有所依托,一定是个收敛的过程。如何收敛思路而不是不漫无边际?思考的起点是什么?答曰,脚踏实地,从实地起,有所依托,纲举目张。依托的是什么,纲举目张的纲是什么?——关键变量。算法的主体就是变量、数据。首先有题目给出的输入参数和返回值,这就是最初的依托,纲。然后看自己需要定义什么变量。这就是思考的起点,算法有哪些主体、player(变量、数据)?这是第一个要问的问题。

           接着,初始化,这些变量的初始化状态应该是什么?

           第三,算法本身,一般会是个循环,分为循环体,也就是每次循环执行的逻辑是什么,这是固定的部分,还是有就是循环条件,这是变化的部分。要问,固定不变的是什么?变化的是什么?

一些应该正确做法:(精神就是:尽量方便自己,别自找麻烦)

1能画图先画图,别在脑子里干想。比如任何链表题,先花个几秒钟画个3、4个节点的链表,一点也不费事。然后对着具体图,推演scenario 、看边界情况,容易多了。

2找规律时候从一个具体的情况入手,先画出一种具体case,基于这种情况得出一个算法,然后在看看有没有别的情况,加个if分支就能解决的事。不要一开始就从最一般的抽象开始考虑给自己加难度。。

3. 先处理特殊、边界情况。

 

循环和递归

算法的主体必然是循环或者递归,二者本质上都是一种重复,只是形式不同。循环的循环体就相当于递归函数的函数体,循环变量相当于递归函数的参数。当然,除了循环变量,递归参数,还有全局变量。每次重复就是围绕这些变量,依赖这些变量,进行判断,更新状态。——这就是算法。关于算法框架,要这么进行思考:每次循环重复什么操作?需要什么变量?

 

一、字符串算法思想

1.从一个字符串中删去多个字符

1) 字符条件:比如另一字符串中,重复,等等,map法,o(1)

2) 怎么删?在字符串的空间重新写字符串法,两个指针,i, j。i代表新串下一个位置的指针,j代表旧串的指针

2 调整字符串/数组

把奇数排在偶数前面,非零排在前面等等。

依然是同一空间重写法,新旧两个下标。

 

二、二叉树的算法思想

一般就是2个思路

1.    基于遍历,变化的只是“访问该节点”时候算法不同,也就是对数据的用法不同,比如可以是:

1)直接使用节点值,判断是否满足某条件;

2)使用衍生数据,

比如累加和,算法使用累加和,

   累加路径长度level,算法使用路径长度

   保存当前路径vector, 算法使用路径vector

算法条件一般也就是

1) 判断是否等于给定值

2) 是否是遍历过程中该值的最大者

基于遍历的算法操作的数据,比如累加和、路径长度、当前路径vector,是每次递归调用之间共享的,所以都是全局变量,算法就是操作全局数据,结果就是遍历结束后全局变量的状态,所以一般不存在返回值。如果需要以返回值的形式给出结果,可以用一个static变量保存,每次返回该值,但只有最外层返回给调用者那次是有意义的,中间递归调用不需要得到返回值。

2.    基于递归思想(当前结果和左右子树上的结果有一定关系),比如求深度,求叶子数,判断二叉树是否平衡,这种都是有返回值的。

1) 先求解左右子树上的结果

2) 基于左右子树上的结果,计算当前树上的结果。

 

专题1: 二叉树上的基于遍历的路径相关的算法(求解满足某条件的路径)

1) 处理为空的情况,一般就是直接return

2) 把当前节点append到路径vector curPath,累加和curSum加入当前节点值

3) 判断是否是否满足算法条件,若满足,打印或者保存

4) 如果需要继续遍历(未找到)对左右子树应用本算法

5) 把当前节点从路径vectorcurPath 中移除,累加和排除当前节点值

 

 

专题二:层次遍历

关键是如何知道层的结束

方案一:基于end, 不需要算层的结点数

维护变量: 队列queue,  层level, 当前level的最后一个节点end,

初始状态,root进队,level =0;  end = root;

算法:当队列不为空:

1) 出队,访问该节点,

2) 左右孩子进队(如果有的话)

3) 判断是否是end, 如果是, level++ , end = 当前队尾

方案二:基于计算每一层节点数,

维护变量:队列queue, 层level, 当前层节点数curNum, 下一层节点数nextNum

初始状态: root进队,level =0,curNum =1 (root),nextNum=0;

算法:当队列不为空:

1) 出队,curNum--, 访问该节点

2) 左右孩子进队(如果有的话),并且nextNum++计数

3) 判断是否是层结束,即curNum==0,如果是,level++, curNum=nextNum,  NextNum=0;

三、位运算基本公式

1取第i位值: ( n >>i ) & 1

1) 把第i位移到个位。

2) 和1与,抹掉其他位。

2对第i位取反:   n ^ (1 << i )  跟1异或就是取反

1)    1左移i位

2)    做异或

3 对第i位赋值:

1) 取第i位值

2) 跟输入值比较,相等什么也不用做,如果不相等,对第i位取反
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法