一、定义:
在求最优解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次贪心选择,最终得出整个问题的最优解,这种求最优解的方法就是贪心算法。
从贪心算法的定义可以看出,贪心算法不是从总体上考虑问题,他所做的选择只是某种意义上的局部最优解,而由问题自身的性质决定了该题运用贪心算法可以得到最优解。
如果一个问题可以同时用几种方法解决,贪心算法是最好的方法。
二、例题:
1、主元素:
给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。
给出数组[1,1,1,1,2,2,2],返回 1
代码:
int majornumber(vector<int>&nums)
{
int cut=0;
int result=0;
for(int i=0;i<nums.size();i++)
{
if(cnt==0)
{
cnt++;
result=nums[i];
}
else if(result==nums[i])
cnt++;
else cnt--;
}
return result;
}
2、最大子数组:
给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。
Example
给出数组[−2,2,−3,4,−1,2,1,−5,3]
,符合要求的子数组为[4,−1,2,1]
,其最大和为6
int maxSunarray(vector<int>&nums)
{
int sum=nums[0];
int max=nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i]<0)
{if(sum>max)
max=sum;
}
if(sum<0)
sum=nums[i];
else sum+=nums[i];
}
return max>sum?max:sum;
}
3、最小子数组:
给定一个整数数组,找到一个具有最小和的子数组。返回其最小和。
Example
给出数组[1, -1, -2, 1],返回 -3
int minSunarray(vector<int>&nums)
{
int sum=nums[0];
int min=nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i]>0)
{if(sum<min)
min=sum;
}
if(sum>0)
sum=nums[i];
else sum+=nums[i];
}
return min<sum?min:sum;
}
4、买股票的最佳时间II
假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格。设计一个算法来找到最大的利润。你可以完成尽可能多的交易(多次买卖股票)。然而,你不能同时参与多个交易(你必须在再次购买前出售股票)。
Example
给出一个数组样例[2,1,2,0,1], 返回 2
代码:
int maxProfit(vector<int>&nums)
{
int i,d,sum=0;
{
for(i=1;i<nums.size();i++)
{
d=nums[i]-nums[i-1];
if(d>0)
sum+=d;
}
return sum;
}
5、寻找缺失的数:
给出一个包含 0 .. N 中 N 个数的序列,找出0 .. N 中没有出现在序列中的那个数。
Example
N = 4
且序列为 [0, 1, 3]
时,缺失的数为2
。
int findMiss(vector<int>&nums)
{
int n=nums.size();
if(n==0)return 0;
if(n==1)return nums[0]==0?1:0;
int sum=0;
for(int i=0;i<n;i++)
sum+=nums[i];
return n*(n+1)/2-sum;
}