高效面试之贪心算法

性质:
最优子结构。
贪心选择性质:局部最优解可以得到全局最优解

贪心算法,子问题可以决定全问题,而dp子问题只能影响全问题。

题目索引:
Jump Game
1. 给定一个数组,每个元素值表示当前可以走的步数,求到达终点最小跳数
farest=max(farest,i+A[i]);

Best Time to Buy and Sell Stock 2,3
2. 最佳时间买卖股票,分别分析1)可以进行一次。2)可以进行多次交易的最大利益
maxPrices=max(maxPrices,prices[i]);
 ans=max(ans,maxPrices-prices[i]);

Longest Substring Without Repeating Characters
3. 给定一个字符串(有重复字符),求最长的无重复字符的子串
max_len=max(max_len,i-start);//i-start为当前无重复字串长度
start=last[s[i]-'a']=i;//更新起码位置为重复字符的下一位置
O(n)解决
Container With Most Water
4. 容器能够装的水的最大体积

真题1:

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.


分析:
 你每走一步 都选择最大的  这样你能保证你走的步数最多  如果走最大步数还到达不了 那就到达不了了
 
class Solution {
public:
    bool canJump(int A[], int n) {
        if (0==n)
            return false;
        int farestdistance=A[0];
        int cur=0;
        for(cur;cur
        {
             farestdistance=max(farestdistance, cur+A[cur] );  //cur数组下标,也是你当前的位置
            if(farestdistance>=n-1)
                   return true;
        }
        return false;
    }
};

Your goal is to reach the last index in the minimum number of jumps.

For example:
Given array A = [2,3,1,1,4]

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)


选择最长的步数能保证最小的次数。

class Solution {

public:

    int jump(int A[], int n) {

        if(0==n)

           return 0;

        int cur=0,next=0,maxdistance=-1,count=0;//初始化老是出错

        while(true)

        {

            if(next>=n-1) //写成maxdistance>=n-1老是[0]测试用例通不过

               return count;

            for(cur;cur<=next;++cur)

            {

                maxdistance=max(maxdistance,cur+A[cur]);//贪心算法,选择cur到next范围内最大的移动值,当前编号+当前位置可移动的最大值

            }

            cur=next; //下一步的新起点

            next=maxdistance; //这一步能够走得最大值

            count++;

        }

    }

};


题目2:


Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.


找到最大利润,你只能进行一次交易

分析:

贪心法,分别找到价格最低和最高的一天,低进高出,注意最低的一天要在 把原始价格序列变成差分序列,本题也可以做是最大 m 子段和,m = 1。


i--版本 用最大值


class Solution {

public:

    int maxProfit(vector &prices) {

        if(prices.size() == 0)

            return 0;

        int ans;//最大差价

        int maxPrices=prices[prices.size()-1];

        for(int i=prices.size()-1;i>=0;i--)

        {

            maxPrices=max(maxPrices,prices[i]);//第i天之后,即i+1到第n天的最大利益maxPrices,即找曲线的最大值

            ans=max(ans,maxPrices-prices[i]);//即i+1到第n天的最大利益maxPrices减去第i天,即第i天最大利益;ans为前面i天中利益最大的一天

        }

        return ans;

    }

};

i++ 版本 用最小值


Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).


找到最大利润,你可以进行多次交易
不需要最大最小值,只要交易能够赚钱,我就交易。

class Solution {
public:
    int maxProfit(vector &prices) {
        if(prices.size()==0 || prices.size()==1)
            return 0;
        int ans[prices.size()-1];
        int buypoint=0,sellpoint=prices.size()-1;
        ans[0]=0;
        for(int i=0;i
        {
           
            if(prices[i+1]>=prices[i])
            {
                sellpoint=i+1;
                buypoint=i;//第一次写忘了
            }
            else
            {
                ans[i+1]=ans[i]; /*如果prices[i+1]
                buypoint=i+1;
            }
            if(sellpoint>=buypoint && prices[i+1]>=prices[i])//第一次写这里也忘了
             ans[i+1]=max(prices[sellpoint]-prices[buypoint],ans[i]+prices[i+1]-prices[i]);
        }
        return ans[prices.size()-1];
    }
};


简化版本:
分析
贪心法,低进高出,把所有正的价格差价相加起来。
把原始价格序列变成差分序列,本题也可以做是最大 m 子段和,m = 数组长度。
代码
// LeetCode, Best Time to Buy and Sell Stock II
// 时间复杂度 O(n),空间复杂度 O(1)
class Solution {
public:
int maxProfit(vector &prices)
 {
    int sum = 0;
    for (int i = 1; i < prices.size(); i++) 
    {
         int diff = prices[i] - prices[i - 1];
         if (diff > 0) sum += diff;
    }
    return sum;
    }
};

题目3:

Longest Substring Without Repeating Characters
描述
Given a string, find the length of the longest substring without repeating characters. For example, the
longest substring without repeating letters for ”abcabcbb” is ”abc”, which the length is 3. For ”bbbbb” the
longest substring is ”b”, with the length of 1.




题4:

Container With Most Water

描述

Given n non-negative integers a1; a2; :::; an, where each represents a point at coordinate (i; ai). n verti-

cal lines are drawn such that the two endpoints of line i is at (i; ai) and (i; 0). Find two lines, which together

with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container



你可能感兴趣的:(高效面试宝典)