贪心:只要把每一个上升区间都吃到手,就能一直赚
class Solution {
public:int maxProfit(vector<int>& prices) {int res = 0;for(int i = 1;i< prices.size();i++){int diff = prices[i] - prices[i-1];if(prices[i] > prices[i-1]){res += diff;}}return res;}
};
我用的是类似dp递推的解法,也就是说从出发点跳到某个位置的最小步数,来自于从出发点跳到前面这些前驱的最小步数+1,但是这个办法每一轮都要查看前面所有节点,因为节点跳跃值是不确定的,O(n^2)
class Solution {
public:vector<int> dp;void resInit(vector<int>& nums){vector<int> dpTem(nums.size(),INT_MAX);dp = dpTem;}int jump(vector<int>& nums) {resInit(nums);dp[0] = 0;for(int i = 1;i< nums.size();i++){for(int j = i-1;j>= 0;j--){if(dp[j] == INT_MAX){continue;}if(j + nums[j] >= i){dp[i] = min(dp[j] + 1,dp[i]);}} }return dp[nums.size()-1];}
};
实际上,好的解法应该是一个类似于覆盖问题的做法,也就是说,第一步在第零步的基础上跳出,找出第一步的范围,如果还没到,就在第一步的基础上找第二步得得范围,,这就是一个O(n)
这道题其实也可以用一点递推的思路来做,从后往前,查找离出发点index = 0
更近的 “可以到达终点的位置”,只是求一条可行通路,不用管开销,就可以这样硬推
class Solution {
public:vector<bool> dp;void resInit(vector<int>& nums){vector<bool> dpTem(nums.size(),false);dp = dpTem;dp[nums.size()-1] = true;}bool canJump(vector<int>& nums) {resInit(nums);int nextIdx = nums.size()-1;for(int i = nums.size()-2;i >= 0;i--){if(nums[i] + i >= nextIdx){dp[i] = true;nextIdx = i;}}return dp[0];}
};
实际上,这还是一个覆盖问题,在前一步的基础上推出后一步的范围,看看能不能把终点覆盖,可以就是返回true