【算法刷题 DAY04】剑指offer树3和队列与栈总结

news2024/11/18 22:29:19

JZ36 二叉搜索树与双向链表

描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

img
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构

解题思路:

  • 首先对二叉树进行中序遍历,把遍历到的每一个结点都保存到队列中。

  • 然后将第一个元素出队,使用head指针始终指向链表的第一个元素。让pre指针初始化为pre=head。

  • 然后开始循环遍历队列,每出队一个元素,就进行相关的链接操作,知道队列中没有元素为止。

public TreeNode Convert(TreeNode pRootOfTree) {
    // 当结点为空当时候
    if (pRootOfTree == null)
      return null;

    // 中序遍历结点,并将结点存入到队列中
    Queue<TreeNode> queue = new LinkedList<>();
    // 中序遍历
    inorder(pRootOfTree, queue);
    // 从队列中先取出一个结点
    TreeNode head = queue.poll();
    TreeNode pre = head;

    // 循环队列
    while (!queue.isEmpty()) {
      // 取出元素
      TreeNode cur = queue.poll();
      pre.right = cur;
      cur.left = pre;
      pre = cur;
    }
    return head;
}

private void inorder(TreeNode root, Queue<TreeNode> queue) {
    if (root == null)
      return;
    inorder(root.left, queue);
    queue.offer(root);
    inorder(root.right, queue);
}

JZ8 二叉树的下一个结点

描述
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示

img

示例:

输入:{8,6,10,5,7,9,11},8

返回:9

解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来

img

解题思路

  • 首先根据传入结点中的指向父结点的指针,一直向上查找,最终可以查找到二叉树的根结点。
  • 然后对二叉树进行中序遍历,并将结点保存到队列中
  • 遍历队列,每次出队都和传入元素的进行比较,如果相等,则返回目前队列中的第一个元素即可。
public TreeLinkNode GetNext(TreeLinkNode pNode) {
    // 根据传入的结点,通过指向父结点的指针,一直找,最终可以找到这个二叉树的根结点
    if(pNode == null) return null;
    TreeLinkNode root = pNode;
    // 查找根结点
    while (root.next != null) root = root.next;
    Queue<TreeLinkNode> queue = new LinkedList<>();
    // 然后二叉树进行中序遍历,将遍历到的结点保存到队列中
    inorder(root, queue);
    // 循环队列中元素,找到输入元素的下一个元素,然后将结点返回即可
    while (!queue.isEmpty()) {
      TreeLinkNode poll = queue.poll();
      if (poll.val == pNode.val)
        return queue.poll();
    }

    return null;
}

private void inorder(TreeLinkNode root, Queue<TreeLinkNode> queue) {
    if (root == null)
      return;
    inorder(root.left, queue);
    queue.offer(root);
    inorder(root.right, queue);
}

JZ68 二叉搜索树的最近公共祖先

描述

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

1.对于该题的最近的公共祖先定义:对于有根树T的两个节点p、q,最近公共祖先LCA(T,p,q)表示一个节点x,满足x是p和q的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先.

2.二叉搜索树是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值

3.所有节点的值都是唯一的。

4.p、q 为不同节点且均存在于给定的二叉搜索树中。

如果给定以下搜索二叉树: {7,1,12,0,4,11,14,#,#,3,5},如下图:

img

示例1

输入:

{7,1,12,0,4,11,14,#,#,3,5},1,12

复制

返回值:

7

复制

说明:

节点1 和 节点12的最近公共祖先是7   

示例2

输入:

{7,1,12,0,4,11,14,#,#,3,5},12,11

复制

返回值:

12

复制

说明:

因为一个节点也可以是它自己的祖先.所以输出12   

解题思路1:利用循环

考虑到二叉搜索树的性质,比根小的元素都在左子树,比根大的元素都在右子树上。因此我们可以根据p,q的大小来判断两个结点的位置

  • 当p<root, q<root时,说明两个结点都在root的左子树上,那么应该让root = root.left,然后继续以root.left为根搜索公共祖先
  • 当p>root, q>root时,说明两个结点都在root的右子树上,那么应该让root = root.right,然后继续以root.right为根搜索公共祖先
  • 当p<root, q>root时,说明两个结点位于root的左右子树上,那么最近公共结点就是root
public int lowestCommonAncestor (TreeNode root, int p, int q) {
    // write code here
    if (root == null) return 0;

    while (root != null) {
      if (p < root.val && q < root.val)
        root = root.left;
      else if (p > root.val && q > root.val)
        root = root.right;
      else
        return root.val;
    }
    return 0;
}

解题思路2(利用中序遍历):可以利用中序遍历,从而记录从根结点到p,q的路径。路径中最后一个相同的结点就是最近的公共祖先。

比如说上面那个树,查找结点12和结点11的最近公共祖先。

结点11的路径是{7, 12, 11} 结点12的路径是{7, 12} 那么这两个序列中最后重复的元素就是12,那么12就是最近公共祖先。

public int lowestCommonAncestor(TreeNode root, int p, int q) {
    // 通过层序遍历记录到p, q结点的路径
    if (root == null) return 0;

    // 创建两个队列
    Queue<TreeNode> nodeQ = new LinkedList<>();
    Queue<ArrayList<Integer>> pathQ = new LinkedList<>();
    ArrayList<ArrayList<Integer>> pathList = new ArrayList<>();

    // 根结点入队
    nodeQ.offer(root);
    pathQ.offer(new ArrayList<>(Arrays.asList(root.val)));

    // 开始遍历
    while (!nodeQ.isEmpty()) {
      // 出队
      TreeNode node = nodeQ.poll();
      ArrayList<Integer> currentPath = pathQ.poll();

      if (node.val == p || node.val == q) {
        pathList.add(currentPath);
      }

      // 判断左右子树
      if (node.left != null) {
        nodeQ.offer(node.left);
        ArrayList<Integer> left = new ArrayList<>(currentPath);
        left.add(node.left.val);
        pathQ.offer(left);
      }

      if (node.right != null) {
        nodeQ.offer(node.right);
        ArrayList<Integer> right = new ArrayList<>(currentPath);
        right.add(node.right.val);
        pathQ.offer(right);
      }
    }

    // 遍历结束后pathList中保存的就是从根到p, q的路径
    ArrayList<Integer> list1 = pathList.get(0);
    ArrayList<Integer> list2 = pathList.get(1);

    // 遍历两个路径
    int i = 0, j = 0;
    int ret = 0;
    while (i < list1.size() && j < list2.size()) {
      if (list1.get(i) == list2.get(j))
        ret = list1.get(i);
      i++;
      j++;
    }

    return ret;
}

第二个方法实际上并没有利用到二叉搜索树的一些特殊性质,直接是按照二叉树的性质来做的。所以第二种方法同时适用于求二叉树中两个结点的最近公共祖先。如下面这道题所示。

JZ86 在二叉树中找到两个节点的最近公共祖先

描述

给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足 1 \le n \le 10^5 \1≤n≤105 , 节点值val满足区间 [0,n)

要求:时间复杂度 O(n)O(n)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

img

所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。

节点本身可以视为自己的祖先

解题思路1(利用中序遍历):可以利用中序遍历,从而记录从根结点到p,q的路径。路径中最后一个相同的结点就是最近的公共祖先。

比如说上面那个树,查找结点12和结点11的最近公共祖先。

结点11的路径是{7, 12, 11} 结点12的路径是{7, 12} 那么这两个序列中最后重复的元素就是12,那么12就是最近公共祖先。

public int lowestCommonAncestor(TreeNode root, int p, int q) {
    // 通过层序遍历记录到p, q结点的路径
    if (root == null) return 0;

    // 创建两个队列
    Queue<TreeNode> nodeQ = new LinkedList<>();
    Queue<ArrayList<Integer>> pathQ = new LinkedList<>();
    ArrayList<ArrayList<Integer>> pathList = new ArrayList<>();

    // 根结点入队
    nodeQ.offer(root);
    pathQ.offer(new ArrayList<>(Arrays.asList(root.val)));

    // 开始遍历
    while (!nodeQ.isEmpty()) {
      // 出队
      TreeNode node = nodeQ.poll();
      ArrayList<Integer> currentPath = pathQ.poll();

      if (node.val == p || node.val == q) {
        pathList.add(currentPath);
      }

      // 判断左右子树
      if (node.left != null) {
        nodeQ.offer(node.left);
        ArrayList<Integer> left = new ArrayList<>(currentPath);
        left.add(node.left.val);
        pathQ.offer(left);
      }

      if (node.right != null) {
        nodeQ.offer(node.right);
        ArrayList<Integer> right = new ArrayList<>(currentPath);
        right.add(node.right.val);
        pathQ.offer(right);
      }
    }

    // 遍历结束后pathList中保存的就是从根到p, q的路径
    ArrayList<Integer> list1 = pathList.get(0);
    ArrayList<Integer> list2 = pathList.get(1);

    // 遍历两个路径
    int i = 0, j = 0;
    int ret = 0;
    while (i < list1.size() && j < list2.size()) {
      if (list1.get(i) == list2.get(j))
        ret = list1.get(i);
      i++;
      j++;
    }

    return ret;
}

JZ9 用两个栈实现队列

描述

用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。

解题思路:

  • 对于入队,只需要将元素保存到stack1中即可
  • 对于出队,首先需要判断一下stack2中是否有元素,如果有元素,则返回栈顶元素即可;如果stack2中没有元素,则需要将stack1中所有元素存入stack2,然后从stack2中弹出一个元素即可。
public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int node) {
        // 入队 就是向stack1中入栈即可
        stack1.push(node);
    }

    public int pop() {
        // 判断stack2中是否有元素
        // 如果有元素,则直接从stack2中出栈一个元素即可
        if (stack2.size() > 0) {
            return stack2.pop();
        }
        // 如果没有元素,则从将stack1中的元素全部压入stack2 然后从stack2中出栈一个元素
        while (!stack1.isEmpty()) {
            // 将stack1中数据保存到stack2
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
}

JZ30 包含min函数的栈

描述

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。

解题思路1:在计算栈中元素最小值的时候,依次遍历栈中所有元素,将元素保存到list中。等遍历完毕后,将list求逆序列。然后在循环list,依次保存到stack中。这种方法时间和空间复杂度都很高。这道题的本意肯定不是这样做。但是可以AC。

public class Solution {
    private Stack<Integer> stack = new Stack<>();

    public void push(int node) {
        stack.push(node);
    }

    public void pop() {
        stack.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int min() {
        ArrayList<Integer> list = new ArrayList<>();
        Integer min = Integer.MAX_VALUE;
        while (!stack.isEmpty()) {
            Integer pop = stack.pop();
            if (pop < min) {
                min = pop;
            }
            list.add(pop);
        }
        Collections.reverse(list);
        for (Integer integer : list) {
            stack.push(integer);
        }
        return min;
    }
}

**解题思路2:**利用两个栈来解决。一个栈就是正常的栈,另一个栈用来保存最小值

  • 入栈:stack1正常入栈,stack2需要判断。如果stack2中没有元素则直接入栈。如果有元素,则需要判断stack2的栈顶元素是否大于输入元素,如果满足条件,则stack2也入栈。
  • 出栈。stack1正常出栈,如果此时stack1中出栈元素等于stack2的栈顶元素,那么stack2也出栈
  • min:stack2的栈顶元素始终是stack1中的最小值。
public class Solution {
    private Stack<Integer> stack1 = new Stack<>();
    private Stack<Integer> stack2 = new Stack<>();

    public void push(int node) {
        // stack1正常入栈
        stack1.push(node);
        // 判断stack2中是否有元素
        if (stack2.isEmpty()) {
            // 为空则直接入栈
            stack2.push(node);
        }
        // 如果不为空,则需要判断stack2的栈顶元素是否小于等于node
        if (stack2.peek().intValue() >= node) {
            stack2.push(node);
        }
    }

    public void pop() {
        if (stack1.peek().intValue() == stack2.peek().intValue()) {
            stack2.pop();
        }
        stack1.pop();
    }

    public int top() {
        return stack1.peek();
    }

    public int min() {
        return stack2.peek();
    }
}

JZ73 翻转单词序列

描述

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“nowcoder. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a nowcoder.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

解题思路1:

  • 利用字符串分割函数,将字符串分解为一个一个的单词组成的数组。
  • 从数组末尾到数组头开始遍历,使用StringBuilder构建字符串。构建过程中需要加空格,最后一个元素不需要加空格。
  • 最终返回即可
public String ReverseSentence(String str) {
    if ("".equals(str))
      return "";
    // 使用空格划分单词
    String[] words = str.split(" ");
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = words.length - 1; i >= 0; i --) {
      stringBuilder.append(words[i]);
      if (i == 0)
        continue;
      stringBuilder.append(" ");
    }
    return stringBuilder.toString();
}

解题思路2(利用栈):实现顺序反转可以使用栈。

  • 利用字符串分割函数,将字符串分解为一个一个的单词组成的数组。
  • 将数组每一个元素入栈。每一个单词入栈以后,在入栈一个空格。
  • 循环出栈之前,先将最后添加的那个空格删除掉。
  • 出栈,使用StringBuilder构建字符串。
public String ReverseSentence(String str) {
    if ("".equals(str)) return "";
    Stack<String> stack = new Stack<>();
    String[] words = str.split(" ");
    for (String word : words) {
      stack.push(word);
      stack.push(" ");
    }
    // 移除栈顶的空格
    stack.pop();

    StringBuilder stringBuilder = new StringBuilder();
    while (!stack.isEmpty()) {
      stringBuilder.append(stack.pop());
    }
    return stringBuilder.toString();
}

JZ31 栈的压入、弹出序列

描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

注意:同时满足压入和弹出序列的情况只有一种

解题思路:

建立一个辅助栈,遍历入栈序列。每遍历一个元素,就入栈。

元素入栈后,需要判断一下栈顶元素是否和popA中指定位置的元素相同,如果相同,则元素出栈。

整个循环结束后,如果栈中还有元素,说明不满足条件。

public boolean IsPopOrder(int [] pushA,int [] popA) {
    if (pushA == null || pushA.length == 0)
      return false;

    Stack<Integer> stack = new Stack<>();
    int k = 0;
    // 遍历入栈序列
    for (int i = 0; i < pushA.length; i++) {
      // 入栈
      stack.push(pushA[i]);
      // 判断栈顶元素是否和popA中元素相同
      while (!stack.isEmpty() && stack.peek() == popA[k]) {
        stack.pop();
        k++;
      }
    }
    return stack.isEmpty();
}

image-20230112221926760

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科新闻 | 虹科与weeve正式建立合作伙伴关系

近日&#xff0c;虹科与weeve正式建立合作伙伴关系&#xff0c;双方就工业应用自动化领域进行深入的交流与合作&#xff0c;未来将共同致力于为中国市场提供完整的物联网边缘服务解决方案&#xff0c;解决中国客户的物联网挑战。 虹科与weeve都表示十分期待这次的合作。“虹科…

day36【代码随想录】贪心算法之根据身高重建队列、用最少数量的箭引爆气球、无重叠区间

文章目录前言一、根据身高重建队列&#xff08;力扣406&#xff09;二、用最少数量的箭引爆气球&#xff08;力扣452&#xff09;三、无重叠区间&#xff08;力扣435&#xff09;前言 1、根据身高重建队列 2、用最少数量的箭引爆气球 3、无重叠区间 一、根据身高重建队列&…

魔改插线板,让电视控制周边设备开关机

一.我的需求 本人是一个极简主义风格的人&#xff0c;自从用了N1盒子刷了coreELEC 系统后&#xff0c;就不断的进行折腾&#xff0c;跟大家说下我的心路历程。 1.我家很少看电视&#xff0c;不想因为偶尔开一次电视就每个月交24块钱&#xff0c;所以把广电的机顶盒停掉了。 2.电…

TextView

1.简介 向用户显示文本的用户界面元素。 2.常见使用 2.1 设置文本内容 //xml 硬编码 <TextView android:text"文本"/> //xml 推荐放在string.xml,为了国际化考虑 <TextView android:text"string/app_name"/> //kotlin tv.text getStr…

零基础学员的shell脚本的写作思路详解

前言 这两天一直再批改学员的脚本作业&#xff0c;大多数学员写的很好&#xff0c;有的学员写的不太好。 还有一些还没有入门到学员不知道脚本该咋写。 不知道脚本怎么写的学员&#xff0c;绝大多数犯了一个错误&#xff1a;一上来就把脚本想的太复杂了。 我们今天单独聊聊这…

以研究用途搭建OpenStreetMap Virtualbox服务器

又到了新年伊始&#xff0c;下载OpenStreetMap全球数据的时候了。结果惊奇的发现&#xff0c;主站已经无法打开。仔细了解了原委&#xff0c;表示理解。好在PBF数据依旧可以获取&#xff0c;只是瓦片服务已经关停。 1.OpenStreetMap的主要问题 OpenStreetMap之所以被Blocked&…

力扣刷题记录——459.重复的字符串、461. 汉明距离、476. 数字的补数

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《459.重复的字符串、461. 汉明距离、476. 数字的补数》。…

Mysql数据库中的表

创建表 和之前的创建库差不多&#xff0c;需要多指定一个engine&#xff08;不写默认INNODB&#xff09;这个后面说 字符集还有校对规则不指定的话和库的保持一致 案例 图形化创建就不说了&#xff0c;主要就指令 # 演示关于创建表的操作 # 在db02创建表USER包含id-整形 name…

(9)go-micro微服务Redis配置

文章目录一 go-redis介绍二 go-redis安装三 redis初始化连接四 存储mail邮件五 存储token六 最后一 go-redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库…

【验证码逆向专栏】某验二代滑块验证码逆向分析

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 本文章未经许可禁止转载…

svn安装与配置并集成

svn安装 客户端安装与下载 下载地址&#xff1a;https://tortoisesvn.net/downloads.zh.html 根据自身设备情况下载 1、更换安装路径&#xff0c;点击next&#xff08;如果安装路径选择不了那么先点击next在点击back就可以选择安装路径了&#xff09; 2、如果需要集成idea在下…

详解“陌生的“位段

目录 一、什么是位段&#xff1f; 二、位段的内存分配 三、位段的应用 一、什么是位段&#xff1f; C 语言允许一个结构体中以位为单位来指定其成员所占内存长度&#xff0c;这种以位为单位的成员称为"位段"或"位域"&#xff08;bit field&#xff09;…

Golang——异常和error

Go 提供了两种处理错误 方式&#xff0c; 一 种是借助 panic和 recover 的抛出捕获机制&#xff0c; 另一种使用error 错误类型 一、异常 1、go没有try/catch&#xff0c;而是使用panic/recover。 panic包出异常&#xff0c;后续代码不再执行 recover再defer中捕获异常&#x…

c++--stack,queue,priority_queue

前言 对于栈和队列我们是不陌生的&#xff0c;在数据结构阶段已经学习过&#xff0c;记得当时我们还是用c语言将它一步一步造出来&#xff0c;因为压栈与出栈正好满足数组的尾插与头删&#xff0c;数组的代价是及小的。对于队列是头出队列&#xff0c;尾插。所以就栈的实现就用…

React 学习笔记总结(七)

针对React拓展相关的学习。 文章目录一. React 项目打包二. React扩展 之 setState两种写法三. React扩展 之 lazyLoad(懒加载)四、React的 stateHook五、React 的 Effect Hook六、React 的 RefHook七、React 的 Fragment八、React 的 Context九、React 的 PureComponent1. Com…

centos配置网卡自动获取ipv4和ipv6地址

环境&#xff1a; os&#xff1a;centos7 1.背景 正常网卡通过dhcp是不会自动获取ipv6地址的&#xff0c;一般手动执行dhclient -6 <网卡名>可以获取。 现在需求是&#xff1a;实现os启动后自动获取到ipv6地址 2.方法 在网卡对应的配置文件/etc/sysconfig/network-sc…

一、初识Node.js

一、初识Node.js 1.什么是Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 的官网地址&#xff1a; https://nodejs.org/zh-cn/ 2.Node.js中JavaScript运行环境 注意&#xff1a; 浏览器是 JavaScript 的前端运行环境。Node.js 是 JavaScript 的…

The VMware Authorization Service is not running 解决办法

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

ARM惹众怒,美国芯片行业也开始抛弃它,跟随中国芯片支持新架构

ARM曾以为它已经垄断了移动芯片市场&#xff0c;因此可以肆意&#xff0c;甚至还传出计划提高芯片架构授权费的消息&#xff0c;去年还计划限制高通等美国芯片企业自研核心架构&#xff0c;此前它已得罪中国芯片&#xff0c;可以说ARM真正惹了众怒&#xff0c;如此情况下这些芯…

开源文档协作套件CryptPad

本文完成于 2022年 9 月&#xff0c;11月的时候补充了些内容&#xff0c;修改了部分图片&#xff0c;原本是准备发的&#xff0c;不知什么原因又给拖延了&#xff1b; 当时的版是 v5.1.0&#xff0c;而现在最新的版本是 v5.2.1 &#xff1b; 什么是 CryptPad &#xff1f; Cryp…