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)
}

执行结果如下:


左神java代码

拓展题:
前后端数据如何统一验证呢?比如前端输入要求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的更多相关文章

  1. 2021.11.04 P1392 取数(多路归并)

    2021.11.04 P1392 取数(多路归并) P1392 取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 在一个n行m列的数阵中,你须在每一行取一个数(共n个数) ...

  2. 2021.09 ccf csp 第四题 收集卡牌

    2021.09 ccf csp 第四题 收集卡牌 思路 这题如果直接计算,因为不同的分类种数太多,枚举所有的分类情况是一个几乎不可能的复杂任务. 但不同摸牌次数,不同已摸出牌种类的子问题的答案之间,具 ...

  3. lintcode 中等题:Max Points on a Line 最多有多少个点在一条直线上

    题目 最多有多少个点在一条直线上 给出二维平面上的n个点,求最多有多少点在同一条直线上. 样例 给出4个点:(1, 2), (3, 6), (0, 0), (1, 3). 一条直线上的点最多有3个. ...

  4. 一条直线上N个线段所覆盖的总长度

    原文:http://blog.csdn.net/bxyill/article/details/8962832 问题描述: 现有一直线,从原点到无穷大. 这条直线上有N个线段.线段可能相交. 问,N个线 ...

  5. 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 ...

  6. [小北De编程手记] : Lesson 04 - Selenium For C# 之 API 上

    这一部分,我准备向大家介绍Selenium WebDriver的常用API,学习这部分内容需要大家最好有一些简单的HTML相关知识,本文主要涉及到以下内容: Selenium API:元素检查 Sel ...

  7. lintcode-186-最多有多少个点在一条直线上

    186-最多有多少个点在一条直线上 给出二维平面上的n个点,求最多有多少点在同一条直线上. 样例 给出4个点:(1, 2), (3, 6), (0, 0), (1, 3). 一条直线上的点最多有3个. ...

  8. JS原生上传大文件显示进度条-php上传文件

    JS原生上传大文件显示进度条-php上传文件 在php.ini修改需要的大小: upload_max_filesize = 8M    post_max_size = 10M    memory_li ...

  9. java 判断点是否在一条线段上

    public static void main(String[] args) { Scanner scan = new Scanner(System.in); Point point1 = new P ...

  10. python扩展实现方法--python与c混和编程 转自:http://www.cnblogs.com/btchenguang/archive/2012/09/04/2670849.html

    前言 需要扩展Python语言的理由: 创建Python扩展的步骤 1. 创建应用程序代码 2. 利用样板来包装代码 a. 包含python的头文件 b. 为每个模块的每一个函数增加一个型如PyObj ...

随机推荐

  1. RTE NG-Lab:一起探索下一代实时互动新世界

    互联网已经彻底改变了我们的工作和生活.从纸书信笺,到智能手机中的 App,再到 VR 头显,实时互动体验逐代升级,已经成为了我们生活的一部分.随着元宇宙的爆火,新增的实时互动场景日益颠覆着我们的想象力 ...

  2. java面向对象-基础入门

    java面向对象-基础入门 面向过程:线性思维 面向对象思维:物以类聚,分类的思维 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统,但是具体到某个微观 ...

  3. Java:数据表的字段设计了默认值0不生效的原因

    在数据表里给字段设置了默认值为0,但是在插入的时候不生效,数据表设计如下 通过数据表生成的实体类 查看代码 @Data @TableName(value = "user") @No ...

  4. Maven 自动化构建

    一.Maven:是一款服务于 Java平台的自动化构建工具 [1]Maven可以将一个项目按模块划分成不同的工程,利于分工协作;[2]Maven可以将 jar包保存在自己的中央"仓库&quo ...

  5. 深入消息队列MQ,看这篇就够了!

    大厂面试爱问消息队列 MQ. 因为消息队列MQ,既是大型分布式系统不可缺少的中间件,也是高并发系统的基石中间件. 如果你想要快速掌握消息队列 MQ 最内核的知识,以及消息队列MQ的主流应用场景.主流产 ...

  6. 基于Admin.NET框架的前端的一些改进和代码生成处理(2)

    在上篇随笔<基于Admin.NET框架的前端的一些改进和代码生成处理(1)>中大致介绍了一些关于对Admin.NET框架的前端的改造工作,主要目的就是希望能够增加前端代码的简洁性和可读性, ...

  7. NoSQL之 Redis配置与优化

    目录 一.缓存概念 1.1 系统缓存 1.1.1buffer与cache 1.2 缓存保存位置及分层结构 1.2.1 DNS缓存 1.2.2 应用层缓存 1.2.3数据层缓存 1.2.4 硬件缓存 二 ...

  8. 使用 Azure OpenAI 打造自己的 ChatGPT

    一.前言 当今的人工智能技术正在不断发展,越来越多的企业和个人开始探索人工智能在各个领域中的应用.其中,在自然语言处理领域,OpenAI 的 GPT 系列模型成为了研究热点.OpenAI 公司的 Ch ...

  9. 五月十一号java基础知识点

    1.通过add()方法向链表list输入1-10十个数for (int i = 1; i <11 ; i++) { list.add(i);//向链表添加1-10的整数 } import jav ...

  10. Rust中的into函数和from函数

    1.Rust中的into函数和from函数是做什么用的? into函数是Rust语言中的一个转换函数,它属于Into trait.它可以将一个类型转换为另一个类型.实现了From trait的类型会自 ...