算术
- x / y 向上取整:
(x + y - 1) / y
进制
- 判断一个数的奇偶性:i&1==0 则 i 为偶数,i&1==1 则 i 为奇数;
- 计算整数i的二进制形式中1的个数
其中一种比较高效的方法是每次用“i&(i-1)”将整数i的最右边的1变成0。整数i减去1,那么它最右边的1变成0。如果它的右边还有0,则右边所有的0都变成1,而其左边所有位都保持不变。下面对i和i-1进行位与运算,相当于将其最右边的1变成0。以二进制的1100为例,它减去1的结果是1011。1100和1011的位与运算的结果正好是1000。二进制的1100最右边的1变为0,结果刚好就是1000。
- 判断两个数是否相等:a&b==0
- 进制运算

左移运算符m<<n表示把m左移n位。如果左移n位,那么最左边的n位将被丢弃,同时在最右边补上n个0。具体示例如下:00001010<<2=0010100010001010<<3=01010000右移运算符m>>n表示把m右移n位。如果右移n位,则最右边的n位将被丢弃。但右移时处理最左边位的情形比较复杂。如果数字是一个无符号数值,则用0填补最左边的n位。如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说,如果数字原先是一个正数,则右移之后在最左边补n个0;如果数字原先是一个负数,则右移之后在最左边补n个1。下面是对8位有符号数值(Java中的byte型整数)进行右移的例子:00001010>>2=0000001010001010>>3=11110001Java中增加了一种无符号右移位操作符“>>>”。无论是对正数还是负数进行无符号右移操作,都将在最左边插入0。下面是对Java中byte型整数进行无符号右移操作的例子:00001010>>>2=0000001010001010>>>3=00010001其他编程语言(如C或C++)中没有无符号右移位操作符。
- 按位异或
- mid 为奇数时,mid - 1 = mid ^ 1
- mid 为偶数时,mid + 1 = mid ^ 1
数组
- 双指针
如果数组中的数字有正数、负数和零,那么双指针的思路并不适用,这是因为当数组中有负数时在子数组中添加数字不一定能增加子数组之和,从子数组中删除数字也不一定能减少子数组之和。
- 累加数组数字求子数组之和
字符串
如果两个字符串包含的字符及每个字符出现的次数都相同,只是字符出现的顺序不同,那么它们就是一组变位词。通常可以用一个哈希表来统计每个字符出现的次数,有了哈希表就很容易判断两个字符串是不是一组变位词。
回文是一类特殊的字符串。不管是从前往后还是从后往前读取其每一个字符,得到的内容都是一样的。通常可以用两个指针来判断一个字符串是不是回文,要么两个指针从字符串的两端开始向中间移动,要么两个指针从中间开始向两端移动。
链表
链表中环的切入点
假设快慢指针相遇时,慢指针slow走了k步,那么快指针fast一定走了2k步

fast一定比slow多走了k步,这多走的k步其实就是fast指针在环里转圈圈,所以k的值就是环长度的「整数倍」
假设环的起点到相遇点的距离为m,见下图,环的起点距头结点head的距离为k - m,也就是说如果从head前进k - m步就能到达环起点。
如果从相遇点继续前进k - m步,也恰好到达环起点。因为结合上图的 fast 指针,从相遇点开始走k步可以转回到相遇点,那走k - m步肯定就走到环起点了
只要我们把快慢指针中的任一个重新指向head,然后两个指针同速前进,k - m步后一定会相遇,相遇之处就是环的起点了

取链表的中点位置
取两个指针为 slow 和 fast,slow 每次走一步,fast 每次走两步。
tip:当节点的个数为奇数时,slow 要比 fast 多一个,偶数则平分。
time 在 between start and end
newEnd > start and newStart < end
