数据结构——二叉树的修改与构造

news2024/9/21 12:33:34

数据结构——二叉树的修改与构造

  • 一、修改二叉树
    • 226. 翻转二叉树
      • 1.前/后序递归
      • 2.广度优先搜索迭代
      • 3.拓展:修改中序遍历 / 中序统一迭代写法
    • 114. 二叉树展开为链表
  • 二、构造二叉树
    • 106. 从中序与后序遍历序列构造二叉树
      • 递归思路
    • 105. 从前序与中序遍历序列构造二叉树
      • 递归思路
    • 889. 根据前序和后序遍历构造二叉树
      • 思路
    • 654. 最大二叉树
      • 思路
    • 617. 合并二叉树
      • 1.递归
      • 2.迭代

一、修改二叉树

226. 翻转二叉树

226. 翻转二叉树

注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便因为中序遍历会把某些节点的左右孩子翻转了两次

使用层序遍历依然是可以的。只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的

1.前/后序递归

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root==null){
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swapTree(root); //前后序都可
        return root;
    }
    public void swapTree(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

2.广度优先搜索迭代

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {return null;}
        ArrayDeque<TreeNode> deque = new ArrayDeque<>();
        deque.offer(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            while (size-- > 0) {
                TreeNode node = deque.poll();
                swapTree(node);
                if (node.left != null) {deque.offer(node.left);}
                if (node.right != null) {deque.offer(node.right);}
            }
        }
        return root;
    }

    public void swapTree(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

3.拓展:修改中序遍历 / 中序统一迭代写法

修改中序遍历,避免节点左右孩子翻转两次的情况

class Solution {
    public TreeNode invertTree(TreeNode root) {
       if(root==null){
            return null;
        }
        invertTree(root.left);
        swapTree(root);
        invertTree(root.left);
        return root;
    }
    public void swapTree(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

中序统一迭代写法用栈来遍历,而不是靠指针来遍历,避免了递归法中翻转了两次的情况

class Solution {
    public TreeNode invertTree(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<>();
        if (root != null) {
            stack.push(root);
        }
        while (!stack.isEmpty()) {
            TreeNode node = stack.peek();
            if (node!=null) {
                stack.pop(); 
                if (node.right!=null) stack.push(node.right);  // 右
                stack.push(node);                // 中
                stack.push(null); 
                if (node.left!=null) stack.push(node.left);    // 左
            } else {
                stack.pop(); 
                node = stack.pop();
                swapTree(node);
            }
        }
        return root;
    }

    public void swapTree(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

114. 二叉树展开为链表

114. 二叉树展开为链表

class Solution {
    public void flatten(TreeNode root) {
        if (root == null) return;
        //分别处理左右子树
        flatten(root.left);
        flatten(root.right);
        //后序,保证左右指针改变指向不会使孩子丢失
        TreeNode left = root.left;
        TreeNode right = root.right;
        //左指针置为null,右指针指向原左子树
        root.left = null;
        root.right = left;
        //将原本的右子树放在当前右子树的末端
        TreeNode p = root;
        while (p.right != null) {
            p = p.right;
        }
        p.right = right;
    }
}

二、构造二叉树

106. 从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

注意: 你可以假设树中没有重复的元素。

例如,给出中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:
在这里插入图片描述

递归思路

根据两个顺序构造一个唯一的二叉树,就是以后序数组的最后一个元素为切割点,将中序数组切分,根据中序数组分割情况,反过来在切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。是一种左右子树分治的方法。

在这里插入图片描述

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

1、如何切割

中序数组相对比较好切,找到切割点(后序数组的最后一个元素)在中序数组的位置,然后切割。

对于后序数组,首先要舍弃末尾元素,因为这个元素就是中间节点,已经用过了。
后序数组没有明确的切割元素来进行左右切割,但注意中序数组大小一定是和后序数组的大小相同的。中序数组已经切成了左中序数组和右中序数组了,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。

中序和后序数组都切割完成后,就可以进行递归了。

2、边界值的计算

注意确定切割的标准,是左闭右开,还有左开右闭,还是左闭右闭,这个就是不变量,要在递归中保持这个不变量。
这里使用左闭右开

左子树-中序数组:中序数组开头 到 找到的节点元素位置
左子树-后序数组:后序数组开头 到 postLeft + (rootIndex - inLeft) (后序数组的起始位置加上左子树长度就是后序数组结束位置了(开区间),左子树的长度 = 根节点索引-左子树)
右子树-中序数组 找到的节点元素位置+1 到 中序数组末尾
右子树-后序数组 postLeft + (rootIndex - inLeft) 到 后序数组倒数第二个元素位置
找到的节点位置rootIndex不进入下次递归

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return buildTree1(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }
    public TreeNode buildTree1(int[] inorder, int inLeft, int inRight,
                               int[] postorder, int postLeft, int postRight) {
        // 没有元素了
        if (inRight - inLeft < 1) {
            return null;
        }
        // 只有一个元素
        if (inRight - inLeft == 1) {
            return new TreeNode(inorder[inLeft]);
        }
        // 后序数组postorder里最后一个即为根结点
        int rootVal = postorder[postRight - 1];
        TreeNode root = new TreeNode(rootVal);
        int rootIndex = 0;//记录下标
        // 根据根结点的值找到该值在中序数组inorder里的位置
        for (int i = inLeft; i < inRight; i++) {
            if (inorder[i] == rootVal) {
                rootIndex = i;
                break;
            }
        }
        // 根据rootIndex划分左右子树
        //左中序,左后序
        root.left = buildTree1(inorder, inLeft, rootIndex,
                postorder, postLeft, postLeft + (rootIndex - inLeft));
        //右中序,右后序
        root.right = buildTree1(inorder, rootIndex + 1, inRight,
                postorder, postLeft + (rootIndex - inLeft), postRight - 1);
        return root;
    }
}

105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

例如,给出

前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树:
在这里插入图片描述

递归思路

与106. 从中序与后序遍历序列构造二叉树思路相同,变为以前序数组的第一个元素为切割点,将中序数组切分,根据中序数组分割情况,切前序数组。

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTree2(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }
    TreeNode buildTree2(int[] preorder, int preLeft, int preRight,
                        int[] inorder, int inLeft, int inRight) {
        // 递归终止条件
        if (inLeft > inRight || preLeft > preRight) return null;

        // val 为前序遍历第一个的值,也即是根节点的值
        // idx 为根据根节点的值来找中序遍历的下标
        int idx = inLeft, val = preorder[preLeft];
        TreeNode root = new TreeNode(val);
        for (int i = inLeft; i <= inRight; i++) {
            if (inorder[i] == val) {
                idx = i;
                break;
            }
        }

        // 根据 idx 来递归找左右子树
        root.left = buildTree2(preorder, preLeft + 1, preLeft + (idx - inLeft),
                         inorder, inLeft, idx - 1);
        root.right = buildTree2(preorder, preLeft + (idx - inLeft) + 1, preRight,
                         inorder, idx + 1, inRight);
        return root;
    }
}

PS:只知道前序和后序遍历序列无法确定唯一的一颗二叉树,因为没有中序遍历就无法确定左右部分,也就无法分割。
如前序遍历是[1 2 3], 后序遍历是[3 2 1],可能有如下四种情况:
在这里插入图片描述

889. 根据前序和后序遍历构造二叉树

889. 根据前序和后序遍历构造二叉树

给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。

如果存在多个答案,您可以返回其中 任何 一个。

思路

通过前序中序,或者后序中序遍历结果可以确定一棵原始二叉树,但是通过前序后序遍历结果无法确定原始二叉树。

前两道题,可以通过前序或者后序遍历结果找到根节点,然后根据中序遍历结果确定左右子树。这道题,你可以确定根节点,但是无法确切的知道左右子树有哪些节点。

首先把前序遍历结果的第一个元素或者后序遍历结果的最后一个元素确定为根节点的值。
然后把前序遍历结果的第二个元素作为左子树的根节点的值。
在后序遍历结果中寻找左子树根节点的值,从而确定了左子树的索引边界,进而确定右子树的索引边界,递归构造左右子树即可。

class Solution {
    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        int len = preorder.length;
        if (len == 0) return null;
        TreeNode node = new TreeNode(preorder[0]);
        if (len == 1) return node;

        int left = 0;
        for (int i = 0; i < len; i++) {
            if (postorder[i] == preorder[1])
                left = i+1;
        }
        // 递归构造左右子树
        // 根据左子树的根节点索引和元素个数推导左右子树的索引边界
        node.left = constructFromPrePost(Arrays.copyOfRange(preorder,1,left+1),
                                        Arrays.copyOfRange(postorder,0,left));
        node.right = constructFromPrePost(Arrays.copyOfRange(preorder,left+1,len),
                                        Arrays.copyOfRange(postorder,left,len-1));
        return node;
    }
}

654. 最大二叉树

654. 最大二叉树

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

二叉树的根是数组中的最大元素。
左子树是通过数组中最大值左边部分构造出的最大二叉树。
右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。

示例 :
在这里插入图片描述
提示:

给定的数组的大小在 [1, 1000] 之间。

思路

代码随想录动图:
在这里插入图片描述
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。

  • 递归函数的参数和返回值:参数就是传入的是存放元素的数组,返回该数组构造的二叉树的头结点
  • 终止条件:当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。
  • 单层递归的逻辑:
  1. 先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。
  2. 最大值所在的下标左区间 构造左子树
    如果不让空节点(空指针)进入递归,就要加判断maxValueIndex > 0,因为要保证左区间至少有一个数值。
  3. 最大值所在的下标右区间 构造右子树
    如果不让空节点(空指针)进入递归,要加判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return constructMaximumBinaryTree1(nums, 0, nums.length);
    }
    public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
        if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }
        int maxIndex = leftIndex;// 最大值所在位置
        int maxVal = nums[maxIndex];// 最大值
        for (int i = leftIndex + 1; i < rightIndex; i++) {
            if (nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root;
    }
}

617. 合并二叉树

617. 合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

注意: 合并必须从两个树的根节点开始。

示例 1:
在这里插入图片描述

1.递归

合并需要同时遍历两个二叉树,和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。

本题前中后序遍历都可以使用

  • 递归函数的参数和返回值:要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。
  • 终止条件:传入了两个树,就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL);反过来如果t2 == NULL,那么两个数合并就是t1。
  • 单层递归的逻辑:重复利用t1树,将t1作为合并之后树的根节点。单层递归中,把两棵树的元素加到一起。接下来t1的左子树是合并t1左子树t2左子树之后的左子树;t1的右子树是合并t1右子树t2右子树之后的右子树。
    也可以重新定义新的树用于存储结果。

前序:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1==null) return root2;// 如果t1为空,合并之后就是t2
        if (root2==null) return root1;// 如果t2为空,合并之后就应该是t1
        root1.val+=root2.val; // 中
        root1.left = mergeTrees(root1.left,root2.left); // 左
        root1.right = mergeTrees(root1.right,root2.right); // 右
        return root1; 
    }
}

中序:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1==null) return root2;// 如果t1为空,合并之后就是t2
        if (root2==null) return root1;// 如果t2为空,合并之后就应该是t1
        root1.left = mergeTrees(root1.left,root2.left); // 左
        root1.val+=root2.val; // 中
        root1.right = mergeTrees(root1.right,root2.right); // 右
        return root1; 
    }
}

后序:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1==null) return root2;// 如果t1为空,合并之后就是t2
        if (root2==null) return root1;// 如果t2为空,合并之后就应该是t1
        root1.left = mergeTrees(root1.left,root2.left); // 左
        root1.right = mergeTrees(root1.right,root2.right); // 右
        root1.val+=root2.val; // 中
        return root1; 
    }
}

2.迭代

使用栈模拟层序遍历:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1==null) return root2;// 如果t1为空,合并之后就是t2
        if (root2==null) return root1;// 如果t2为空,合并之后就应该是t1
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root2);
        stack.push(root1);
        while (!stack.isEmpty()) {
            TreeNode node1 = stack.pop();
            TreeNode node2 = stack.pop();
            node1.val += node2.val;
            if (node2.right != null && node1.right != null) {
                stack.push(node2.right);
                stack.push(node1.right);
            } else {
                if (node1.right == null) {
                    node1.right = node2.right;
                }
            }
            if (node2.left != null && node1.left != null) {
                stack.push(node2.left);
                stack.push(node1.left);
            } else {
                if (node1.left == null) {
                    node1.left = node2.left;
                }
            }
        }
        return root1;
    }
}

使用队列模拟层序遍历:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1==null) return root2;// 如果t1为空,合并之后就是t2
        if (root2==null) return root1;// 如果t2为空,合并之后就应该是t1
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root1);
        queue.offer(root2);
        while (!queue.isEmpty()) {
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
            // 此时两个节点一定不为空,val相加
            node1.val = node1.val + node2.val;
            // 如果两棵树左节点都不为空,加入队列
            if (node1.left != null && node2.left != null) {
                queue.offer(node1.left);
                queue.offer(node2.left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1.right != null && node2.right != null) {
                queue.offer(node1.right);
                queue.offer(node2.right);
            }
            // 若node1的左节点为空,直接赋值
            if (node1.left == null && node2.left != null) {
                node1.left = node2.left;
            }
            // 若node2的左节点为空,直接赋值
            if (node1.right == null && node2.right != null) {
                node1.right = node2.right;
            }
        }
        return root1;
    }
}

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

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

相关文章

Java day11

第11章 在用户界面上排列组件 11.1 基本的界面布局11.1.1 布置界面11.1.2 顺序布局11.1.3 方框布局11.1.4 网格布局11.1.5 边框布局 11.2 使用多个布局管理器11.3 卡片布局11.3.1 在应用程序中使用卡片布局11.3.2 单元格内边距和面板内边距 11.1 基本的界面布局 11.1.1 布置界…

瑞芯微rk3568移植openbmc(五)----关于novnc h265 webcodec硬解码

本章没有什么实质内容&#xff0c;其实在第四节调好了H264的webcodec以后&#xff0c;H265仅仅只需要改下参数&#xff0c;其他的都交给webgl去处理就行了&#xff0c;没有什么大的变化&#xff0c;vp8、vp9、h264、h265处理都一样&#xff0c;仅仅只是参数的变化&#xff0c;不…

Winform粉丝提问1——winform怎么在设计界面找到代码里的控件

前言&#xff1a; 今天订阅《Winform从入门到精通》的粉丝在VIP群里面问我一个问题&#xff0c;我感觉这个问题应该是初学者都会遇到的&#xff0c;所以我写了这篇文章来帮助初学者来理解这个问题&#xff0c;问题如下&#xff1a; 假设我在Form1界面上添加了两个Label&#x…

建筑行业为什么要数字化转型?

建筑行业为什么要数字化转型&#xff1f; 建筑行业作为国民经济的重要支柱产业之一&#xff0c;其生产过程繁琐、复杂&#xff0c;且产业链条长&#xff0c;涉及众多领域。 然而&#xff0c;目前传统的建筑模式已经无法适应行业的发展需求&#xff0c;建筑行业的数字化转型已…

PasteSpider之项目-服务-环境介绍

在PasteSpider中&#xff0c;项目和服务是重要的对象&#xff0c;只有理解什么是项目什么是服务后配置起来才不会稀里糊涂的&#xff01; 项目 PasteSpider中的项目和我们平时说的项目意思一样&#xff0c;比如你要开发一个在线客服系统(项目)&#xff0c;一个商城系统(项目),…

平台资金提现解决方案之实现单笔转账到支付宝账户功能

大家好&#xff0c;我是小悟 使用场景 不管是做APP、电脑网站、手机网站还是小程序&#xff0c;为了推广基本上都离不开用户分佣的场景。 换句话说就是在其平台内为每个用户设置“电子钱包”功能&#xff0c;而电子钱包在平台那里只是一串数字&#xff0c;这就需要平台为用户…

ESP32CAM的IDF环境开发

首先&#xff0c;我们需要先搭建一个IDFvscode的开发环境&#xff0c;然后再下载源码 esp32-cam 它这个源码有很多文件&#xff0c;我们可以将它分解到我们之前已有的idf环境中&#xff0c;首先是打开我们下载的文件路径 esp32-web-cam/esp-idf/components下面&#xff1a; 这…

【Kafka】SASL认证的Kafka客户端代码示例(spring-kafka和原生客户端)

文章目录 spring-kafka原生客户端Tips spring-kafka 添加依赖&#xff1a; <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.6.3</version></dependency>添加spr…

pytorch 39 yolov5_obb的onnx部署及其优化

进行部署要求配置opencv和onnxruntime环境,这里不累述。 1、模型导出 yolov5_obb项目的使用可以参考:https://hpg123.blog.csdn.net/article/details/129366477 下载yolov5s_csl_dotav1_best.pt,并执行以下命令,得到yolov5s_csl_dotav1_best.onnx python export.py --we…

【Java】文件类 File 中的文件操作与文件读写

文件操作 File 类 属性 修饰符及类型属性说明static StringpathSeparator路径分隔符&#xff0c;String 类型表示static charpathSeparator路径分隔符&#xff0c;char 类型表示 构造方法 方法签名说明File(File parent, String child)根据父目录 File 对象 孩子路径&…

JavaSE学习进阶day05_01 Collection集合

第九章 Collection集合 9.1 集合概述 在前面基础班我们已经学习过并使用过集合ArrayList<E> ,那么集合到底是什么呢? 集合&#xff1a;集合是java中提供的一种容器&#xff0c;可以用来存储多个数据。 集合和数组既然都是容器&#xff0c;它们有什么区别呢&#xff…

华特转债上市价格预测

华特转债 基本信息 转债名称&#xff1a;华特转债&#xff0c;评级&#xff1a;AA-&#xff0c;发行规模&#xff1a;6.46亿元。 正股名称&#xff1a;华特气体&#xff0c;今日收盘价&#xff1a;93.75元&#xff0c;转股价格&#xff1a;84.22元。 当前转股价值 转债面值 / …

如何成为一名优秀的自动化测试开发工程师?

目录 前言 精通编程语言 掌握自动化测试框架 熟悉测试方法和流程 熟练使用测试工具 具备团队协作能力 学习新技术和工具 以下是更为具体的建议&#xff1a; 总结 前言 自动化测试作为软件测试领域中发展最快的一个分支&#xff0c;已经成为了许多企业提升软件质量和效…

C语言断言函数的应用

对于断言&#xff0c;相信大家都不陌生&#xff0c;大多数编程语言也都有断言这一特性。简单地讲&#xff0c;断言就是对某种假设条件进行检查。 在 C 语言中&#xff0c;断言被定义为宏的形式&#xff08;assert(expression)&#xff09;&#xff0c;而不是函数&#xff0c;其…

vue element-ui web端 引入高德地图,并获取经纬度

发版前接到一个临时新需求 &#xff0c;需要在web端地址选择时用地图&#xff0c;并获取经纬度。 临阵发版之际加需求&#xff0c;真的是很头疼&#xff0c;于是赶紧找度娘&#xff0c;找api。 我引入的是高德地图&#xff0c;首先要去申请key &#xff0c; 和密钥&#xff0c;…

【Typora-使用手册】Typora使用手册 常用设置 常用快捷键

【Typora-使用手册】Typora使用手册 & 常用设置 & 常用快捷键 1&#xff09;Typora简介1.1.Typora是什么1.2.下载地址1.3.下载注意事项 2&#xff09;Markdown语法总结2.1.标题编写2.1.1.大标题2.1.2.小标题 2.2.单选框2.3.删除线2.4.表情包2.5.字体加粗2.6.斜体2.7.表…

4.HDFS概述

如果说HDFS是存储,则Yarn就是cpu和内存,mapreduce就是程序。 1.HDFS文件块大小 HDFS中的文件在物理.上是分块存储(Block) ,block默认保存3份块的大小可以通过配置参数(dfs blocksize)来规定,默认大小在Hadoop2 .x版本中是128M,老版本中是64M。 解释:块的大小:10ms*100*…

分布式链路追踪—SkyWalking

文章目录 1. 总览2. 为什么要使用分布式链路追踪3. 了解OpenTracingOpenTracing数据模型 4. 使用分布式链路追踪的好处5. SkyWalking相关问题思考5.1 如何自动采集数据5.2 如何跨进程传递5.3 traceId如何保证全局唯一5.4 请求量大&#xff0c;采集数据对性能的影响 1. 总览 2. …

ES6 总结

概述 笔记内容为参考《JavaScript 高级程序设计 (第4版)》相关内容进行 ES6 部分知识的总结。主要涉及的知识是变量声明、对象解构、函数和对象的扩展内容、集合引用类型的扩展和面向对象编程等。 ES6 学习系列笔记 ES6 总结Symbol、Map、SetES6 中的类&#xff08;class&am…

LeetCode刷题集(三)(26 删除有序数组中的重复项)

学习目标&#xff1a; 基本掌握LeetCode中的26删除有序数组中的重复项 学习内容&#xff1a;LeetCode 26删除有序数组中的重复项 题目描述&#xff1a; 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c…