美团--美团骑手包裹区间分组
生活随笔
收集整理的這篇文章主要介紹了
美团--美团骑手包裹区间分组
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
美團–美團騎手包裹區間分組
文章目錄
- 美團--美團騎手包裹區間分組
- 一、題目描述
- 二、分析
- 三、代碼
一、題目描述
2110年美團外賣火星第3000號配送站點有26名騎手,分別以大寫字母A-Z命名,因此可以稱呼這些騎手為黃家騎士特工A,黃家騎士特工B…黃家騎士特工Z,某美團黑珍珠餐廳的外賣流水線上會順序產出一組包裹,美團配送調度引擎已經將包裹分配到騎手,并在包裹上粘貼好騎手名稱,如RETTEBTAE代表一組流水線包裹共9個,同時分配給了名字為A B E R T的5名騎手。請在不打亂流水線產出順序的情況下,把這組包裹劃分為盡可能多的片段,同一個騎手只會出現在其中的一個片段,返回一個表示每個包裹片段的長度的列表。
- 輸入描述:
- 輸出描述:
二、分析
- 這個問題有點像求每個連續區間的長度,而每個連續區間都是由小區間的覆蓋連接組合起來的,每個字母第一次和最后一次出現的位置構成一個個小區間
- 所以我們可以先記錄每個字母最后一次出現的位置:
- 現在我們只需要遍歷一個個小區間即可
- 現在需要注意的問題是我們知道了每個字符的最后一次出現的位置,但是在一個字符第一次出現的位置和最后一次出現的位置之間還可能出現其他字符
- 那么我們需要判斷在一個字符區間中間出現的字符最后一次出現的位置是否超過本次區間的最后一次出現的位置
三、代碼
#include <iostream> #include <vector> using namespace std;int divide(string S, int start, int end,int letterRight[26]) {//代表該字符所表示的區間左邊界int left = start;//代表該字符所表示區間的右邊界int right = letterRight[S[left] - 'A'];//遍歷該字符所表示的整個區間for (int i = left + 1; i <= right; i++){//如果出現該區間中間的字符所表示的區間的右邊界超過right//那么我們就需要更新right繼續判斷,從而獲得整個區間的長度if (letterRight[S[i] - 'A'] > right) right = letterRight[S[i] - 'A'];}return right - left+1;}vector<int> partitionLabels(string S) {//保存每個字符最后一次出現的位置int letterRight[26];//保存每個區間的長度vector<int> result;//統計每個字符最后一次出現的位置for (int i = 0; i < 26; i++){int t = S.find_last_of((char)( i + 'A'));letterRight[i] = t;}//字符所表示區間的開始int start = 0; //字符所表示區間的結束int end = S.size(); //表示該小區間最終的長度int tmp;while (start < end){//得到滿足題意:同一個字符只存在一個區間;的區間長度//并保存到result當中tmp = divide(S, start, end, letterRight);result.push_back(tmp);//注意注意??,一旦從前往后遍歷找到一個區間,一定要更新start的值//不一定再從下一個位置繼續判斷,因為可能下一個字符的位置在區間的中間,//那么該字符肯定已經被計算到區間長度當中,不用多次計算start += tmp;}return result; } int main() {string str;getline(cin, str);vector<int> result = partitionLabels(str);//打印結果for (int i = 0; i < result.size(); i++){cout<<result[i]<<" ";}return 0; }總結
以上是生活随笔為你收集整理的美团--美团骑手包裹区间分组的全部內容,希望文章能夠幫你解決所遇到的問題。