- class Solution {
- public:
- int maxProfit(vector<int>& prices) {
- vector
int>> dp(prices.size(), vector<int>(2, 0)); -
- //0表示不持有, 1表示持有
- dp[0][0] = 0;
- dp[0][1] = -prices[0];
-
- for(int i=1; i
size(); i++){ - dp[i][0] = max(dp[i-1][1]+prices[i], dp[i-1][0]);
- dp[i][1] = max(dp[i-1][0]-prices[i], dp[i-1][1]);
- }
-
- return dp[prices.size()-1][0];
- }
- };
- class Solution {
- public:
- bool canJump(vector<int>& nums) {
- if(nums[0] == 0 && nums.size() > 1) return false;
- vector<int> dp(nums.size(), 0);
-
- dp[0] = nums[0];
- for(int i=1; i
size(); i++){ - dp[i] = max(nums[i], dp[i-1]-1);
- if(dp[i] <= 0 && i != nums.size()-1) return false;
- }
- return true;
- }
- };
出现的错误:
1.要注意特殊情况, 如果数组中只有一个数字
2.最后一位是不需要考虑的,因为已经到最后了
其他做法:
- class Solution {
- public:
- bool canJump(vector<int>& nums) {
- int farthestNum = 0;
-
- for(int i=0; i
size()-1; i++){ - farthestNum = max(farthestNum, i+nums[i]);
- if(farthestNum <= i){
- return false;
- }
- }
- return true;
- }
- };
好处:不需要数组存储,并且不需要考虑特殊情况了
- class Solution {
- public:
- int jump(vector<int>& nums) {
- int res = 0;
- int step = 0;
- int farthest = 0;
-
- for(int i=0; i
size()-1; i++){ - farthest = max(farthest, nums[i]+i);
- if(step == i){
- step = farthest;
- res++;
- }
- }
-
- return res;
- }
- };
这道题的关键是想到,要用一个数字来记录选择的跳跃步数
- class Solution {
- public:
- int hIndex(vector<int>& citations) {
- sort(citations.begin(), citations.end());
- int start = 0, end = citations.size()-1;
- int avg;
- while(start <= end){
- avg = (start+end)/2;
- if(citations[avg] >= citations.size()-avg) end = avg-1;
- else start = avg+1;
- }
- return citations.size()-start;
- }
- };
运用二分搜索,但感觉思路很绕
- class Solution {
- public:
- int candy(vector<int>& ratings) {
- if(ratings.size() == 1) return 1;
- vector<int> candies(ratings.size(), 1);
-
- for(int i=1; i
size(); i++){ - if(ratings[i] > ratings[i-1])
- candies[i] = candies[i-1]+1;
- }
- int sum = candies[ratings.size() - 1];
- for(int i = ratings.size()-2; i>=0; i--){
- if(ratings[i] > ratings[i+1]){
- candies[i] = max(candies[i], candies[i+1]+1);
- }
- sum += candies[i];
- }
-
- return sum;
- }
- };
这道题因为要考虑左右两边,所以要从左到右遍历一次,也要从右到左遍历一次
2.peak and valley
- class Solution {
- public:
- int candy(vector<int>& ratings) {
- int n = ratings.size();
- int candy = n, i = 1;
- while(i < n){
- if(ratings[i] == ratings[i-1]){
- i++;
- continue;
- }
-
- int peak = 0;
- while(ratings[i] > ratings[i-1]){
- peak++;
- candy += peak;
- i++;
- if(i == n) return candy;
- }
-
- int valley = 0;
- while(i < n && ratings[i] < ratings[i-1]){
- valley++;
- candy += valley;
- i++;
- }
-
- candy -= min(peak, valley);
- }
- return candy;
- }
- };
可以想象成山峰山谷,当上升时(ratings[i] > ratings[i-1]), 那么这个人就要比前一个人多拿一个,下降时,前一个人要比后面的多拿一个(如果只看计算,那么就可以想象成+1即可),这样算完后会有一个问题就是, 每一个山峰会多算一次(peak和valley各算了一次), 为了两边都满足,peak要取两边的最大值,也就是说在计算上,要减去小的值