面试笔试算法系列之分治法
来源:互联网 发布:王吴悠是什么梗 知乎 编辑:程序博客网 时间:2024/05/21 17:14
面试笔试算法系列之分治法
分治法:顾名思义乃是分而治之的意思,将一个大规模的问题分成若干个小规模的子问题。其中每个子问题是相对独立的,小规模情况下容易解。
问题举例:
1.快速排序
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
面试中经常会要求写出快速排序的代码,一段简洁代码如下:
void Qsort(int a[], int low, int high){ if(low >= high) { return; } int first = low; int last = high; int key = a[first];/*用字表的第一个记录作为枢轴*/ while(first < last) { while(first < last && a[last] >= key) { --last; } a[first] = a[last];/*将比第一个小的移到低端*/ while(first < last && a[first] <= key) { ++first; } a[last] = a[first]; /*将比第一个大的移到高端*/ } a[first] = key;/*枢轴记录到位*/ Qsort(a, low, first-1); Qsort(a, first+1, high);}
我们举例 57, 68, 59, 52, 72, 28, 96, 33, 24,上述代码的过程主要是设置一个first指针和last指针,分别指向比key小的值和比key大的值,上述代码的过程简洁,但是代码细节过强。
使用Partition函数进行分治快排
int Partition(int* data,int length,int start,int end){if(data==NULL||length<0||start<0||end>length-1) exit(0);//数组中随机选取一个数字,将数组分为两组,左边的比该数字小,右边的比该数字大int index = Random(start,end);//放到最后的位置,以便和所有的数进行比较 Swap(&data[end],&data[index]);//定义一个small,指向当前比选中数(现在的位置是data[end])小的数int small = start-1; for(int index = start;index < end;index++){ if(data[index]<data[end]){ //找到一个比选中数小的数 small++; //判断当前位置index和small所指的位置是否相等 if(index!=small){ Swap(&data[index],&data[small]); } } } //定位到新的位置,把选中的数放回去 small++;Swap(&data[small],&data[end]); return small;}
这个使用Partition函数的快速排序过程如下图所示,
2.找出数组中出现次数大于一半的数字
该问题可以使用一个Partition分治函数去解决,寻找对应中间位置的数字,即为所需数字,源码如下
#include <iostream>#include <stdlib.h>#include <time.h> using namespace std;void Swap(int *a,int *b){int temp=*a;*a = *b;*b=temp;} int Random(int start,int end){srand((unsigned)time(NULL)); return start+(int)(rand()%(end-start+1));}int Partition(int* data,int length,int start,int end){if(data==NULL||length<0||start<0||end>length-1) exit(0);//数组中随机选取一个数字,将数组分为两组,左边的比该数字小,右边的比该数字大int index = Random(start,end);//放到最后的位置,以便和所有的数进行比较 Swap(&data[end],&data[index]);//定义一个small,指向当前比选中数(现在的位置是data[end])小的数int small = start-1; for(int index = start;index < end;index++){ if(data[index]<data[end]){ //找到一个比选中数小的数 small++; //判断当前位置index和small所指的位置是否相等 if(index!=small){ Swap(&data[index],&data[small]); } } } //定位到新的位置,把选中的数放回去 small++;Swap(&data[small],&data[end]); return small;}void QuickSort(int data[],int length,int start,int end ){ if(start==end) return;int index = Partition(data,length,start,end); if(index>start){ QuickSort(data,length,start,index-1);}if(index<end){ QuickSort(data,length,index+1,end);}} //寻找数组中出现次数超过一半的数字int findMoreThanHalf(int* data,int length,int start,int end){int middle = length/2;int index = Partition(data,length,start,end);while(index!=middle){ if(index>middle){ end = index-1; index = Partition(data,length,start,end); }else{ start = index+1; index = Partition(data,length,start,end); }}return data[index];}int main(){srand((unsigned)(time(NULL)));int length = Random(1,20);int data[length]; int start =1;int end =1000;for(int i=0;i<length;i++){ data[i]=start+(int)(rand()%(end-start+1));} int data[10] ={12,34,54,54,67,54,2,54,54,54}; int length=10;for(int i=0;i<length;i++){ cout<<data[i]<<" ";}printf("\n");cout<<"中位数是"<<findMoreThanHalf(data,length,0,length-1)<<endl; QuickSort(data,length,0,length-1);for(int i=0;i<length;i++){ cout<<data[i]<<" ";}return 0;}
0 0
- 面试笔试算法系列之分治法
- 面试笔试算法系列之DFS
- 算法系列之分治
- 大数据笔试面试问题之分治法解决
- 【算法系列】分治法
- 算法系列—分治法
- 机器学习笔试面试系列算法集锦
- 机器学习笔试面试系列算法集锦
- 程序员笔试面试算法题系列--数组
- 机器学习笔试面试系列算法集锦
- 算法之分治法
- 算法之分治法
- 面试笔试系列之三 字符串相关
- 面试/笔试数据结构之排序算法篇
- 面试/笔试数据结构之排序算法篇
- 算法基础之分治法
- 基本算法之分治法
- 排序算法之分治法
- Qt---log日志框架(2)从性能考虑文件操作
- IE与其他浏览器的区别
- 简易的lazyman实现
- windows向virtualbox上的Linux系统传文件
- 面向对象编程的几个原则
- 面试笔试算法系列之分治法
- PAT 乙等 1024 科学记数法 C语言
- SonicOperator之相关工作2
- 应用调试之使用gdb和gdbserver
- leetcode没做出来看答案的题
- 0508-a标签的伪类选择器
- Python 3基础教程38-threading和创建一个线程
- Jmeter httpSampler采样器修改(用于http请求自动拼接签名)
- 纳税申报