80 字 少于 1 分钟阅读

  1. 先判断边界条件,尤其注意 int 类型边界问题。
  2. 数据如果元素顺序对结果没有影响的话尝试先进行排序。
  3. 数组遍历的时候试一下倒序遍历,看是否比正序更好处理。
  4. 数组双层循环遍历使用双指针优化,双指针还可以尝试下同向、逆向、相向是否可行。
  5. 如果无思路就先想出暴力解法,再根据暴力解法进行优化。
  6. 递归尝试优化为迭代,使用循环处理。
  7. 链表操作尝试添加虚拟头结点可避免维护头结点的麻烦。
  8. Map 操作如果数据范围不大的话尝试改为数组,比如 26 个英文字母这样。
  9. 在使用异或操作交换数组元素时,会遇到传入两个下标相同的情况,这时异或操作实际上变成了a^=a;a^=a;a^=a;这时 a 的值会变成 0。解决方法:

     public static void swap(int[] arr,int i,int j){
         if(i==j) return;
         a[i]^=a[j];
         a[j]^=a[i];
         a[i]^=a[j];
     }
    
  10. 二叉树递归函数究竟什么时候需要返回值,什么时候不要返回值。 搜索一条边的写法:
    if (递归函数(root->left)) return ;
    if (递归函数(root->right)) return ;
    

    搜索整个树写法:

    left = 递归函数(root->left);   // 左
    right = 递归函数(root->right); // 右
    left  right的逻辑处理;        // 中
    

    在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)

    112. 路径总和
    113. 路径总和 II
    236. 二叉树的最近公共祖先

  11. 回溯算法数组先排序,注意剪枝,可以从元素数量和目标和两个维度进行剪枝。
  12. 如果把子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点
  13. 回溯树层去重树枝去重,数层去重不回溯。 491. 递增子序列
  14. 01背包压缩为一维数组的时候要倒序遍历背包。
  15. 完全背包 如果求组合数就是外层for循环遍历物品,内层for遍历背包如果求排列数就是外层for遍历背包,内层for循环遍历物品

    377. 组合总和 Ⅳ 322. 零钱兑换

  16. 动态规划的如果无思路就先定义 dp 数组表示以某个字符为结尾的目标值。