2021-09-04:加油站。在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost
2021-09-04:加油站。在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。说明: 如果题目有解,该答案即为唯一答案。输入数组均为非空数组,且长度相同。输入数组中的元素均为非负数。力扣134。
福大大 答案2021-09-04:
纯能数组。gas[i]-distance[i]。
时间复杂度:O(N)。
额外空间复杂度:O(1)。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
gas := []int{1, 2, 3, 4, 5}
cost := []int{3, 4, 5, 1, 2}
ret := canCompleteCircuit(gas, cost)
fmt.Println(ret)
}
func canCompleteCircuit(gas []int, cost []int) int {
if len(gas) == 0 {
return -1
}
if len(gas) == 1 {
return twoSelectOne(gas[0] < cost[0], -1, 0)
}
good := stations(cost, gas)
for i := 0; i < len(gas); i++ {
if good[i] {
return i
}
}
return -1
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
func stations(cost []int, gas []int) []bool {
if len(cost) < 2 || len(cost) != len(gas) {
return nil
}
init0 := changeDisArrayGetInit(cost, gas)
if init0 == -1 {
return make([]bool, len(cost))
} else {
return enlargeArea(cost, init0)
}
}
func changeDisArrayGetInit(dis []int, oil []int) int {
init0 := -1
for i := 0; i < len(dis); i++ {
dis[i] = oil[i] - dis[i]
if dis[i] >= 0 {
init0 = i
}
}
return init0
}
func enlargeArea(dis []int, init0 int) []bool {
res := make([]bool, len(dis))
start := init0
end := nextIndex(init0, len(dis))
need := 0
rest := 0
for {
// 当前来到的start已经在连通区域中,可以确定后续的开始点一定无法转完一圈
if start != init0 && start == lastIndex(end, len(dis)) {
break
}
// 当前来到的start不在连通区域中,就扩充连通区域
// start(5) -> 联通区的头部(7) -> 2
// start(-2) -> 联通区的头部(7) -> 9
if dis[start] < need { // 当前start无法接到连通区的头部
need -= dis[start]
} else { // 当前start可以接到连通区的头部,开始扩充连通区域的尾巴
// start(7) -> 联通区的头部(5)
rest += dis[start] - need
need = 0
for rest >= 0 && end != start {
rest += dis[end]
end = nextIndex(end, len(dis))
}
// 如果连通区域已经覆盖整个环,当前的start是良好出发点,进入2阶段
if rest >= 0 {
res[start] = true
connectGood(dis, lastIndex(start, len(dis)), init0, res)
break
}
}
start = lastIndex(start, len(dis))
if start == init0 {
break
}
} //for (start != init0);
return res
}
// 已知start的next方向上有一个良好出发点
// start如果可以达到这个良好出发点,那么从start出发一定可以转一圈
func connectGood(dis []int, start int, init0 int, res []bool) {
need := 0
for start != init0 {
if dis[start] < need {
need -= dis[start]
} else {
res[start] = true
need = 0
}
start = lastIndex(start, len(dis))
}
}
func lastIndex(index int, size int) int {
return twoSelectOne(index == 0, (size - 1), index-1)
}
func nextIndex(index int, size int) int {
return twoSelectOne(index == size-1, 0, index+1)
}
执行结果如下:

拓展题:
前后端数据如何统一验证呢?比如前端输入要求6-16个字符,后端也做6-16个字符的验证。前后端分开验证,前后端都得开发,工作量增加。如何做到前端做验证,后端验证直接使用前端的规则?这样后端就不用开发了,工作量就减少了。
福大大 答案2021-09-04:
用js写验证api,前后端调用。
js、joi、request-validate、jsonschma、swagger。
2021-09-04:加油站。在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost的更多相关文章
- 2021.11.04 P1392 取数(多路归并)
2021.11.04 P1392 取数(多路归并) P1392 取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 在一个n行m列的数阵中,你须在每一行取一个数(共n个数) ...
- 2021.09 ccf csp 第四题 收集卡牌
2021.09 ccf csp 第四题 收集卡牌 思路 这题如果直接计算,因为不同的分类种数太多,枚举所有的分类情况是一个几乎不可能的复杂任务. 但不同摸牌次数,不同已摸出牌种类的子问题的答案之间,具 ...
- lintcode 中等题:Max Points on a Line 最多有多少个点在一条直线上
题目 最多有多少个点在一条直线上 给出二维平面上的n个点,求最多有多少点在同一条直线上. 样例 给出4个点:(1, 2), (3, 6), (0, 0), (1, 3). 一条直线上的点最多有3个. ...
- 一条直线上N个线段所覆盖的总长度
原文:http://blog.csdn.net/bxyill/article/details/8962832 问题描述: 现有一直线,从原点到无穷大. 这条直线上有N个线段.线段可能相交. 问,N个线 ...
- LeetCode:149_Max Points on a line | 寻找一条直线上最多点的数量 | Hard
题目:Max Points on a line Given n points on a 2D plane, find the maximum number of points that lie on ...
- [小北De编程手记] : Lesson 04 - Selenium For C# 之 API 上
这一部分,我准备向大家介绍Selenium WebDriver的常用API,学习这部分内容需要大家最好有一些简单的HTML相关知识,本文主要涉及到以下内容: Selenium API:元素检查 Sel ...
- lintcode-186-最多有多少个点在一条直线上
186-最多有多少个点在一条直线上 给出二维平面上的n个点,求最多有多少点在同一条直线上. 样例 给出4个点:(1, 2), (3, 6), (0, 0), (1, 3). 一条直线上的点最多有3个. ...
- JS原生上传大文件显示进度条-php上传文件
JS原生上传大文件显示进度条-php上传文件 在php.ini修改需要的大小: upload_max_filesize = 8M post_max_size = 10M memory_li ...
- java 判断点是否在一条线段上
public static void main(String[] args) { Scanner scan = new Scanner(System.in); Point point1 = new P ...
- python扩展实现方法--python与c混和编程 转自:http://www.cnblogs.com/btchenguang/archive/2012/09/04/2670849.html
前言 需要扩展Python语言的理由: 创建Python扩展的步骤 1. 创建应用程序代码 2. 利用样板来包装代码 a. 包含python的头文件 b. 为每个模块的每一个函数增加一个型如PyObj ...
随机推荐
- instanceof与类型转换
instanceof与类型转换 package com.andy.base.oop.demo01.demo06; public class Teacher extends Person { } pac ...
- RPA的概念和优势
大多数人每天都会使用到一些机器人流程自动化的工具,例如读取邮件和系统,计算.生成文件和报告.而在未来,那些你不想做的枯燥的工作,也许真的可以不做了,重复化.标准化的工作都可以让机器人帮你完成.想必此刻 ...
- Matlab笔记--Matlab概述(初登场)
Matlab概述 安装MATLAB教程 可以参考这里:https://www.cnblogs.com/sixuwuxian/p/15858196.html Matlab的启动 右键图标,选择属性,可以 ...
- Android studio手机界面的显示
终于显示出来啦! 前几天因为SDK的地址错误一直不显示,现在终于显示出来啦! 关于报错原因的话,我也不太清楚是咋解决的,就改了改Android studio软件里面下载SDK的地址,就出来啦!(只要报 ...
- Spring--AOP通知类型
AOP通知类型 前置通知 通知类中的数据在原始数据的前面 后置通知 通知类中的数据在原始数据的后面 环绕通知 若是只是加一个注解: 我们需要这样做:加一个参数: 若是面对有返回值的方法,又有一点不同之 ...
- Javaweb基础复习------Filter相关应用+登录验证案例的使用
Filter(过滤器) 基本步骤: 1.定义类,实现Filter接口,并重写其所有方法 2.配置Filter拦截资源的路径,在类上定义2 WebFilter注解(WebFilter配置的路径,是拦截资 ...
- java选择结构-if
java选择结构-if if单选泽结构 if双选择结构 if多选择结构 if嵌套结构 package charpter2; import com.sun.xml.internal.ws.address ...
- MongoDB基础知识梳理
简介 MongoDB 是由 C++ 编写的开源 NoSQL 和基于文档的数据库.MongoDB 提供了面向文档的存储方式,操作起来比较简单和容易,支持"无模式"的数据建模,可以存储 ...
- TSDB - VictoriaMetrics 技术原理浅析
版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/17258452.html ),以下内容为个人 ...
- Docker容器中使用GPU
背景 容器封装了应用程序的依赖项,以提供可重复和可靠的应用程序和服务执行,而无需整个虚拟机的开销.如果您曾经花了一天的时间为一个科学或 深度学习 应用程序提供一个包含大量软件包的服务器,或者已经花费数 ...