1、https://leetcode.cn/problems/gas-station/submissions/514930619/?envType=study-plan-v2&envId=top-interview-150 對於這個問題可以這樣來考慮,將數據看作一個環,如果答案唯一,那麼就意味著從任 ...
1、https://leetcode.cn/problems/gas-station/submissions/514930619/?envType=study-plan-v2&envId=top-interview-150
對於這個問題可以這樣來考慮,將數據看作一個環,如果答案唯一,那麼就意味著從任意一個節點開始尋找,最後都會得到同一個節點的答案,那麼為何不直接從0節點開始呢?
其次,我們可以建立一個total變數來記錄總的油量和消耗量的差的結果,倘若這個值小於0,則一定沒有解,倘若大於零,則說明一定有解。
繼續這個思路,當有解時,我們不妨從i節點出發,設置一個temp變數記錄從i開始到j的剩餘油量。當temp小於0時,說明現在到達的節點j是可以到達的,但是無法到達j+1節點,那麼下次的起點就可以從j+1開始重覆這個過程。
為什麼?
不妨這樣考慮,i到j構成一個弧,同樣,我們假設當前的問題是無解的,那麼我們應該可以用上述方式將j與j+1斷開,把環分成許多的弧。當然我們這裡假設的無解,其實從total就可以看出。那麼假如現在我們發現total大於0了,我們還可以將環分割成這樣的弧嗎?我們不妨0開始,一直分割,假設前面我們分割成了許多弧,最後從某個節點k開始一直遍歷完了卻再也沒有分割出弧。那麼這個末尾的弧可以和第一個弧鏈上嗎?當然可以!假設不可以的話,那麼我們每個弧最終的剩餘油量都不足以支持它到達下一個弧,那麼total不就是小於0了嗎?但我們已經得到了total大於0,所以最後一個弧一定可以和第一個弧連起來,接下來兩個弧變成一個弧,我們將這個新弧看作最後一個弧,那麼他和現在的新的第一個弧會怎麼樣呢,同理,他們還是可以連起來的!由此我們的演算法就明確了:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len = gas.size();
vector<int> remaind(len);
int total = 0,temp = 0;
int start = 0;
for(int i=0;i<len;i++){
total=total+gas[i]-cost[i];
temp = temp+gas[i]-cost[i];
if(temp<0){
temp=0;
start=i+1;
}
}
return total<0?-1:start;
}
};
2、https://leetcode.cn/problems/candy/submissions/514952725/?envType=study-plan-v2&envId=top-interview-150
對於這個問題,我們觀察數組,會發現第一個和最後一個元素非常特殊,因為它們只有一個元素和自己相鄰,如果其餘元素都確定了,那麼它們也就確定了,所以我們不妨從第二個和倒數第二個元素開始處理,我們設置兩個變數j,i它們分別從第二個以及倒數第二個開始向後向前遍歷,並且它們會分別比較自己的j-1以及i+1元素,倘若比它們小則不變,大於則比較現在的糖果數量,若是少了則改變糖果數量。最後每個元素都會和自己左右兩個相鄰的元素比較。
class Solution {
public:
int candy(vector<int>& ratings) {
int len=ratings.size();
vector<int> candy(len);
int total=0;
for(int i=len-2,j=1;i>=0;i--,j++){
if(ratings[i]>ratings[i+1]){
if(candy[i]<=candy[i+1]){
total=total+candy[i+1]+1-candy[i];
candy[i]=candy[i+1]+1;
}
}
if(ratings[j]>ratings[j-1]){
if(candy[j]<=candy[j-1]){
total=total+candy[j-1]+1-candy[j];
candy[j]=candy[j-1]+1;
}
}
}
total = total+len;
return total;
}
};
本文由博客一文多發平臺 OpenWrite 發佈!