如有缺漏谬误,还请批评指正。
1.买卖股票的最佳时机
低价买入,高价卖出,贪心寻找最优解。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int maxv=0;
int minv=INT_MAX;
int n=prices.size();
for(int i=0;i<n;i++){
minv=min(minv,prices[i]);
maxv=max(maxv,prices[i]-minv);
}
return maxv;
}
};
2.跳跃游戏
引入变量maxv记录当前节点所能跳到的最远距离,每次跳跃时更新最远距离,最终如果最远距离超过终点,说明可达,返回true。否则返回false。
class Solution {
public:
bool canJump(vector<int>& nums) {
int n=nums.size();
int maxv=0;
for(int i=0;i<=maxv;i++){
maxv=max(maxv,i+nums[i]);
if(maxv>=n-1) return true;
}
return false;
}
};
3.跳跃游戏II
为了让跳数最少,在不得不跳时才会跳一次。
class Solution {
public:
int jump(vector<int>& nums) {
int n=nums.size();
if(n<=1) return 0;
int dest=0,cnt=0,ed=0;
for(int i=0;i<n-1;i++){
dest=max(dest,i+nums[i]);
//不得不跳时才跳
if(i==ed){
cnt++;
ed=dest;
if(ed>=n-1) return cnt;
}
}
return cnt;
}
};
4.划分字母区间
本质上是区间合并问题:有重叠的区间需要进行合并,最后留下的区间是不重叠的独立子区间。
(1)每个字符对应一个区间
(2)合并重叠区间,最后不重叠区间就是答案
class Solution {
public:
vector<int> partitionLabels(string s) {
unordered_map<char,int> last; //记录字符最后出现的位置
int n=s.size();
for(int i=0;i<n;i++) last[s[i]]=i;
vector<int> res;
int st=0,ed=0;
for(int i=0;i<n;i++){
ed=max(ed,last[s[i]]); //更新当前区间的结束位置
if(i==ed){ //到达当前区间的末尾
res.push_back(ed-st+1); //区间长度
st=i+1; //新区间的起始位置
}
}
return res;
}
};