贪心算法总结

一、定义:

在求最优解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次贪心选择,最终得出整个问题的最优解,这种求最优解的方法就是贪心算法。

从贪心算法的定义可以看出,贪心算法不是从总体上考虑问题,他所做的选择只是某种意义上的局部最优解,而由问题自身的性质决定了该题运用贪心算法可以得到最优解。

如果一个问题可以同时用几种方法解决,贪心算法是最好的方法。

二、例题:

1、主元素:

给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。

Example

给出数组[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;
}

三、贪心算法的实现框架
    从问题的某一初始解出发;
    while (能朝给定总目标前进一步)
    { 
          利用可行的决策,求出可行解的一个解元素;
    }
    由所有解元素组合成问题的一个可行解;









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值