1.找列表的中点
可以使用快慢指针,一个指针步进1,另一个指针步进2。可用于数组或者链表。
对于数组
[1, 2, 3, 4]
i1 = 0; // 每次步进1
i2 = 0; // 每次步进2
// 第一次
i1 = 1;
i2 = 2;
if (i2 >= arr.length - 1) // 检查i2是否到达尾部,或者超过尾部
// 第二次
i1 = 2;
i2 = 4;
if (i2 >= arr.length - 1) // 检查i2是否到达尾部,或者超过尾部,因为arr.length = 4,所以已经出国了尾部,退出循环
i1 = 2 即使数组的中点。
| |
[1, 2, 3, 4]
再来看看奇数长度数组的情况
[1, 2, 3, 4, 5]
i1 = 0;
i2 = 0;
i1 = 1;
i2 = 2;
i1 = 2;
i2 = 4;
2.反转链表
1->2->3->4->null
4->3->2->1->null
我们需要将后面的指针保存下来就可以逐一的改变链接,用流程图表示一下:
用代码表示为:
public Node reserveList(Node head) {
Node prev = null;
Node node = head;
Node temp;
while (node != null) {
temp = node.next;
node.next = prev;
prev = node;
node = temp;
}
return prev;
}
3.位操作
3.1. n & (n - 1)
这个操作可以将n的二进制最右边的1消除。举个栗子,比如5,二进制位101,那么 5 & 4 会怎么样呢?
101
100
--------
100
最右侧的1被消去了。如果我们再来一遍。
100
011
--------
000
100最右侧的1被消去了,变成了0。
以上就是我对这个操作的直观理解,那么它有什么作用呢。
1.数一个数二进制有多少个1。
给我一个数,然后不停的让n & n - 1,再将结果赋值给n,并计数,判断啥时候n为0了,计数君就是1的个数了。
2.判断一个数字是否是2的幂。
2的幂在二进制上有个特点,就是100000…0000这种形式,那么只需要 n & n - 1,如果结果是0,那么它就是2的幂了。