算法第2章实践报告
1.实践题目名称
7-1 maximum number in a unimodal array
2.问题描述
我们要在O(logn)的条件下求出一个单峰序列的maximum
3.算法描述
int get_top(int l , int r)
{
while (l < r) //终止条件为不可二分
{
int mid = (l + r) >> 1 ;
if (a[mid] > a[mid - 1] && a[mid] > a[mid + 1]) // 若当前值同时满足大于左边的数和小于右边的数 那其必然为我们要找的最大值
return a[mid] ;
if (a[mid] > a[mid - 1]) // 如果当前值大于我们左边的数 就说明此时区域性成非严格递增 最大值一定在当前值的右边
l = mid + 1 ; // 更新左指针
if (a[mid] < a[mid - 1]) // 同理可知 如果当前值小于我们左边的数 就说明此时区域性成非严格递减 最大值一定在当前值的左边
r = mid - 1 ;// 更新右指针
}
}
4.算法时间及空间复杂度分析
时间复杂度分析:很明显每次搜索都减半了 , O(logn)
空间复杂度分析:
一个O(n)的数组
5.心得体会
上完本次的实践课我收获颇丰,尤其是在和搭档的思维层面互相碰撞,一些超出二分本身的额外算法由此产生,我们两个一起写然后彼此互相看,这样的效果比一直都是一个人编调程序来的好,可以知道别人是怎么思考的。同时本节课老师带给我们的知识分享也让我受益良多,更值得一提的是自由讨论的氛围,让每一个同学都拥有机会去展现自己的思维。
6.分治法的个人体会和思考
分治法(divide-and-conquer):将原问题划分成n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。
分治模式在每一层递归上都有三个步骤:
- 分解(Divide):将原问题分解成一系列子问题;
- 解决(conquer):递归地解各个子问题。若子问题足够小,则直接求解;
- 合并(Combine):将子问题的结果合并成原问题的解。
合并排序(merge sort)是一个典型分治法的例子。其对应的直观的操作如下:
- 分解:将n个元素分成各含n/2个元素的子序列;
- 解决:用合并排序法对两个子序列递归地排序;
- 合并:合并两个已排序的子序列以得到排序结果
当然分治的思想并不是这么固定,需要根据不同情况进行调整。
blog: https://cotton-narco.github.io