算法通关村——原来如此简单

1 层序遍历简介

广度优先遍历又叫做层次遍历,基本过程如下:
在这里插入图片描述

层序遍历就是从根节点开始先访问根节点下面一层全部元素,在访问之后的层次,类似金字塔一样一层层访问。我们可以看到这里就是从左到右一层一层的去遍历二叉树,先访问3,之后访问1的左右子孩子9和20,之后分别访问9和20的左右孩子[4,5]和[6.7],最后得到结果[3,9,20,8,13,15,17]。

这里的问题是怎么将遍历过得元素的子孩子保存一下呢,例如访问9时其左右孩子8和13应该先存一下,直到处理20之后才会处理。使用队列来存储能完美解决上述问题,例如上图的图中:

  1. 首先3入队。
  2. 然后3出队,之后将3的左右子孩子9和20 保存到队列中。
  3. 之后9出队,将9的左右子孩子8和13入队。
  4. 之后20出队,将28的左右子孩子15和7入队。
  5. 之后 8,13,15,7分别出队,此时都是叶子结点,只出队就行了。

2. 二叉树的层序遍历

leetcode102:二叉树的层序遍历

LeetCode102 题目要求: 给你一个二又树,请你返回其按层序遍历得到的节点值。(即逐层地,从左到右访问所有节点)。

二叉树:[3,9,2,null,null,15,7]
    3
   / \
  9  20
     / \
    15  7
返回其层序遍历结果:
[
  [3],
  [9,28],
  [15,7]
]

我们再观察执行过程图,我们先将根节点放到队列中,然后不断遍历队列。
在这里插入图片描述

那如何判断某一层访问完了呢? 简单,用一个变量size标记一下就行了size表示某一层的元素个数,只要出队,就将size减1,减到0就说明该层元素访问完了。当size变成0之后,这时队列中剩余元素的个数恰好就是下一层元素的个数,因此重新将size标记为下一层的元素个数就可以继续处理新的一行了,例如在上面的序列中:

1.首先拿到根节点3,其左/右子节点都不能为空,就将其左右放入队列中,因此此时3已经出队了,剩余元素9和20恰好就是第二层的结点,此时size=2。

2.继续将9从队列中拿走,size–变成1,并将其子孩子8和13入队。之后再将20出队,并将15和7入队,此时再次size–,变成9了。当size=0,说明当前层已经处理完了,此时队列有四个元素,而且恰好就是下一层的元素个数。

最后,我们把层序遍历到的结点都放入到一个结果集中,将其返回就可以了。

代码实现

public static List<List<Integer>> level102Order(TreeNode root) {
    if (root == null) {
        return new ArrayList<List<Integer>>();
    }

    List<List<Integer>> res = new ArrayList<List<Integer>>();
    LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
    //将根节点放入队列中,然后不断遍历队列
    queue.add(root);
    while (queue.size() > 0) {
        //获取当前队列的长度,这个长度相当于 当前这一层的节点个数
        int size = queue.size();
        ArrayList<Integer> tmp = new ArrayList<Integer>();
        //将队列中的元素都拿出来(也就是获取这一层的节点),放到临时list中
        //如果节点的左/右子树不为空,也放入队列中
        for (int i = 0; i < size; ++i) {
            TreeNode t = queue.remove();
            tmp.add(t.val);
            if (t.left != null) {
                queue.add(t.left);
            }
            if (t.right != null) {
                queue.add(t.right);
            }
        }
        //将临时list加入最终返回结果中
        res.add(tmp);
    }
    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RSA是一种非对称加密算法,由三位科学家Rivest、Shamir和Adleman共同发明,在加密和数字签名领域发挥着重要作用。RSA算法基于数论中的两个重要难题:大整数分解和模幂运算。 RSA算法的核心概念是公钥和私钥。在加密过程中,首先需要生成一对密钥,其中一个是公钥,可以公开给其他人使用,而另一个是私钥,必须保密。通过公钥可以将信息进行加密,而只有使用私钥才能解密。 RSA算法的加密过程如下:选择两个大素数p和q,并计算它们的乘积n=p*q作为所需的大整数。再选择一个与(p-1)*(q-1)互质的正整数e作为公钥,其中1 < e < (p-1)*(q-1)。然后计算d,满足(d*e) mod ((p-1)*(q-1)) = 1,并将d作为私钥。公钥对应着(n, e),私钥对应着(n, d)。 对于明文M,加密后得到密文C,加密过程为C = M^e mod n。解密过程为M = C^d mod n。由于大整数分解问题的复杂性,只有获得私钥才能成功解密,保护了通信的安全性。 RSA算法广泛应用于计算机网络和电子商务中,例如在网站上进行数据传输过程中,使用RSA加密算法保护数据的机密性和完整性,确保数据不被窃取或篡改。 需要注意的是,尽管RSA算法在安全性上相对较好,但其加解密过程消耗较大的计算资源,在处理大量数据时效率可能较低。因此,在实际应用中,常常将RSA与其他加密算法结合使用,以平衡安全性和效率的要求。 总之,RSA算法作为一种非对称加密算法,通过公钥和私钥的配对实现信息的加密和解密。它在数据安全领域的应用广泛,为保护通信和数据的安全做出了重要贡献。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值