当前位置: 首页 > news >正文

创建站点如何做网站seo搜索引擎优化业务

创建站点如何做网站,seo搜索引擎优化业务,外国做电子产品网站有哪些,广州seo网站多少钱一、为什么要使用线段树? 线段树又称为区间树,Segment Tree,对于有一类的问题,我们关心的是线段(或者区间),有一个非常经典的例子:区间染色 问题1:有一面墙,长度为n,每…

一、为什么要使用线段树?

线段树又称为区间树,Segment Tree,对于有一类的问题,我们关心的是线段(或者区间),有一个非常经典的例子:区间染色

问题1:有一面墙,长度为n,每次选择一段墙进行染色,n次操作后,我们可以在[i,j]区间内看见多少种颜色

实际上这道题可以拆分为两个步骤:

①染色操作(更新区间)

②查询操作(查询区间)

如果都使用数组实现的话,染色和查询操作时间复杂度都为O(n)。

 

问题2:区间查询——查询一个区间[i,j]的最大值,最小值,或者区间数字和

问题的实质:基于区间的统计查询

如:2017年注册用户中消费最高的用户?消费最少的用户?学习时间最长的用户?

某个太空区间中天体总量?

 

二、线段树是什么样子的?

在二叉树中,每一个节点存储的是一个线段或一个区间,如上图,每一个节点都对应一个线段的和值。

那么线段树是否一定为满二叉树/完全二叉树呢?——不一定,  且叶子节点不一定全都在树的最后一层!!!但线段树是一颗平衡二叉树(即最大深度与最小深度差值最大为1),如图:

 

 

三、构建线段树

具体代码:

public interface Merger<E> {E merge(E a , E b);
}
public class SegmentTree<E> {private E[] data;private E[] tree;private Merger<E> merger;public SegmentTree(E[] arr,Merger<E> merger){this.merger = merger;data = (E[]) new Object[arr.length];for(int i = 0 ; i < arr.length ;i++){data[i] = arr[i];}tree = (E[]) new Object[4 * arr.length];//在treeIndex的位置创建表示区间从[l...r]的线段树buildSegmentTree(0,0,data.length - 1);}/**** @param treeIndex 创建线段树所对应的根节点的索引* @param l 区间的左端点* @param r 区间的右端点*/private void buildSegmentTree(int treeIndex,int l,int r) {if(l == r){tree[treeIndex] = data[l];return ;}int leftTreeIndex = leftChild(treeIndex);int rightTreeIndex = rightChild(treeIndex);int mid = l + (r - l ) / 2 ;buildSegmentTree(leftTreeIndex , l , mid);buildSegmentTree(rightTreeIndex , mid + 1 , r);//综合两个子节点的信息得到父节点的信息,如求和操作tree[treeIndex] = merger.merge(tree[leftTreeIndex],tree[rightTreeIndex]);}public int getSize(){return data.length;}public E get(int index){if(index < 0 ||index >= data.length){throw new IllegalArgumentException("参数错误");}return data[index];}private int leftChild(int index){return 2 * index + 1;}private int rightChild(int index){return 2 * index + 2;}
}

 

四、线段树中区间查询

    /*** @param queryL 查询左边界* @param queryR 查询右边界* @return*/public E query(int queryL,int queryR){//确定边界if(queryL < 0 || queryL >= data.length || queryR < 0 || queryR >= data.length || queryL > queryR)throw new IllegalArgumentException("边界值异常");return query(0,0,data.length - 1 ,queryL ,queryR);}//在以根节点为treeIndex的线段树中[l...r]的范围里,搜索区间[queryL...queryR]的值private E query(int treeIndex , int l , int r , int queryL ,int queryR) {if(l == queryL && r == queryR)return tree[treeIndex];int leftTreeIndex = leftChild(treeIndex);int rightTreeIndex = rightChild(treeIndex);int mid = l + (r - l ) / 2 ;//忽略左部分if(queryL >= mid + 1)return query(rightTreeIndex,mid + 1 , r,queryL,queryR);//忽略右部分if(queryR <= mid)return query(leftTreeIndex,l,mid,queryL,queryR);//并没有完全落在左节点或者右节点中,一部分落在左边,一部分落在右边E leftResult = query(leftTreeIndex, l, mid, queryL, mid);E rightResult = query(rightTreeIndex, mid + 1, r, mid + 1, queryR);return merger.merge(leftResult,rightResult);}

 

五、参考题目

参考Leetcode上303题《区域和检索 - 不可变》

给定一个整数数组  nums,求出数组从索引 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

相关链接:https://leetcode-cn.com/problems/range-sum-query-immutable/description/

可以使用线段树进行解答:

public class NumArray {private SegmentTree<Integer> segmentTree;public NumArray(int[] nums) {if(nums.length > 0){Integer[] data = new Integer[nums.length];for(int i = 0 ; i < nums.length ; i++){data[i] = nums[i];}segmentTree = new SegmentTree<Integer>(data,(a,b) -> a + b);}}public int sumRange(int i, int j) {if(segmentTree == null)throw new IllegalArgumentException("segmentTree is null,请考虑数组是否为空");return segmentTree.query(i,j);}
}

由于数据是不可变的,我们不使用线段树,也可以得到更好的解答。来看看不使用线段树的解题思路:

public class NumArray {private int [] sum; //sum中存储着前i个元素的和,sum[0] = 0//sum[i]存储着nums[0...i-1]的和public NumArray(int[] nums) {sum = new int[nums.length + 1];sum[0] = 0 ;for(int i = 1 ; i < sum.length ; i ++)sum[i] = sum[i - 1] + nums[i - 1];}public int sumRange(int i, int j) {return sum[j + 1] - sum[i];}
}

可见对于数据不可变的情况下,线段树的优势并没体现出来,线段树主要是应用在数据是动态变化的场景

 

参考Leetcode上307题:https://leetcode-cn.com/problems/range-sum-query-mutable/description/

 区域和检索 - 数组可修改

 

 

 

 

 

 

 

 

此时我们可以来看看不使用线段树的解题思路:

public class NumArray {private int [] sum; //sum中存储着前i个元素的和,sum[0] = 0//sum[i]存储着nums[0...i-1]的和private int[] data;public NumArray(int[] nums) {data = new int[nums.length];for(int i = 0 ; i < nums.length ; i++)data[i] = nums[i];sum = new int[nums.length + 1];sum[0] = 0 ;for(int i = 1 ; i < sum.length ; i ++)sum[i] = sum[i - 1] + nums[i - 1];}public void update(int index , int val){data[index] = val;for(int i = index + 1; i < sum.length ; i++)sum[i] = sum [i - 1] + data[i - 1];}public int sumRange(int i, int j) {return sum[j + 1] - sum[i];}
}

这种操作时间复杂度略高,虽然sumRange依然是O(1)复杂度,但update是一个O(n)复杂度,最坏情况需要遍历nums.length次,如果测试用例中频繁使用update,则每次都是O(n)复杂度,进行m次update操作的话则时间复杂度是O(m*n),性能较低。

 

下面我们使用线段树中更新操作O(logn)

public void set(int index , E e){if(index < 0 || index >= data.length)throw new IllegalArgumentException("Index越界");data[index] = e;set(0,0,data.length-1,index,e);}private void set(int treeIndex, int l, int r, int index, E e) {if(l == r){tree[treeIndex] = e;return;}int mid = l + (r - l) / 2;int leftTreeIndex = leftChild(treeIndex);int rightTreeIndex = rightChild(treeIndex);if(index >= mid + 1){set(rightTreeIndex,mid + 1,r,index,e);}elseset(leftTreeIndex,l,mid,index,e);tree[treeIndex] = merger.merge(tree[leftTreeIndex],tree[rightTreeIndex]);}

 

http://www.lbrq.cn/news/2411857.html

相关文章:

  • 北京海淀区是几环新网站 seo
  • 悦然外贸建站昆山网站建设公司
  • 英文网站建设的请示怎么写网络推广营销方法
  • 佛山外贸企业网站建设app开发自学教程
  • 你的网站尚未备案 根据免费网站推广群发软件
  • 长沙做网站建设公司百度关键词搜索排名统计
  • 建设网站市场分析网址查询注册信息查询
  • 做 了一个 家教 网站哪家网站优化公司好
  • 做网站要做哪些百度搜索网址
  • wordpress架构的网站自己建网站怎么弄
  • 自己做小程序商城西安seo学院
  • 自己做游戏网站网站页面
  • 国外市场网站推广公司国内10大搜索引擎
  • .net做网站教程网络营销产品的特点
  • 进口外贸网站有哪些网站流量
  • 电子商务网站建设系统功能站内推广有哪些方式
  • 如何用自己公司网站做邮箱企业推广方法
  • 沈阳网站seo网站备案查询工信部官网
  • 网站获取访客文职培训机构前十名
  • 做英德红茶的网站竞价恶意点击犯法吗
  • 帮人负责做网站叫什么工作购买域名
  • 电子商务网站建设基本步骤品牌广告和效果广告
  • 网页设计师好吗广州网站优化页面
  • 网站常用文件夹seo刷排名公司
  • 做网站前端用什么关键词查询工具有哪些
  • 医疗企业vi设计公司百度seo优化包含哪几项
  • 上海做衣服版的网站高端网站建设制作
  • 赌博类网站开发中国旺旺(00151) 股吧
  • 成都网站建设索q479185700免费发广告的平台有哪些
  • 专做化妆品网站百度的链接
  • Android Studio 的 Gradle 究竟是什么?
  • (9)机器学习小白入门 YOLOv:YOLOv8-cls 技术解析与代码实现
  • 用 Jetpack Compose 写 Android 的 “Hello World”
  • 《P3398 仓鼠找 sugar》
  • 彩虹云商城全源码 - 全新客服系统上线
  • 【Settlement】P1:整理GH中的矩形GRID角点到EXCEL中