10.11 峰与谷

     《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
     次优解先将数组按升序排序,然后从 i n d e x = 1 index=1 index=1开始,每次以加2的方式迭代交换 i n d e x − 1 index-1 index1 i n d e x index index处的元素。

//次优解,谷位于index为1、3处(index从0开始算起)
void swap(vector<int> &myArray,int left,int right)
{
	int temp = myArray[left];
	myArray[left]= myArray[right];
	myArray[right] = temp;
}

void sortValleyPeak(vector<int> &myArray)
{
	sort(myArray.begin(), myArray.end());
	for (int i=1;i<myArray.size();i+=2)
	{
		swap(myArray, i - 1, i);
	}
}
 
图1.

     最优解没有首先将数组排序而是直接从 i n d e x = 1 index=1 index=1开始,每次以加2的方式迭代,每次将其左右的值和其本身三个元素中值最大的元素和当前 i n d e x index index处的元素交换。因此这种情况下峰位于index为1、3等奇数索引处(index从0开始算起)。在下一次迭代过程中不会改变前一次迭代过程中已经构建的峰谷排序。在下一次迭代过程中如果要改变前一次迭代过程中已经构建的峰谷排序,则这一次迭代过程中左边的元素(即上一次迭代中的右边的元素)必须被交换,因为如果不出现交换的话就不会改变前一次迭代过程中已经构建的峰谷排序。因此这一次迭代中的三个元素中的最大值必须位于这一次迭代中的左边的元素(即上一次迭代中的右边的元素)。交换过后这一次迭代中的左边的元素小于这一次迭代中的中间的元素,也肯定小于上一次迭代中的中间元素。如果要在下一次迭代过程中如果要改变前一次迭代过程中已经构建的峰谷排序,交换过后这一次迭代中的左边的元素必须要大于大于上一次迭代中的中间的元素,这就互相矛盾了。所以在下一次迭代过程中不会改变前一次迭代过程中已经构建的峰谷排序。

//最优解,峰位于index为1、3处(index从0开始算起)
int max(int a,int b)
{
	if (a > b)
		return a;
	else
		return b;
}

void swap(vector<int> &myArray,int left,int right)
{
	int temp = myArray[left];
	myArray[left]= myArray[right];
	myArray[right] = temp;
}

int maxIndex(vector<int>& myArray, int left, int middle, int right)
{
	int len = myArray.size();
	int leftValue = left >= 0 && left < len ? myArray[left] : numeric_limits<int>::min();
	int middleValue = middle >= 0 && middle < len ? myArray[middle] : numeric_limits<int>::min();
	int rightValue = right >= 0 && right < len ? myArray[right] : numeric_limits<int>::min();

	int maxV = max(leftValue, max(middleValue, rightValue));

	if (leftValue == maxV)
	{
		return left;
	}
	else if (middleValue == maxV)
	{
		return middle;
	}
	else 
	{
		return right;
	}
}

void sortValleyPeak(vector<int> &myArray)
{
	for (int i=1;i<myArray.size();i+=2)
	{
		int biggestIndex = maxIndex(myArray, i - 1, i, i + 1);
		if (i != biggestIndex)
		{
			swap(myArray, i, biggestIndex);
		}
	}
}
 
图2.

     最优解2与最优解基本相同,只不过它没有调用额外的函数来寻找临近的三个元素中最大的哪一个。最优解2中谷位于index为1、3处(index从0开始算起)。

//最优解2,谷位于index为1、3处(index从0开始算起)
void swap(vector<int>& myArray, int left, int right)
{
	int temp = myArray[left];
	myArray[left] = myArray[right];
	myArray[right] = temp;
}

void sortValleyPeak(vector<int>& myArray)
{
	for (int i = 1; i < myArray.size(); i += 2)
	{
		if (myArray[i - 1] < myArray[i])
		{
			swap(myArray, i - 1, i);
		}
		if (i + 1 < myArray.size() && myArray[i + 1] < myArray[i])
		{
			swap(myArray, i + 1, i);
		}
	}
}
 
图3.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值