基本原理

0s 表示一串 0,1s 表示一串 1。

x ^ 0s = x      x & 0s = 0      x | 0s = x
x ^ 1s = ~x     x & 1s = x      x | 1s = 1s
x ^ x = 0       x & x = x       x | x = x
  • 利用 x ^ 1s = ~x 的特点,可以将位级表示翻转;利用 x ^ x

二分图

如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么这个图就是二分图。

1. 判断是否为二分图

785. Is Graph Bipartite? (Medium)

Input: [[1,3], [0,2], [1,3], [0,2]]
Output: true
Explanation:
The graph looks like this:
0----1
|    |
|    |
3----2
We can divide the vertices into two groups: {0, 2} and {1, 3}.
Example 2:
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
Explanation:
The graph looks like this:
0----1
| \  |
|  \ |
3----2
We cannot find a way to divide the set of nodes into two independent subsets.
public boolean isBipartite(int[][] graph) {
    int[] colors = new int[graph.length];
    Arrays.fill(colors, -1);
    for (int i = 0; i < graph.length; i++) {  // 处理图不是连通的情况
        if (colors[i] == -1 && !isBipartite(i, 0, colors, graph)) {
            return false;
        }
    }
    return true;
}

private boolean isBipartite(int curNode, int curColor, int[] colors, int[][] graph) {
    if (colors[curNode] != -1) {
        return colors[curNode] == curColor;
    }
    colors[curNode] = curColor;
    for (int 

1. 把数组中的 0 移到末尾

283. Move Zeroes (Easy)

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].Copy to clipboardErrorCopied
public void moveZ

1. 字符串循环移位包含

编程之美 3.1

s1 = AABCD, s2 = CDAA
Return : true

给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。

s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。

2. 字符串循环移位

编程之美 2.17

s =

哈希表使用 O(N) 空间复杂度存储数据,并且以 O(1) 时间复杂度求解问题。

  • Java 中的 HashSet 用于存储一个集合,可以查找元素是否在集合中。如果元素有穷,并且范围不大,那么可以用一个布尔数组来存储一个元素是否存在。例如对于只有小写字符的元素,就可以用一个长度为 26 的布尔数组来存储一个字符集合,使得空间复杂度降低为 O(1)。

  • Java 中的 HashMa

1. 用栈实现队列

232. Implement Queue using Stacks (Easy)

栈的顺序为后进先出,而队列的顺序为先进先出。使用两个栈实现队列,一个元素需要经过两个栈才能出队列,在经过第一个栈时元素顺序被反转,经过第二个栈时再次被反转,此时就是先进先出顺序。

class MyQueue {

    private Stack<Integer> in = n

递归

一棵树要么是空树,要么有两个指针,每个指针指向一棵树。树是一种递归结构,很多树的问题可以使用递归来处理。

1. 树的高度

104. Maximum Depth of Binary Tree (Easy)

public int maxDepth(TreeNode root) {
    if (root == null) return 0;
    return Mat

链表是空节点,或者有一个值和一个指向下一个链表的指针,因此很多链表问题可以用递归来处理。

1. 找出两个链表的交点

160. Intersection of Two Linked Lists (Easy)

例如以下示例中 A 和 B 两个链表相交于 c1:

A:          a1 → a2
                    ↘
                    

素数分解

每一个数都可以分解成素数的乘积,例如 84 = 22 * 31 * 50 * 71 * 110 * 130 * 170 * …

整除

令 x = 2m0 * 3m1 * 5m2 * 7m3 * 11m4 * …

令 y = 2n0 * 3n1 * 5n2 * 7n3 * 11n4 * …

如果 x

递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存了子问题的解,避免重复计算。

斐波那契数列

1. 爬楼梯

70. Climbing Stairs (Easy)

题目描述:有 N 阶楼梯,每次可以上一阶或者两阶,求有多少种上楼梯的方法。

定义一个数组 dp 存储上楼梯的方法数(为了方便讨论,数组下标从 1 开始),dp[i] 表示走到第

    Page 2 of 4