1.arr[i]-arr[j] = (arr[i]-arr[i+1])+(arr[i+1]-arr[i+2])+......(arr[j-1]-arr[j])
该种转换应用:求最小正子串
2.arr[i]+arr[i+1]+....arr[j] = (arr[0]+arr[1]+......+arr[i])-(arr[0]+arr[1]+......+arr[j])
该种转换应用:求最大逆序对
3.递归的时候,特别注意某个子问题有没有重复计算,优化也是从这个角度入手。
应用:(1)计算字符串编辑距离,会出现重复计算;
(2)判断二叉树是不是平衡
注:o(n)=2o(n/2)+c => o(n)的时间复杂度
4.查找算法尽量往二分法、三分法上面靠(二分法适用于单调函数、三分法适用于凸函数)。当然有的需要额外的一些巧妙算法,例如寻找一个数组中出现次数为奇数的数。hash查找时间复杂度为o(1)。
5.linux计算动态优先级公式:
Dynamicy priority = max (100, min (static priority - bonus + 5, 139)) 。
6.在写代码的时候,尽量用一些比较安全的数据类型。例如:size_t、ptrdiff_t。
7.在《STL源码剖析》p61,第二级空间配置器中需要将内存量向上调至8的倍数,这样实现的:
enum{__ALIGN = 8};
static size_t ROUND_UP(size_t bytes){
return (((bytes)+ALIGN-1) &~(ALIGN-1));
}
8.+x和x++稍微有一点性能的差别。你如果对汇编比较熟悉,可以发现++x的汇编比x++要简洁一些。(海涛说的)
9.精炼的代码:while(n--)i++; ===>for(;n;--n,i++);//逗号的妙用
for(;begin<end;begin++,end++);
for(scanf("%d",&N);N;scanf("%d",&N))//for语句的妙用
10.只在内部使用的代码一般加上"__"前缀。
11.int count(int a,int);
int count(int a,float);
这时最后一个参数只声明了一个型别,并未指定参数名称,因为它纯粹是用来激活重载机制。
12.编写链表的时候不要忘了最后一个节点要赋值为“NULL”
13.在初始化结构器的时候,采用宏形式,恩不错。
- #define DEFINE_WAIT_FUNC(name, function) \
- wait_queue_t name = { \
- .private = current, \
- .func = function, \
- .task_list = LIST_HEAD_INIT((name).task_list), \
- }
这段代码也不错:
#define wait_event(wq, condition) \
do { \
if (condition) \
break; \
__wait_event(wq, condition); \
} while (0)
14.统计单词常用map、hash_map、trie树
15.那么怎样才能建立在整个类中都恒定的常量呢? 答案是使用 枚举常量
- class test
- {
- enum { SIZE1 = 100, SIZE2 = 200 };
- int array1[SIZE1];
- int array2[SIZE2];
- };
但是其存在一个缺点: 它的隐含数据类型是整数,其最大值有限,且不能表示浮点数
16.细细品位下面的代码
void Print(int n)
{
if(n<0)return;
cout<<n<<" ";
Print(n-1);
}
void Print1(int n)
{
if(n<0)return;
Print1(n-1);
cout<<n<<" ";
}
17.这段代码有意思
#if 0
#include<new>
#define _THROW_BAD_ALLOC throw bad_alloc
#elif !defined(_THROW_BAD_ALLOC)
#include<iostream>
#define _THROW_BAD_ALLOC cerr<<“out if memory”<<endl;exit(1);
#endif
18.为了避免浪费空间,STL源码free_list的采用链表结构
- union obj{
- union obj* free_list_link;
- char client_data[1];
- }