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

潍坊建设网站公司seo排名首页

潍坊建设网站公司,seo排名首页,上海网页设计公司山东济南兴田德润简介,玉溪做网站建设的公司1.题目基本信息 1.1.题目描述 给定一个数组 trees,其中 trees[i] [xi, yi] 表示树在花园中的位置。 你被要求用最短长度的绳子把整个花园围起来,因为绳子很贵。只有把 所有的树都围起来,花园才围得很好。 返回恰好位于围栏周边的树木的坐…

1.题目基本信息

1.1.题目描述

给定一个数组 trees,其中 trees[i] = [xi, yi] 表示树在花园中的位置。

你被要求用最短长度的绳子把整个花园围起来,因为绳子很贵。只有把 所有的树都围起来,花园才围得很好。

返回恰好位于围栏周边的树木的坐标。

1.2.题目地址

https://leetcode.cn/problems/erect-the-fence/description/

2.解题方法

2.1.解题思路

求凸包算法:andraw算法、Graham算法、jarvis算法

2.2.解题步骤

andraw算法(O(nlogn))

  • 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可

  • 第二步,定义求叉积函数cross,函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧

  • 第三步,将nodes按坐标位置进行升序排列

  • 第四步,构建维护变量。stack维护遍历到的结点集合的凸包;visited维护stack中已经存在的结点,避免在求上半部分的凸包时重复(visited初始化时不标记起始结点,因为最后求上半闭包时也需要将起始结点入栈)

  • 第五步,求凸包的下半部分。正序枚举nodes[1:],在stack长度大于等于2,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stack和visited

  • 第六步,求凸包的上半部分。逆序枚举nodes[:i-1],对于没有访问过的结点,在stack长度大于等于凸包下半部分长度时,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stack和visited

  • 第七步,将stack栈顶的起始结点进行弹出;根据stack中的结点索引构建凸包,返回即可

graham算法(O(nlogn))

  • 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可

  • 第二步,定义求叉积函数cross,函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧

    • 2.1.计算叉积

    • 2.2.计算距离的平方

  • 第三步,获取最底部的结点bottom,并将bottom结点置换到nodes的第一个位置

  • 第四步,将nodes中各个结点进行角排序,通过叉积的正负来比较大小,叉积相同则通过与nodes[0]的距离排序

  • 第五步,对于凸包上的最后一条边,如果上面存在共线,那么距离需要从大到小排列,所以需要翻转

    • 5.1.将nodes[low,...,high]中结点进行翻转
  • 第六步,正序枚举nodes[1:],在stack长度大于等于2,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stack

  • 第七步,根据stack中的结点索引构建凸包,返回即可

jarvis算法(O(n^2))

  • 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可

  • 第二步,定义求叉积函数cross。函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧

  • 第三步,获取最左边的最下面一个结点在nodes中的索引leftMost

  • 第四步,构建维护变量。result数组存储凸包中已经找到的结点;visited维护各个结点是否已经在result中;p维护最后找到的一个凸包结点在nodes中的位置

  • 第五步,循环遍历,寻找凸包上的结点添加到result数组中,并更新维护变量

    • 5.1.找到一个结点q,使其余结点都在p->q向量的左边

    • 5.2.找到q后,判断是否存在没有访问过且与p->q向量共线的结点,如果存在则将结点i添加到result数组中

    • 5.3.如果q没有访问过,则将结点q添加到result结果数组中,并更新维护变量visited

    • 5.4.将结点q赋值到p变量中,继续循环寻找下一个q结点;直到回到leftMost结点结束

  • 第六步,返回结果result

3.解题代码

andraw算法代码

# ==> Andrew算法(求凸包算法)(O(nlogn))
def andrewConvexHull(nodes:list[list[int]]) -> list[list[int]]:n = len(nodes)# 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可if n < 4:return nodes# 第二步,定义求叉积函数cross,函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧def cross(node1:list[int], node2:list[int], node3:list[int]) -> int:x1, y1 = node1x2, y2 = node2x3, y3 = node3return (x2 - x1) * (y3 - y2) - (x3 - x2) * (y2 - y1)# 第三步,将nodes按坐标位置进行升序排列nodes.sort()# 第四步,构建维护变量。stack维护遍历到的结点集合的凸包;visited维护stack中已经存在的结点,避免在求上半部分的凸包时重复(visited初始化时不标记起始结点,因为最后求上半闭包时也需要将起始结点入栈)stack = [0]visited = [False] * n# 第五步,求凸包的下半部分。正序枚举nodes[1:],在stack长度大于等于2,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stack和visitedfor i in range(1, n):while len(stack) > 1 and cross(nodes[stack[-2]], nodes[stack[-1]], nodes[i]) < 0:item = stack.pop()visited[item] = Falsestack.append(i)visited[i] = True# 第六步,求凸包的上半部分。逆序枚举nodes[:i-1],对于没有访问过的结点,在stack长度大于等于凸包下半部分长度时,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stack和visitedm = len(stack)  # 凸包下半部分的结点个数for i in range(n - 2, -1, -1):if not visited[i]:while len(stack) > m and cross(nodes[stack[-2]], nodes[stack[-1]], nodes[i]) < 0:item = stack.pop()visited[item] = Falsestack.append(i)visited[i] = True# 第七步,将stack栈顶的起始结点进行弹出;根据stack中的结点索引构建凸包,返回即可stack.pop()return [nodes[i] for i in stack]class Solution:# 思路1:andraw算法def outerTrees1(self, trees: List[List[int]]) -> List[List[int]]:convexHull = andrewConvexHull(trees)return convexHull

graham算法代码

# ==> Graham算法(求凸包算法)(O(nlogn))
from functools import cmp_to_key
def grahamConvexHull(nodes:list[list[int]]) -> list[list[int]]:n = len(nodes)# 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可if n < 4:return nodes# 第二步,定义求叉积函数cross,函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧# 2.1.计算叉积def cross(node1:list[int], node2:list[int], node3:list[int]) -> int:x1, y1 = node1x2, y2 = node2x3, y3 = node3return (x2 - x1) * (y3 - y2) - (x3 - x2) * (y2 - y1)# 2.2.计算距离的平方def dist2(node1:list[int], node2:list[int]) -> int:x1, y1 = node1x2, y2 = node2return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)# 第三步,获取最底部的结点bottom,并将bottom结点置换到nodes的第一个位置bottom = 0for i in range(1, n):if nodes[i][1] < nodes[bottom][1]:bottom = inodes[bottom], nodes[0] = nodes[0], nodes[bottom]# 第四步,将nodes中各个结点进行角排序,通过叉积的正负来比较大小,叉积相同则通过与nodes[0]的距离排序def compare(node1:list[int], node2:list[int]) -> int:diff = -cross(nodes[0], node1, node2)return diff if diff else dist2(nodes[0], node1) - dist2(nodes[0], node2)nodes[1:] = sorted(nodes[1:], key = cmp_to_key(compare))# 第五步,对于凸包上的最后一条边,如果上面存在共线,那么距离需要从大到小排列,所以需要翻转right = n - 1while right >= 0 and cross(nodes[0], nodes[n - 1], nodes[right]) == 0:right -= 1low, high = right + 1, n - 1# 5.1.将nodes[low,...,high]中结点进行翻转while low < high:nodes[low], nodes[high] = nodes[high], nodes[low]low += 1high -= 1# 第六步,正序枚举nodes[1:],在stack长度大于等于2,且stack[-1]->nodes[i]的向量在stack[-2]->stack[-1]向量的右边时(叉积判断),不断循环从stack中弹出结点;同时在循环中和循环后更新维护变量stackstack = [0]for i in range(1, n):while len(stack) > 1 and cross(nodes[stack[-2]], nodes[stack[-1]], nodes[i]) < 0:stack.pop()stack.append(i)# 第七步,根据stack中的结点索引构建凸包,返回即可return [nodes[i] for i in stack]class Solution:# 思路3:Graham算法def outerTrees(self, trees: List[List[int]]) -> List[List[int]]:convexHull = grahamConvexHull(trees)return convexHull

jarvis算法代码

# ==> Jarvis算法(求凸包算法)(O(n^2))
def jarvisConvexHull(nodes:list[list[int]]) -> list[list[int]]:n = len(nodes)# 第一步,特殊情况处理。如果nodes的长度小于等于3,则结点都在凸包中,直接返回即可if n < 4:return nodes# 第二步,定义求叉积函数cross。函数功能:求node1->node2和node2->node3两向量的叉积;根据叉积性质,如果axb二维叉积标量小于0,则向量b在向量a的右侧def cross(node1:list[int], node2:list[int], node3:list[int]) -> int:x1, y1 = node1x2, y2 = node2x3, y3 = node3return (x2 - x1) * (y3 - y2) - (x3 - x2) * (y2 - y1)# 第三步,获取最左边的最下面一个结点在nodes中的索引leftMostleftMost = 0for i in range(n):if nodes[i][0] < nodes[leftMost][0] or (nodes[i][0] == nodes[leftMost][0] and nodes[i][1] < nodes[leftMost][1]):leftMost = i# 第四步,构建维护变量。result数组存储凸包中已经找到的结点;visited维护各个结点是否已经在result中;p维护最后找到的一个凸包结点在nodes中的位置result = []visited = [False] * np = leftMost# 第五步,循环遍历,寻找凸包上的结点添加到result数组中,并更新维护变量while True:# 5.1.找到一个结点q,使其余结点都在p->q向量的左边q = (p + 1) % nfor j, node in enumerate(nodes):if cross(nodes[p], nodes[q], node) < 0:q = j# 5.2.找到q后,判断是否存在没有访问过且与p->q向量共线的结点,如果存在则将结点i添加到result数组中for i in range(n):if not visited[i] and i != p and i != q and cross(nodes[i], nodes[p], nodes[q]) == 0:result.append(nodes[i])visited[i] = True# 5.3.如果q没有访问过,则将结点q添加到result结果数组中,并更新维护变量visitedif not visited[q]:result.append(nodes[q])visited[q] = True# 5.4.将结点q赋值到p变量中,继续循环寻找下一个q结点;直到回到leftMost结点结束p = qif p == leftMost:break# 第六步,返回结果resultreturn resultclass Solution:# 思路2:jarvis算法def outerTrees2(self, trees: List[List[int]]) -> List[List[int]]:convexHull = jarvisConvexHull(trees)return convexHull

4.执行结果

http://www.dtcms.com/wzjs/311820.html

相关文章:

  • 哪个平台做网站好制作网站的软件
  • 免费移动版wordpress2020 惠州seo服务
  • go语言做的网站河南百度推广电话
  • 遂宁市建设银行网站夜夜草
  • 商务信息网站怎么做竞价服务托管价格
  • 提高政府的门户网站建设2023年6月疫情恢复
  • 百度推广网页制作seo关键字排名
  • 网站ftp查询长沙网站推广排名优化
  • 四川时宇建设工程有限公司官方网站谷歌手机版浏览器官网
  • 目前网站开发的主流语言是什么seo快速排名软件
  • 南通做网站推广的公司网络营销有哪些特点
  • 网站制作公司南宁哪里有整站优化
  • wordpress 分类 模板关键词排名优化营销推广
  • 网站建设用语言长沙做网站推广
  • 上海工作网站hao123影视
  • 日本无线上网wifi广州百度快速优化排名
  • 广告制作公司需要什么资质石家庄百度快照优化排名
  • 做网站会什么问题seo推广是做什么
  • 四平做网站佳业脚本外链平台
  • wordpress nginx 配置文件网站制作优化
  • 网站建设重要意义广告网页
  • 网站域名地址查询广告词
  • 广州网站制作武汉公众号关键词排名优化
  • 商务网站建设的可行性分析包括广告联盟骗局
  • 哈尔滨网站推广会计培训
  • 那种投票网站里面怎么做连接友谊
  • 没有公司自己做网站seo优化快排
  • 中国足球最新消息网站seo综合诊断
  • 深圳著名设计网站发帖推广平台
  • 电子贺卡在线制作网站怎么样推广自己的公司