二分查找|雙指針:LeetCode:2398.預算內的最多機器人數目

作者推薦

本文涉及的基礎知識點

二分查找算法合集
滑動窗口
單調隊列:計算最大值時,如果前面的數小,則必定被淘汰,前面的數早出隊。

題目

你有 n 個機器人,給你兩個下標從 0 開始的整數數組 chargeTimes 和 runningCosts ,兩者長度都為 n 。第 i 個機器人充電時間為 chargeTimes[i] 單位時間,花費 runningCosts[i] 單位時間運行。再給你一個整數 budget 。
運行 k 個機器人 總開銷 是 max(chargeTimes) + k * sum(runningCosts) ,其中 max(chargeTimes) 是這 k 個機器人中最大充電時間,sum(runningCosts) 是這 k 個機器人的運行時間之和。
請你返回在 不超過 budget 的前提下,你 最多 可以 連續 運行的機器人數目為多少。
示例 1:
輸入:chargeTimes = [3,6,1,3,4], runningCosts = [2,1,3,4,5], budget = 25
輸出:3
解釋:
可以在 budget 以內運行所有單個機器人或者連續運行 2 個機器人。
選擇前 3 個機器人,可以得到答案最大值 3 。總開銷是 max(3,6,1) + 3 * sum(2,1,3) = 6 + 3 * 6 = 24 ,小于 25 。
可以看出無法在 budget 以內連續運行超過 3 個機器人,所以我們返回 3 。
示例 2:
輸入:chargeTimes = [11,12,19], runningCosts = [10,8,7], budget = 19
輸出:0
解釋:即使運行任何一個單個機器人,還是會超出 budget,所以我們返回 0 。
參數范圍
chargeTimes.length == runningCosts.length == n
1 <= n <= 5 * 104
1 <= chargeTimes[i], runningCosts[i] <= 105
1 <= budget <= 1015

雙指針

分析

本質是子數組,我們可以枚舉起點left ,子數組[left,righ)是不超預算的最長子數組。

時間復雜度

O(n),枚舉left和right都是O(n),right沒有從新開始,所有總時間復雜度是O(n)。

代碼

核心代碼

class Solution {
public:
int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
m_c = chargeTimes.size();
int iRet = 0;
long long llSum = 0;
std::deque vMaxIndex;
for (int left = 0, right = 0; left < m_c; left++)
{
if (right < left)
{
llSum = 0;
right = left;
vMaxIndex.clear();
}
while (right < m_c)
{
while (vMaxIndex.size() && (chargeTimes[vMaxIndex.back()] <= chargeTimes[right]))
{
vMaxIndex.pop_back();
}
vMaxIndex.emplace_back(right);
const long long llNew = (llSum + runningCosts[right]) * (right-left+1) + chargeTimes[vMaxIndex.front()];
if (llNew > budget)
{
break;// [left,right)超出預算,有多個right,取最小的按個
}
llSum += runningCosts[right];
right++;
}
iRet = max(iRet, right - left);
llSum -= runningCosts[left];
if (vMaxIndex.front() == left)
{
vMaxIndex.pop_front();
}
}
return iRet;
}
int m_c;
};

測試用例

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){assert(v1[i] == v2[i]);}
}template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}int main()
{vector<int> chargeTimes, runningCosts;long long budget;{Solution slu;chargeTimes = { 3,6,1,3,4 }, runningCosts = { 2,1,3,4,5 }, budget = 25;auto res = slu.maximumRobots(chargeTimes, runningCosts, budget);Assert(3, res);}{Solution slu;chargeTimes = { 11,12,19 }, runningCosts = { 10,8,7 }, budget = 19;auto res = slu.maximumRobots(chargeTimes, runningCosts, budget);Assert(res, 0);}{Solution slu;chargeTimes = { 19,63,21,8,5,46,56,45,54,30,92,63,31,71,87,94,67,8,19,89,79,25 }, runningCosts = { 91,92,39,89,62,81,33,99,28,99,86,19,5,6,19,94,65,86,17,10,8,42 }, budget = 85;auto res = slu.maximumRobots(chargeTimes, runningCosts, budget);Assert(res, 1);}//CConsole::Out(res);
}

優化

如果不存在以left開始的合法子數組,right和left相同,left++后,right就小于left ,需要特殊處理。
我們換成先枚舉right,再枚舉left。左閉右閉空間[left,right]是最長合法子數組。但不存在合法子數組時:left等于right+1,right++后,兩者就相等了,無需特殊處理。

代碼

class Solution {
public:int maximumRobots(vector<int>& chargeTimes, vector<int>& runningCosts, long long budget) {m_c = chargeTimes.size();int iRet = 0;long long llSum = 0;std::deque<int> vMaxIndex;for (int right = 0, left = 0; right < m_c; right++){	while (vMaxIndex.size() && (chargeTimes[vMaxIndex.back()] <= chargeTimes[right])){vMaxIndex.pop_back();				}vMaxIndex.emplace_back(right);llSum += runningCosts[right];while (left <= right ){		const long long llNew = llSum * (right-left+1) + chargeTimes[vMaxIndex.front()];if (llNew > budget){llSum -= runningCosts[left];if (vMaxIndex.front() == left){vMaxIndex.pop_front();}left++;}else{break;}}iRet = max(iRet, right - left+1);			}return iRet;}int m_c;
};

二分查找

尋找最后一個不超預算的連續機器人長度,左開右閉。時間復雜度😮(longnn)。二分長度,時間復雜度度O(logn);指定長度枚舉所有終點,時間復雜度O(n)。

代碼

class Solution {
public:
int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
m_c = chargeTimes.size();
int left = 0, right = m_c + 1;
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
if (NeedBudget(chargeTimes, runningCosts, mid) <= budget)
{
left = mid;
}
else
{
right = mid;
}
}
return left;
}
long long NeedBudget(vector& chargeTimes, vector& runningCosts, int len)
{
long long llSum = 0;
std::deque vMaxIndex;
int i = 0;
for (; i < len; i++)
{
llSum += runningCosts[i];
while (vMaxIndex.size() && (chargeTimes[vMaxIndex.back()] <= chargeTimes[i]))
{
vMaxIndex.pop_back();
}
vMaxIndex.emplace_back(i);
}
long long llNeed = llSum * len + chargeTimes[vMaxIndex.front()];
for (; i < m_c; i++)
{
llSum += runningCosts[i]- runningCosts[i-len];
while (vMaxIndex.size() && (chargeTimes[vMaxIndex.back()] <= chargeTimes[i]))
{
vMaxIndex.pop_back();
}
vMaxIndex.emplace_back(i);
if (vMaxIndex.front() == i-len)
{
vMaxIndex.pop_front();
}
llNeed = min(llNeed,llSum * len + chargeTimes[vMaxIndex.front()]);
}
return llNeed;
}
int m_c;
};

擴展閱讀

視頻課程

有效學習:明確的目標 及時的反饋 拉伸區(難度合適),可以先學簡單的課程,請移步CSDN學院,聽白銀講師(也就是鄙人)的講解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成戰斗了,為老板分憂,請學習C#入職培訓、C++入職培訓等課程
https://edu.csdn.net/lecturer/6176

相關下載

想高屋建瓴的學習算法,請下載《喜缺全書算法冊》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想對大家說的話
聞缺陷則喜是一個美好的愿望,早發現問題,早修改問題,給老板節約錢。
子墨子言之:事無終始,無務多業

。也就是我們常說的專業的人做專業的事。 |
|如果程序是一條龍,那算法就是他的是睛|

測試環境

操作系統:win7 開發環境: VS2019 C++17
或者 操作系統:win10 開發環境:

VS2022 C++17

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210850.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210850.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210850.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Django回顧7

一.Django緩存 1.緩存介紹 在動態網站中,用戶所有的請求,服務器都會去數據庫中進行相應的增,刪,查,改,渲染模板,執行業務邏輯,最后生成用戶看到的頁面. 當一個網站的用戶訪問量很大的時候,每一次的的后臺操作,都會消耗很多的服務端資源,所以必須使用緩存來減輕后端服務器的壓力…

算法:最長公共前綴(橫向掃描和縱向掃描)

橫向掃描 時間復雜度 O(m * n)&#xff0c;空間復雜度O(1) /*** param {string[]} strs* return {string}*/ var longestCommonPrefix function(strs) {// 先把第一個字符串拿出來let str strs[0]// 用 startsWith 檢查數組中每個字符串是否以當前字符串為前綴while(!strs.e…

聽GPT 講Rust源代碼--src/tools(11)

File: rust/src/tools/rust-analyzer/crates/hir/src/lib.rs 在Rust源代碼中&#xff0c;rust/src/tools/rust-analyzer/crates/hir/src/lib.rs文件的作用是定義了Rust語言的高級抽象層次&#xff08;Higher-level IR&#xff0c;HIR&#xff09;。它包含了Rust語言的各種結構和…

Python:核心知識點整理大全10-筆記

目錄 5.4 使用 if 語句處理列表 5.4.1 檢查特殊元素 toppings.py 5.4.2 確定列表不是空的 5.4.3 使用多個列表 5.5 設置 if 語句的格式 5.6 小結 第6章 字 典 6.1 一個簡單的字典 alien.py 6.2 使用字典 6.2.1 訪問字典中的值 6.2.2 添加鍵—值對 6.2.3 先創建一…

智能優化算法應用:基于蜉蝣算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用&#xff1a;基于蜉蝣算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用&#xff1a;基于蜉蝣算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.蜉蝣算法4.實驗參數設定5.算法結果6.參考文獻7.MA…

JAVA+SSM+springboot+MYSQL企業物資庫存進銷存管理系統

。該系統從兩個對象&#xff1a;由管理員和員工來對系統進行設計構建。主要功能包括首頁、個人中心、員工管理、項目信息管理、倉庫信息管理、供應商管理、項目計劃管理、物資庫存管理、到貨登記管理、物資出庫管理、物資入庫管理等功能進行管理。本企業物資管理系統方便員工快…

linux 定時任務

使用 crontab Usage: crontab [-u user] [-e|-l|-r] Crontab 的格式說明如下: * 逗號(‘,’) 指定列表值。如: “1,3,4,7,8″ * 中橫線(‘-’) 指定范圍值 如 “1-6″, 代表 “1,2,3,4,5,6″ * 星號 (‘*’) 代表所有可能的值 */15 表示每 15 分鐘執行一次 # Use the ha…

C++編程法則365天一天一條(24)RTTI運行時類型信息typeid和type_info

文章目錄 基本用法編譯時或運行時判定 基本用法 typeid 是 C 的一個運算符&#xff0c;它用于獲取表達式的類型信息。它返回一個 std::type_info 對象引用&#xff0c;該對象包含有關表達式的類型的信息。 要使用 typeid 運算符&#xff0c;需要包含 <typeinfo> 頭文件…

關于振動試驗

這是試驗的說明&#xff08;來自gbt4710-2009&#xff09; 這是試驗的參數&#xff1a; 一、試驗方向&#xff1a; 振動試驗中有幾個方向 除有關規范另有規定外&#xff0c;應在產品的三個互相垂直方向上進行振動試驗。 一般定義產品長邊為X軸向&#xff0c;短邊為Y軸向&…

飛書面試題匯總

面試相關經驗 Interview | JavaGuide(Java面試 學習指南) 同學1 7次面試 編程題匯總&#xff1a; 有序鏈表找中位數 &#xff08;飛書1面&#xff09; m個有序數組合并 &#xff08;飛書1面&#xff09; 海量數據尋找TopK&#xff08;口述&#xff09; &#xff08;飛書…

Android 10(Q) 以上普通 APP 隱藏應用圖標問題探究及解決方案

1、實驗環境 aosp 版本 10.0 系統 aosp 版本 13.0 系統 2、驗證結果 2.1 方式一 APP AndroidManifest.xml 中通過 activity-alias 配置帶 LAUNCHER 屬性 category&#xff0c;并且 android:enabled“true” 10.0 系統中可安裝后正常顯示 icon&#xff0c;通過 setComponen…

idea中run和debug是灰色的

【現象】idea中run和debug是灰色的 點擊 旁邊的Add Configuration…一看都是空白 【解決方法】&#xff1a; npm點開之后 【結果】

文本轉圖像 學習筆記

VQGAN (Vector Quantized Generative Adversarial Network) 是一種基于 GAN 的生成模型&#xff0c;可以將圖像或文本轉換為高質量的圖像。 VQ &#xff08;Vector Quantization&#xff09;是一種數據壓縮技術&#xff0c;是指將連續數據表示為離散化的向量。輸入的圖像或文本…

轉換NC或HDF數據時候轉出數據無坐標信息的處理方法

有時候我們在轉換NC或HDF數據時&#xff0c;有時候會出現沒有坐標信息的情況&#xff01;如下圖&#xff1a; 這種情況一般是原始數據將坐標信息存儲在說明文件中以便后期做生成坐標信息的處理、或坐標存儲的形式比較特殊&#xff0c;造成工具無法讀取&#xff01;這種數據處理…

Python迭代器與生成器研究記錄

Python迭代器與生成器研究記錄 前言 迭代器肯定是可迭代對象&#xff0c;但是可迭代對象不一定是迭代器&#xff0c;生成器一定是迭代器&#xff0c;但是迭代器不一定是生成器 生成器是特殊的迭代器&#xff0c;所以生成器一定是迭代器&#xff0c;迭代器一定是可迭代對象 我…

YOLOv8分割訓練及分割半自動標注

YOLOv8是基于目標檢測算法YOLOv5的改進版,它在YOLOv5的基礎上進行了優化和改進,加入了一些新的特性和技術,如切片注意力機制、骨干網絡的選擇等。 本文以yolov8-seg為基準,主要整理分割訓練流程及使用v8分割模型進行半自動標注的過程。 一、v8-seg訓練 1.1 環境配置 github…

【Altera】平臺設計器互連會回壓 AXI 接口怎么辦

說明 實現 AXI 接口的所有組件都具有發行或接受能力設置。每當互連檢測到管理器&#xff08;主管理器&#xff09;發出的事務多于管理器的發行容量設置時&#xff0c;互連將通過斷言 AxREADY 向管理器背壓。每當互連檢測到從屬&#xff08;從站&#xff09;接收的事務多于從屬的…

實用篇 | 一文快速構建人工智能前端展示streamlit應用

----------------------- &#x1f388;API 相關直達 &#x1f388;-------------------------- &#x1f680;Gradio: 實用篇 | 關于Gradio快速構建人工智能模型實現界面&#xff0c;你想知道的都在這里-CSDN博客 &#x1f680;Streamlit :實用篇 | 一文快速構建人工智能前端展…

Activity從下往上彈出視差效果實現

其實這篇文章是轉至簡書上的大佬的&#xff0c;加上我自己的代碼實踐了下發現可行&#xff0c;于是就分享下 先看效果 介紹: 其實有很多方法都可以實現這種效果&#xff0c;popwindow&#xff0c;Dialog&#xff0c;BottomSheetDialogFragment&#xff0c;BottomSheetDialog等…