2023-05-19:汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。

沿途有加油站,每个 station[i] 代表一个加油站,

它位于出发位置东面 station[i][0] 英里处,并且有 station[i][1] 升汽油。

假设汽车油箱的容量是无限的,其中最初有 startFuel 升燃料。

它每行驶 1 英里就会用掉 1 升汽油。

当汽车到达加油站时,它可能停下来加油,将所有汽油从加油站转移到汽车中。

为了到达目的地,汽车所必要的最低加油次数是多少?如果无法到达目的地,则返回 -1 。

注意:如果汽车到达加油站时剩余燃料为 0,它仍然可以在那里加油。

如果汽车到达目的地时剩余燃料为 0,仍然认为它已经到达目的地。

输入:target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]。

输出:2。

答案2023-05-19:

具体步骤如下:

1.初始化车内油量 to 和已经加得次数 cnt。

2.遍历所有加油站,对于每个加油站,判断能否到达。如果不能到达,就从大根堆中不断取出油量添加到车内,直至可以到达该加油站或无法再添加油量为止。如果无法到达该加油站,则无法到达目标位置,返回-1。

3.如果能够到达该加油站,则将该加油站的油量添加到大根堆中,并继续向前移动。

4.如果无法到达目标位置,则不断从大根堆中取出油量,直至能够到达目标位置或者大根堆为空为止。

5.返回已经加油的次数。

时间复杂度:O(nlogn),其中n为加油站的数量。主要是因为该算法使用了堆来维护加油站的油量,每次需要考虑哪个加油站的油量最多,以便优先选择加油量最大的加油站。

空间复杂度:O(n),其中n为加油站的数量。主要是因为该算法使用了堆存储加油站的油量,所以需要额外的空间存储堆中的元素。

go完整代码如下:

package main

import (
"container/heap"
) func minRefuelStops(target int, startFuel int, stations [][]int) int {
if startFuel >= target {
return 0
} // 大根堆
// 维持的是:最值得加油的加油站,有多少油
// 最值得:加得次数少,跑的还最远
h := &IntHeap{}
heap.Init(h) // 当前车里的油,能达到的位置
to := startFuel
cnt := 0 for _, station := range stations {
position := station[0]
fuel := station[1] if to < position {
for !h.IsEmpty() && to < position {
to += heap.Pop(h).(int)
cnt++
if to >= target {
return cnt
}
}
if to < position {
return -1
}
}
heap.Push(h, fuel)
} // 最后一个加油站的位置,都达到了
// 但还没有到target
for !h.IsEmpty() {
to += heap.Pop(h).(int)
cnt++
if to >= target {
return cnt
}
} return -1
} func main() {
target := 100
startFuel := 10
stations := [][]int{{10, 60}, {20, 30}, {30, 30}, {60, 40}}
result := minRefuelStops(target, startFuel, stations)
println(result)
} // IntHeap实现大根堆
type IntHeap []int func (h IntHeap) Len() int {
return len(h)
} func (h IntHeap) Less(i, j int) bool {
return h[i] > h[j]
} func (h IntHeap) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
} func (h *IntHeap) Push(x interface{}) {
*h = append(*h, x.(int))
} func (h *IntHeap) Pop() interface{} {
n := len(*h)
x := (*h)[n-1]
*h = (*h)[:n-1]
return x
} func (h *IntHeap) IsEmpty() bool {
return h.Len() == 0
}

rust完整代码如下:

use std::collections::BinaryHeap;

fn min_refuel_stops(target: i32, start_fuel: i32, stations: Vec<Vec<i32>>) -> i32 {
if start_fuel >= target {
return 0;
} // 大根堆
// 维持的是:最值得加油的加油站,有多少油
// 最值得:加得次数少,跑的还最远
let mut heap = BinaryHeap::new(); // 当前车里的油,能达到的位置
let mut to = start_fuel as i64;
let mut cnt = 0; for station in stations.iter() {
let position = station[0] as i64;
let fuel = station[1] as i64; if to < position {
while !heap.is_empty() && to < position {
to += heap.pop().unwrap();
cnt += 1;
if to >= target as i64 {
return cnt;
}
}
if to < position {
return -1;
}
}
heap.push(fuel);
} // 最后一个加油站的位置,都达到了
// 但还没有到target
while !heap.is_empty() {
to += heap.pop().unwrap();
cnt += 1;
if to >= target as i64 {
return cnt;
}
} -1
} fn main() {
let target = 100;
let start_fuel = 10;
let stations = vec![vec![10, 60], vec![20, 30], vec![30, 30], vec![60, 40]];
let result = min_refuel_stops(target, start_fuel, stations);
println!("{}", result);
}

c语言完整代码如下:

#include <stdio.h>
#include <stdlib.h> // IntHeap实现大根堆,这里用函数指针代替仿函数
int cmp(int a, int b) {
return a < b;
} // 交换两个数的值
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
} typedef struct IntHeap {
int (*cmp)(int, int); void (*swap)(int*, int*); int* data;
int size;
int capacity;
}IntHeap; // 初始化大根堆
void initHeap(IntHeap* heap, int (*cmp)(int, int)) {
heap->cmp = cmp;
heap->swap = &swap;
heap->data = (int*)malloc(sizeof(int) * 128);
heap->size = 0;
heap->capacity = 128;
} // 扩容
void resize(IntHeap* heap) {
int newCapacity = heap->capacity * 2;
int* newData = (int*)realloc(heap->data, sizeof(int) * newCapacity);
heap->data = newData;
heap->capacity = newCapacity;
} // 堆化
void down(IntHeap* heap, int i) {
while (i * 2 + 1 < heap->size) {
int left = i * 2 + 1;
int right = i * 2 + 2;
int j = left;
if (right < heap->size && heap->cmp(heap->data[right], heap->data[left])) {
j = right;
}
if (heap->cmp(heap->data[i], heap->data[j])) {
break;
}
heap->swap(&heap->data[i], &heap->data[j]);
i = j;
}
} // 入堆
void pushHeap(IntHeap* heap, int val) {
if (heap->size == heap->capacity) {
resize(heap);
}
heap->data[heap->size++] = val; int i = heap->size - 1;
while (i > 0) {
int p = (i - 1) / 2;
if (heap->cmp(heap->data[p], heap->data[i])) {
break;
}
heap->swap(&heap->data[p], &heap->data[i]);
i = p;
}
} // 弹出堆顶元素
int popHeap(IntHeap* heap) {
int top = heap->data[0];
heap->data[0] = heap->data[--heap->size];
down(heap, 0);
return top;
} int minRefuelStops(int target, int startFuel, int** stations, int stationsSize, int* stationsColSize) {
if (startFuel >= target) {
return 0;
} // 大根堆
// 维持的是:最值得加油的加油站,有多少油
// 最值得:加得次数少,跑的还最远
IntHeap heap;
initHeap(&heap, &cmp); // 当前车里的油,能达到的位置
long long to = startFuel;
int cnt = 0; for (int i = 0; i < stationsSize; i++) {
int position = stations[i][0];
int fuel = stations[i][1]; if (to < position) {
while (heap.size && to < position) {
to += popHeap(&heap);
cnt++;
if (to >= target) {
return cnt;
}
}
if (to < position) {
return -1;
}
}
pushHeap(&heap, fuel);
} // 最后一个加油站的位置,都达到了
// 但还没有到 target
while (heap.size) {
to += popHeap(&heap);
cnt++;
if (to >= target) {
return cnt;
}
} return -1;
} int main() {
int target = 100;
int startFuel = 10;
int** stations = (int**)malloc(sizeof(int*) * 4);
int stationsColSize[4] = { 2, 2, 2, 2 };
for (int i = 0; i < 4; i++) {
stations[i] = (int*)malloc(sizeof(int) * 2);
}
stations[0][0] = 10;
stations[0][1] = 60;
stations[1][0] = 20;
stations[1][1] = 30;
stations[2][0] = 30;
stations[2][1] = 30;
stations[3][0] = 60;
stations[3][1] = 40;
int result = minRefuelStops(target, startFuel, stations, 4, stationsColSize);
printf("%d\n", result); for (int i = 0; i < 4; i++) {
free(stations[i]);
}
free(stations); return 0;
}

c++完整代码如下:

#include <iostream>
#include <vector>
#include <queue>
using namespace std; // IntHeap实现大根堆
struct IntHeap {
bool operator()(int a, int b) { return a < b; }
}; int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {
if (startFuel >= target) {
return 0;
} // 大根堆
// 维持的是:最值得加油的加油站,有多少油
// 最值得:加得次数少,跑的还最远
priority_queue<int, vector<int>, IntHeap> heap; // 当前车里的油,能达到的位置
long long to = startFuel;
int cnt = 0; for (auto station : stations) {
int position = station[0];
int fuel = station[1]; if (to < position) {
while (!heap.empty() && to < position) {
to += heap.top();
heap.pop();
cnt++;
if (to >= target) {
return cnt;
}
}
if (to < position) {
return -1;
}
}
heap.push(fuel);
} // 最后一个加油站的位置,都达到了
// 但还没有到target
while (!heap.empty()) {
to += heap.top();
heap.pop();
cnt++;
if (to >= target) {
return cnt;
}
} return -1;
} int main() {
int target = 100;
int startFuel = 10;
vector<vector<int>> stations = { {10, 60}, {20, 30}, {30, 30}, {60, 40} };
int result = minRefuelStops(target, startFuel, stations);
cout << result << endl;
return 0;
}

2023-05-19:汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。 沿途有加油站,每个 station[i] 代表一个加油站, 它位于出发位置东面 station[i][的更多相关文章

  1. 2023 01 19 HW

    2023 01 19 HW Okay, then let's start.  Okay. Maybe Karina, we start with the C2 design freeze. Yeah, ...

  2. [LeetCode] Minimize Max Distance to Gas Station 最小化去加油站的最大距离

    On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...

  3. 【转载】Spring Boot【快速入门】2019.05.19

    原文出处:https://www.cnblogs.com/wmyskxz/p/9010832.html   Spring Boot 概述 Build Anything with Spring Boot ...

  4. Perl: hash散列转换为Json报错集, perl.c,v $$Revision: 4.0.1.8 $$Date: 1993/02/05 19:39:30 $

    bash-2.03$ ./u_json.pl Can't locate object method "encode" via package "JSON" at ...

  5. 2016/05/19 thinkphp 3.2.2 文件上传

    显示效果:  多文件上传.  这里是两个文件一起上传 上传到文件夹的效果: ①aa为调用Home下common文件夹下的function.php  中的rname方法  实现的 ②cc为调用与Home ...

  6. 【转载】Spring学习(1)——快速入门--2019.05.19

    原文地址:https://www.cnblogs.com/wmyskxz/p/8820371.html   认识 Spring 框架 Spring 框架是 Java 应用最广的框架,它的成功来源于理念 ...

  7. Fitness - 05.19

    倒计时226天 运动45分钟,共计9组,4.7公里.拉伸10分钟. 每组跑步3分钟(6.5KM/h),走路2分钟(5.5KM/h). 上周的跑步计划中断了,本周重复第三阶段的跑步计划. 一共掉了10斤 ...

  8. [Swift]LeetCode871. 最低加油次数 | Minimum Number of Refueling Stops

    A car travels from a starting position to a destination which is target miles east of the starting p ...

  9. LeetCode 871 - 最低加油次数 - [贪心+优先队列]

    汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处. 沿途有加油站,每个 station[i] 代表一个加油站,它位于出发位置东面 station[i][0] 英里处,并且有 s ...

  10. LeetCode之Weekly Contest 93

    第一题:二进制间距 问题: 给定一个正整数 N,找到并返回 N 的二进制表示中两个连续的 1 之间的最长距离. 如果没有两个连续的 1,返回 0 . 示例 1: 输入:22 输出:2 解释: 22 的 ...

随机推荐

  1. xshell无法调用gdc

    现象: <topprod:/u1/topprod/tiptop> exe2 p_zzExecute program:p_zz<topprod:/u1/topprod/tiptop&g ...

  2. [WPF]原生TabControl控件实现拖拽排序功能

    在UI交互中,拖拽操作是一种非常简单友好的交互.尤其是在ListBox,TabControl,ListView这类列表控件中更为常见.通常要实现拖拽排序功能的做法是自定义控件.本文将分享一种在原生控件 ...

  3. ORB-SLAM3测试

    (一)环境搭建教程 1.Ubuntu18.04从零开始搭建orb slam3及数据集测试:https://blog.csdn.net/Skether/article/details/131320852 ...

  4. 数据结构与算法 | 深搜(DFS)与广搜(BFS)

    深搜(DFS)与广搜(BFS) 在查找二叉树某个节点时,如果把二叉树所有节点理理解为解空间,待找到那个节点理解为满足特定条件的解,对此解答可以抽象描述为: 在解空间中搜索满足特定条件的解,这其实就是搜 ...

  5. calico网络异常,不健康

    解决calico/node is not ready: BIRD is not ready: BGP not established withxxx calico有一个没有ready,查了一下是没有发 ...

  6. P4870 [BalticOI 2009 Day1]甲虫 题解

    题目链接 简要题意 在一个数轴上有 \(n\) 滴露水,每滴露水初始水量为 \(m\),每秒会蒸发一滴水,一个甲虫初始在原点,速度为 1,水能瞬间喝完,问它最多能喝到几滴水. 题目分析 对于这种移动区 ...

  7. QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托

    1 写在前面的话 我们在之前写的<QT(7)-初识委托>文章末尾提到,"使用一个类继承QStyledItemDelegate实现常用的控件委托,在使用时可以直接调用接口,灵活实现 ...

  8. go 中如何实现定时任务

    定时任务简介 定时任务是指按照预定的时间间隔或特定时间点自动执行的计划任务或操作.这些任务通常用于自动化重复性的工作,以减轻人工操作的负担,提高效率.在计算机编程和应用程序开发中,定时任务是一种常见的 ...

  9. Java实现两字符串相似度算法

    1.编辑距离 编辑距离:是衡量两个字符串之间差异的度量,它表示将一个字符串转换为另一个字符串所需的最少编辑操作次数(插入.删除.替换). 2.相似度 计算方法可以有多种,其中一种常见的方法是将编辑距离 ...

  10. 哪一个更好?Spring boot还是Node.js

    前言 本篇文章有些与众不同,由于我自己手头有些关于这个主题的个人经验,受其启发写出此文.虽然SpringBoot和Node.js服务于很不一样的场景,但是这两个框架共性惊人.其实每种语言都有不计其数的 ...