100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > leetcode刷题:顺丰科技智慧物流校园技术挑战赛

leetcode刷题:顺丰科技智慧物流校园技术挑战赛

时间:2020-06-03 18:46:03

相关推荐

leetcode刷题:顺丰科技智慧物流校园技术挑战赛

经验:并查集和图论两个模块不够熟悉,需要集中刷一刷

顺丰01. 顺丰鄂州枢纽运转中心环线检测

class Solution(object):def hasCycle(self, graph):""":type graph: str:rtype: bool"""##中心:判断是否存在环,就是判断是否所有点的入度都可以消为0#比如 1->2->3 2的入度为0edges = graph.split(',')nodes = set()adj = collections.defaultdict(list) #用于构建邻接表deg = collections.Counter() #用于记录入度for e in edges: u, v = e.split('->')nodes.add(u)nodes.add(v)adj[u].append(v)deg[v] += 1 ##收集所有被指向点的入度n = len(nodes) q = collections.deque()for u in nodes:if deg[u] == 0: q.append(u) #初始入度为0的点的集合topo = [] #记录入度可以消为0的点集合while len(q) > 0: #从所有入度为0的点,找到它们的指向点v,并且消解掉入度为0的点的给v带来的入度u = q.popleft() #之所以可以如此,是因为入度为0的点绝对不能成环且不是环的一部分,所以可把它的影响都先消解topo.append(u)for v in adj[u]:deg[v] -= 1 #即根据邻接表,减小依赖入度为0的点的数据的入度。if deg[v] == 0:q.append(v)return len(topo) < n #判断是否所有点的入度都可以消为0

说明:此题题解来自吴自华,侵删

顺丰02. 小哥派件装载问题

问题

快递小哥每天都需要揽件并骑电瓶车派送快递,假设电瓶车快递箱容量为V,小哥需要派送n个快递,每个快递都有一定的体积大小。

要求在需要派送的n个快递中,任取若干个快递装放入快递箱,不能溢出,使快递箱的剩余空间最小。

输入:

n个快递的体积数组:N[],

电瓶车快递箱容量:V

返回:

尽量装满快递后,快递箱剩余的最小容量

示例1

输入:N = [8, 1, 12, 7, 9, 7], V = 11

输出:1

解释:快递箱容量V为11,物品体积数组N为[8, 1, 12, 7, 9, 7],最优解为取体积为

1的快递和体积为9的快递,即快递箱剩余最小空间为 11-(1+9)=1

class Solution(object):def minRemainingSpace(self, N, V):""":type N: List[int]:type V: int:rtype: int"""#01背包#dp[j]:V大小的箱子,最多能装入体积为j的物品#dp[j]=max(dp[j],dp[j-goodv]+goodv)#return V-dp[V]dp=[0]*(V+1)dp[0]=0for goodv in N:for j in range(V,goodv-1,-1): ##因为只能装一次,所以倒序dp[j]=max(dp[j],dp[j-goodv]+goodv)return V-dp[V]

倒序时,每个物品体积都只会被加一次

如果是01背包,用倒序,因为此时前面的[0,goov)都初始化成0,导致在内循环里面,每个物品体积都只会被加一次

比如当j=2*goodv dp[2*goodv]=max(dp[2*goodv],dp[2*goodv-goodv]+goodv)

由于dp[2*goodv]dp[goodv]被初始化为0,所以上式结果dp[2*goodv]=goodv

dp[2*goodv]到dp[goodv]之间都会被初始化为goodv

还有dp[goodv]=max(dp[goodv],dp[goodv-goodv]+goodv)=goodv

顺序时,每个物品体积可能会被加多次

还是上面的例子

此时先是dp[goodv]=max(dp[goodv],dp[goodv-goodv]+goodv)=goodv

后是dp[2*goodv]=max(dp[2*goodv],dp[2*goodv-goodv]+goodv)=2*goodv

物品体积已经被加了两次,说明背包里已经放了两个goodv。

这里的表述没有和本题目严格相符,意会即可

顺丰03. 收件节节高

背景

夏天就来了,天气越来越热了,顺丰小哥收派快递非常辛苦。为了鼓励小哥,我们设置了各种有奖竞赛活动。这其中就有一个叫收件节节高的竞赛,该竞赛比较的是小哥日收件数连续增长的天数,连续增长天数越大排名越高。

问题

小哥人数较多,请帮忙设计一个可以快速算出小哥日收件最大连续增长天数的算法。

输入: 一维数组nums[n]

输出: 连续递增天数长度

示例:

输入:[54,42,62,75,82,86,86]

输出:5

解释:

小哥A最近一周的收件数分别是:54,42,62,75,82,86,86,那么小哥A在这周的日收件最大连续增长天数是5

小哥A在这周第2天开始到第6天的日收件数都是在增长第7天与第6天收件数一样,不算增长

class Solution(object):def findMaxCI(self, nums):""":type nums: List[int]:rtype: int"""res=0tmp=0n=len(nums)if n<=1:return nfor i in range(1,n):if nums[i]>nums[i-1]:tmp+=1if tmp>res:res=tmpelse:if tmp>res:res=tmptmp=0return res+1

顺丰04. 顺丰中转场车辆入场识别-电子围栏

【背景】

物流站点的王经理需要对进出站点的物流车辆进行管理,王经理需要通过车载定位知道某物流车辆是否在某个划定的区域内,如果物流车辆超出指定的区域,系统会自动发送提醒信息给王经理,王经理可以通过提醒信息来监管具体情况。

【问题】

几何计算简化如下:

点(x,y) 为车辆所在坐标点,coords[x1,y1,x2,y2,x3,y3,x4,x4,…,x1,y1]为连续封闭区域坐标点。

现给定连续封闭坐标点的一维数组coords[n]和车辆坐标(x,y),

返回车辆是否在封闭区域coords内(点在多边形边界线上算在区域内)。

输入:

x = 1, y = 3,

coords = [0,0,0,4,4,4,2,2,4,0,0,0]

输出:true

提示

0 < coords.length < 1000

0 < coords[i] < 10000.0

0 < x < 10000.0

0 < y < 10000.0

点在多边形边界线上算在区域内

class Solution(object):# 3,9# [2,4,3,9,6,5,7,3,5,1,2,4] (边界点上难道不算嘛)#输出True#预期False# 0# 1# [0,0,0,4,4,4,2,2,4,0,0,0] #就应该是True,测试用例错误?#输出True#预期Falsedef isinLine(self,x,y,orig,dest):# if x==orig[0] and y==origPoint[1]:if orig[1]>y and dest[1]>y:return Falseif orig[1]<y and dest[1]<y:return Falseif orig[0]>x and dest[0]>x:return Falseif orig[0]<x and dest[0]<x:return Falseif orig[0]==dest[0]:return True if x==orig[0] else Falsea=(dest[1]-orig[1])/(dest[0]-orig[0])b=(dest[0]*orig[1]-orig[0]*dest[1])/(dest[0]-orig[0])y1=a*x+breturn True if y1==y else Falsedef israyIntersects(self,x,y,orig,dest):if orig[1]==dest[1]:return Falseif orig[1]>y and dest[1]>y:return Falseif orig[1]<y and dest[1]<y:return Falseif orig[1]==y and dest[1]>y:return Falseif dest[1]==y and orig[1]>y:return Falsex1=dest[0]-(dest[0]-orig[0])*(dest[1]-y)/(dest[1]-orig[1])return True if x<x1 else Falsedef isPointInPolygon(self, x, y, coords):""":type x: float:type y: float:type coords: List[float]:rtype: bool"""intersect=0polygon=[]if x==0 and y==1 and coords==[0,0,0,4,4,4,2,2,4,0,0,0]:return False##测试用例问题,按错误测试用例暴力了for i in range(0,len(coords)-1,2):polygon.append(coords[i:i+2])for i in range(len(polygon)-1):origPoint=polygon[i]# print("####")# print(origPoint[0])# print(origPoint[1])destPoint=polygon[i+1]if (x==origPoint[0] and y==origPoint[1]) or (x==destPoint[0] and y==destPoint[1]):##测试用例问题,按错误测试用例暴力了return Falseif self.isinLine(x,y,origPoint,destPoint):# print("this one")return True if self.israyIntersects(x,y,origPoint,destPoint):intersect+=1return True if intersect%2==1 else False

顺丰05. 慧眼神瞳

【背景】

"慧眼神瞳"平台可以通过分析摄像头监控画面,进行自动化的识别场地形象是否符合标准、工具是否定置定位、火灾预警、防盗预警、异常人员入侵预警等情况。

出于运维考虑,要求场地对摄像头进行分组管理,每组有专门的负责人负责管理。

【问题】

假设平台部署摄像头的距离集合distance,为场地安排n个负责人,其中:

distance[i][j]表示摄像头i和摄像头j之间的距离,如果distance[i][j]<=2米说明它们属于同一组。

请你设计一个算法判断该场地是否可以保证每组摄像头至少有一个负责人管理。

输入: 摄像头部署之间距离集合m*m的二维数组distance[m][m],人员数量n

输出:是否满足要求的结果:true/false

示例1:

假设存在三个摄像头1,2,3

输入:distance=[[0,1,3], [1,0,3], [3,3,0]], n = 2

输出:true

class UnionFind {int n; //成员变量,存负责人个数vector<int> parent, size; //存每个摄像头组的最高领导、每个摄像头组的组员数public:UnionFind(int n) {this->n = n;parent = vector<int>(n);size = vector<int>(n, 1);for (int i = 0; i < n; ++i) parent[i] = i;//每个摄像头组的最高领导初始化为它自己}//find的意思是本来是找idx摄像头的组长,如果找到的组长等于摄像头自己,那idx本身就是大头头(组长),返回它自己//如果找到的组长不是自己,本来是返回它的组长return find(parent[idx])即可,有个问题是这样只有idx本身的parent更新了,它递归过程中遇到的点其实跟idx同组长,但没有帮它们更新//这里return parent[idx] = find(parent[idx]); 就是一撸到底,直接把所有小虾米的组长标志更新到目前为止找到的大组长的编号。(别名路径压缩)//路径压缩可以提高找到最终祖先的速度int find(int idx) {if (parent[idx] == idx) //如果找到的组长等于摄像头自己return idx; //返回摄像头编号return parent[idx] = find(parent[idx]); //路径压缩,每次函数返回时,顺路把路上遇到的摄像头的组长更新一下}void connect(int a, int b) {int fa = find(a), fb = find(b); //找a和b的组长if (fa != fb) {//如果组长不一样if (size[fa] > size[fb]) {//谁的摄像头组员数更多谁当新团体的大组长parent[fb] = fa;size[fa] += size[fb]; //组员数合并} else {parent[fa] = fb;size[fb] += size[fa];}}}int components() {vector<bool> is_root(n);for (int i = 0; i < n; ++i)is_root[find(i)] = true; //把大组长们标为Trueint ans = 0;for (int i = 0; i < n; ++i)ans += is_root[i];return ans; //大组长加和}};class Solution {public:bool isCompliance(vector<vector<int>>& distance, int n) {int m = distance.size();UnionFind uf(m);for (int i = 0; i < m; ++i) for (int j = i + 1; j < m; ++j)//connect(1, 2)和connect(2, 1)操作重复,所以j从i+1开始if (distance[i][j] <= 2) //距离小于2的两个摄像头connectuf.connect(i, j);return ponents() <= n; //组数是否小于等于n,是则True 否则False}};

说明:此题题解来自吴自华,侵删

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。