連接:https://leetcode-cn.com/contest/weekly-contest-153/ 環形公交路線上有 n 個站,按次序從 0 到 n - 1 進行編號。咱們已知每一對相鄰公交站之間的距離,distance[i] 表示編號爲 i 的車站和編號爲 (i + 1) % n 的車站之間的距離。 環線上的公交車均可以按順時針和逆時針的方向行駛。 返回乘客從出發點 start 到目的地 destination 之間的最短距離。算法
思路:看代碼數組
class Solution { public: int distanceBetweenBusStops(vector<int>& distance, int start, int destination) { int n=distance.size(); int len=0; for(int i=0;i<n;++i)len+=distance[i]; int dist=0; for(int i=start;i<destination;++i)dist+=distance[i]; for(int i=destination;i<start;++i)dist+=distance[i]; return min(dist,len-dist); } };
給你一個日期,請你設計一個算法來判斷它是對應一週中的哪一天。 輸入爲三個整數:day、month 和 year,分別表示日、月、年。 您返回的結果必須是這幾個值中的一個 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}。設計
思路:看代碼(1971年1月1日,星期五code
class Solution { public: string dayOfTheWeek(int day, int month, int year) { int mon[]={31,28,31,30,31,30,31,31,30,31,30,31}; string d[]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; int len=4; for(int i=1971;i<year;++i){ len=(len+365)%7; if(is_year(i)) len=(len+1)%7; } for(int i=1;i<month;++i){ if(is_year(year)&&i==2)len=(len+1)%7; len=(len+mon[i-1])%7; } len=(len+day)%7; return d[len]; } bool is_year(int year){ if(((year%4==0)&&(year%100!=0))||(year%400==0)) return true; return false; } };
給你一個整數數組,返回它的某個 非空 子數組(連續元素)在執行一次可選的刪除操做後,所能獲得的最大元素總和。 換句話說,你能夠從原數組中選出一個子數組,並能夠決定要不要從中刪除一個元素(只能刪一次哦),(刪除後)子數組中至少應當有一個元素,而後該子數組(剩下)的元素總和是全部子數組之中最大的。 注意,刪除一個元素後,子數組 不能爲空。索引
思路一: 1.這裏left[i]表示的是以自身爲右端點的一個連續區間段的最大值,right[i]相同 2.在求left[i]時能夠順帶求不刪除一個區間段的一個值的答案來更新答案。 3.最後求刪除arr[i]時的狀況leetcode
class Solution { public: int maximumSum(vector<int>& arr) { if(arr.size()==1)return arr[0];//特殊狀況 int n=arr.size(); vector<int> left(n+1); vector<int> right(n+1); left[0]=arr[0]; int ans=arr[0]; for(int i=1;i<n;++i){ left[i]=max(left[i-1]+arr[i],arr[i]);//不刪除 ans=max(ans,left[i]); } right[n-1]=arr[n-1]; for(int i=n-2;i>=0;i--){ right[i]=max(right[i+1]+arr[i],arr[i]); } for(int i=0;i<n;++i){//刪除arr[i] int l=0,r=0; if(i-1>=0){ l=left[i-1]; } if(i+1<n){ r=right[i+1]; } ans=max(ans,l+r); } return ans; } };
思路二: 1.g[i]表示以i結尾且刪除了一個元素的序列和 2.f[i]表示以i結尾且一個也不刪除的序列和 3.狀態轉移:f[i]第i位能夠和前面加在一塊兒,也能夠另起一個新的序列 g[i]第i位能夠刪除本身和前面f[i-1],不刪的話就是g[i]+當前數 4.答案更新:在ans和f[i],g[i]中取最大值get
class Solution { public: int maximumSum(vector<int>& arr) { int n=arr.size(); if(n==1)return arr[0]; vector<int> f(n),g(n); f[0]=arr[0]; g[0]=0; int ans=arr[0]; for(int i=1;i<n;++i){ f[i]=max(f[i-1]+arr[i],arr[i]); g[i]=max(f[i-1],g[i-1]+arr[i]); ans=max(ans,max(f[i],g[i])); } return ans; } };
給你兩個整數數組 arr1 和 arr2,返回使 arr1 嚴格遞增所須要的最小「操做」數(可能爲 0)。 每一步「操做」中,你能夠分別從 arr1 和 arr2 中各選出一個索引,分別爲 i 和 j,0 <= i < arr1.length 和 0 <= j < arr2.length,而後進行賦值運算 arr1[i] = arr2[j]。 若是沒法讓 arr1 嚴格遞增,請返回 -1。string
思路: 1.f[i][j]表示前i位經歷j次操做達到的最小值 2.狀態轉移:f[i][j]對第i位不進行操做,那麼f[i-1][j]<arr1[i]就能夠轉移 若對第i位操做,f[i-1][j-1]如果成功操做過(!=INT_MAX),那麼就能夠在arr2裏面找數進行賦值操做 3.答案在f[n-1][j]裏面尋找,看最小j是否操做過it
class Solution { public: int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) { int n=arr1.size(); int m=arr2.size(); sort(arr2.begin(),arr2.end()); vector<vector<int>> f(n+1,vector<int>(n+1,INT_MAX));//f[i][j]表示前i位經歷j次賦值的最小值,j<=i+1 f[0][1]=arr2[0]; f[0][0]=arr1[0]; for(int i=1;i<n;++i){ for(int j=0;j<=i+1;++j){ if(f[i-1][j]<arr1[i]){ f[i][j]=min(f[i][j],arr1[i]); } if(j-1>=0){ int t=f[i-1][j-1]; if(t<INT_MAX){ auto it = upper_bound(arr2.begin(),arr2.end(),t); if(it!=arr2.end()){ f[i][j]=min(f[i][j],*it); } } } } } for(int j=0;j<=n;++j){ if(f[n-1][j]!=INT_MAX) return j; } return -1; } };