代码随想录算法训练营第二十八天 | 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和

122.买卖股票的最佳时机II  

       因为可以在同一点购买出售,所以只要保证第二天卖出有利润,都可以买入,反映到数组上条件为nums[i] < nums[i+1],然后把所有利润累加。

class Solution {
public:
    int maxProfit(vector<int>& nums) {
        int sum = 0;
        for(int i = 0; i < nums.size() - 1; ++i) {
            if(nums[i] < nums[i+1]) {
                sum += nums[i+1] - nums[i];
            } 
        }
        return sum;
    }
};

55. 跳跃游戏

        判断跨越区间是否能覆盖最后一个元素,如果能就返回true,不能就返回false;

        但是疏忽了一点,当有元素为0时,不能保证一定能跳到后面的元素。比如说[3,2,1,0,4],无论怎么跳都只能到0这个点,所以遍历范围是不合理的。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0;
        for(int i = 0; i < nums.size(); ++i) {
            cover = nums[i] + i;
            if(cover > nums.size() - 1) return true;
        }   
        return false;     
    }
};

        修改后: 只能跳跃到cover范围内的所有元素,所以范围修改成cover;其次使用max函数保证cover是能达到的最远路径。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        if(nums.size() == 1) return true;
        int cover = nums[0];
        for(int i = 0; i <= cover; ++i) {
            cover = max(cover, nums[i] + i);
            if(cover >= nums.size() - 1) return true;
        }   
        return false;     
    }
};

45.跳跃游戏II

        思路是一次跳跃中尽可能大地覆盖元素,然后从已覆盖的元素中判断下一次能不能到达最后一个元素;不能则循环,能则结束。代码中:

        cover指从元素所覆盖的长度(和第一个元素的距离)

        curCover指当前的元素出发所能到达的最远长度

        maxCover指在当前元素到达最远长度前,从某一元素出发能到达的下个最远长度

        代码整体逻辑则是先走一步到达curCover前,期间寻找到maxCover;下一步再按照maxCover走。

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int cover = nums[0];
        int maxCover = cover;
        int sum = 0;
        int curCover;
        while(1) {
            curCover = maxCover;
            if(curCover >= nums.size() - 1) {
                sum++;
                return sum;
            }
            sum++;
            for(int i = 0; i <= curCover; ++i) {
                cover = nums[i] + i;
                if(maxCover >= cover) continue;
                else{
                    //记录这次范围内能到达的最远值
                    maxCover = cover;  
                }                    
            }
        }        
        return sum;
    }
};

1005.K次取反后最大化的数组和

        首先得排序,对于正负元素混合的数组首先对最小的负数取反;其次。对于全正数的数组,则k为偶数可以取回原数,k为奇数则取最小的数字为负。

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int sum = 0;
        for(auto& n:nums) {
            if(k <= 0 || n >= 0) break;
            if(n < 0) {
                n = -n;
                k--;
            }
        }    
        sort(nums.begin(), nums.end());
        //接着没负数了
        for(auto& n:nums) {
            if(k != 0 && k % 2) n = -n;
            break;
        }
        //求和
        for(auto n : nums) {
            cout << n<< endl;
            sum += n;
        }    
        return sum;
    }
};

第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练营的内容。通过这些题目的练习,可以提升对双指针滑动窗口等算法的理解应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值