【算法】一些刷题心得

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、二进制
    • 1.获取最后一位二进制数
  • 二、树
    • 1.中序遍历迭代
  • 三、数组/哈希
    • 1.原地哈希


前言

刷题也有好一段时间了,总感觉做的还没有忘的多,还是需要做个笔记来记载一些算法中的技巧和模板。
佛系更新


一、二进制

1.获取最后一位二进制数

n & 1

这个方法在二进制类型的题中还蛮常用的,经常搭配位移操作在循环中使用。

例子:

int num = 10;    // 二进制形式 1010
num = num & 1;   // 0,可以看到最后一位二进制数确实为0

int num = 3;     // 二进制形式 11
num = num & 1;   // 1,最后一位二进制数为1

原理:
主要是通过与运算的特性:遇0变0(我不是),全1为1
而1的二进制为0001,那么可知,无论num的二进制前n-1位为多少都一样,都会被0001的前缀0给变为0,所以只需要判断最后一位的二进制位。

二、树

1.中序遍历迭代

中序遍历的递归版本对于大多数人来说应该还是蛮简单的,但是有时转换为迭代版本时总是会卡壳,直接给迭代版本的代码。

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Deque<TreeNode> stk = new LinkedList<TreeNode>();
        while (root != null || !stk.isEmpty()) {
            // 一直向左推进
            while (root != null) {
                stk.push(root);
                root = root.left;
            }
            root = stk.pop();
            res.add(root.val);
            // 向右试探
            root = root.right;
        }
        return res;
    }
}

一看就懂,一做就忘
我的想法是可以从递归的版本来开始理解

// 递归版本
find(root.left);
print(root.val);
find(root.right);

可知道,中序是优先满足左子树,然后满足自己,再去想想右子树。
迭代也是这么个想法,优先去满足左子树,只要有就将左子树加入栈中,然后打印自己的值,最后往右看看。

三、数组/哈希

1.原地哈希

将元素放到同样的元素索引下,比如把3放到索引为3的位置,目的是以索引的存在来标识元素的存在,比如索引2的位置标志为真,那么说明在原来的数组存在元素2,所以当我们想知道元素的存在就可以转换为索引的存在,查找复杂度从O(n)转换为O(1)【算法】一些刷题心得_第1张图片
图片来源于leetcode 41题,重点在最后两行

如果按照正常思想,从左往右遍历,【3放到索引2,4放到索引3】,此时轮到1时,就不知道原来索引为3的地方有个1,覆盖了信息

所以图中展示了一种方式,将元素转化为对应值的负数,那么在中途可以通过取绝对值的方式查看覆盖前的信息,相当于此时保存了两类信息,转换前转换后的数据


学习要有输入,也要有输出,输出也是为了再一次顺利的输入,人是有极限的。

你可能感兴趣的:(java,算法,数据结构)