算法第二章小结
算法第二章主要学习了递归算法和分治的思想。递归算法是指直接或者间接的调用自身的算法,最重要的一点是要有终止条件,一般由if语句执行。分治思想是指将一个难以直接解决的较大的问题,分割成一些比较小规模的相同的问题。
首先学习了递归的经典例题,斐波那契数列,当满足n>1时,这个数列的第n项的值是它前面两项的和这时就可以采用递归算法。
int fibonacci(int n){ if(n<=1) return 1; return fibonacci(n-1)+fibonacci(n-2); }
接下来是整数划分问题,即将正整数n表示成一系列正整数之和。对于整数划分这块,我暂时还没有很好地理解下来。
还有汉诺塔问题。在解决汉诺塔问题的时候,可以把这个问题的规模变小,然后找出规律。
void hannoi(int n, int a, int b, int c) if(n>0){ hanoi(n-1,a,c,b); move(a,b); hanoi(n-1,c,b,a); } }
然后是用分治的策略解决二分查找的问题。
基本思想是:将 n个元素分成大致相同的两半,取a[n/2]与要找的那个数x作比较。如果相等算法终止,如果x<a[n/2],则在数组左边继续寻找,否则在右边找。这种算法的时间复杂度最坏情况下为O(logn)。
int BinarySearch(int a[], int x, int n) { int left=0; int right=n-1; while(left<=right){ int middle =(left+right)/2; if(x==a[middle]) return middle; if(x>a[middle]) left=middle+1; else right=middle-1; } return -1; }
接下来是快排的分治思想。快排的主要侧重点是,基准元素的位置是确定的。快排的时间复杂度是O(nlogn)。
本章总共上机两次。首先是最大子列和的问题。刚看到这道题目的时候,只是会想到用那种前面一直加然后再比较的想法,这种思想十分复杂。在老师的说明下,了解到用二分的方法,分别找出左边和右边的最大值,然后再看是否跨界的为最大。其实也算是一种子问题的划分。第一次算法上机的时候,我和同伴都是慌张的。以前上机的话,老师可能会把代码大概给出来,然后这次是只是给了一个思想。所以我也才明白到思想其实很重要,然后自己把代码写出来也有一定难度。经过和同伴的讨论以及查一些资料,终于在自己的理解下把代码敲出来了。这个时候其实收获最大的是,要好好学习思想,然后锻炼自己的能力。
第二次上机是,找第k小的数,这道题我和同伴一直认为是快排思想的变形。因为在快排里面,你要找的那个基准元素的位置是一定固定的。所以只要把基准元素的位置和我们找的那个位置比较,就可以得出结果
结对打代码确实给了我不一样的感觉。两个人一起打代码,其实会更有思想的碰撞,能够更好地理解题目解决问题。希望接下来能够更好地学习算法的思想,能够把代码自己敲下来。