贪心算法

  1. 跳跃游戏

    LeetCode 45

    给定一个非负矩阵,矩阵中每个位置的数字代表从这个位置最多可以跳的跳数。目标是求出到达最后一个元素的最小跳数。

    输入:

    [2, 3, 1, 1, 4]

    输出:

    2

    解释:

    从0位置跳到1位置,再从1位置跳到4位置,一共两跳到达终点。

    /*
    	思路:采用贪心算法,引入reach变量表示可能达到的最远处,这也就是全局最优解;当遍历到i时,局部最优解即次局部下最远可达位置A[i] + i,此时全局的最优解reach和A[i] + i 的最大值,即reach = max(reach, A[i] + i)
    	除此之外,还要记录跳的次数,至于什么时候step需要加1?当前的i超过了前一步的最远位置。所以引入last变量记录上一步能到达的最远位置。
    */
    class Solution {
    public:
        int jump(vector<int>& nums) {
            int len = nums.size();
            int reach = 0; //最远能到达的位置
            int last = 0; //上一步最远能到达的位置
            int step = 0; //i超过上一步最远位置时+1
            for(int i = 0; i <= reach && i < len; ++i) 
            {
                if(i > last) //当前位置比上一步最远能到达的位置还要远
                {
                    step++; //则需要跳一步
                    last = reach; //将目前最远能到达的位置变成上一步最远能到达的位置,进行迭代
                }
                reach = max(reach, nums[i] + i); //每次取最远能达到的位置和nums[i] + i的最大值作为新的reach
            }
            return step;
        }
    };
    
  2. 买卖股票

    LeetCode 121

    给出一个数组,代表每天股票价格,计算出最大收益,只能买卖一次。

    输入:[7, 1, 5, 3, 6, 4]

    输出:5

    输入:[7, 6, 4, 3, 1]

    输出:0

    /*
    	思路:分别找出价格最低和最高的一天,低进高出,注意最低的一天要在最高的一天之前且只能交易一次。遍历一次,由局部推出全局最优。
    */
    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int res = 0;
            if(prices.size() <= 1)
                return res;
            int curmin = prices[0];
            for(int i = 0; i < prices.size(); ++i)
            {
                if(curmin > prices[i])
                    curmin = prices[i];
                if(res < (prices[i] - curmin))
                    res = prices[i] - curmin;
            }
            return res;
        }
    };
    
  3. 买卖股票2

    LeetCode 122

    相比121,本题有多次买卖机会,同一时刻只能持有一个股票,只有当当前的股票卖掉才能买新的股票 。

    输入:[7, 1, 5, 3, 6, 4]

    输出:7

    输入:[1, 2, 3, 4, 5]

    输出:4

    /*
    	思路:本题实际上是找局部的递增序列,对局部递增序列计算收益,然后将所有局部递增序列的收益相加即可。
    */
    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int res = 0;
            for(int i = 0; i < prices.size();)
            {
                int j = i;
                while(j + 1 < prices.size() && prices[j + 1] >= prices[j]) //寻找最长递增序列
                {
                    j++;
                }
                if(j == i)//如果没有递增序列,则++i从下一个开始重新寻找
                    i++;
                else  //否则求出这两的差
                {
                    res += prices[j] - prices[i];
                    i = j + 1;
                }
            }
            return res;
        }
    };
    

你可能感兴趣的:(C++,面试知识点)