题目一
两数之和
给定一个整数数组,和一个整数值m,要求在这个整数数组里找到两个数使得其和等于要求值m
#include <iostream>
using namespace std;
int b[10];
void merge_sort(int a[],int start,int end,int temp[]);
void merge(int a[],int start,int mid,int end,int temp[]);
void search_result(int a[],int dst,int size);
void merge_sort(int a[],int start,int end,int temp[])
{
if(start<end)
{
int mid =start+(end-start)/2;
merge_sort(a,start,mid,b);
merge_sort(a,mid+1,end,b);
merge(a,start,mid,end,b);
}
return;
}
void merge(int a[],int start,int mid,int end,int temp[])
{
int p1=start;
int p2=mid+1;
int pb=start;
while (p1<=mid && p2<=end)
{
if (a[p1]<=a[p2])
temp[pb++]=a[p1++];
else
temp[pb++]=a[p2++];
}
//将剩下的数装到数列里
while (p1<=mid)
temp[pb++]=a[p1++];
while (p2<=end)
temp[pb++]=a[p2++];
for(int i=start;i<=end;i++)
{
a[i]=temp[i];
}
}
void search_result(int a[],int dst,int size)
{
int i=0;
int j=size;
while (i!=j)
{
if(a[i]+a[j]<dst)
i++;
else if(a[i]+a[j]>dst)
j--;
else
break;
}
cout<<"find the result:"<<a[i]<<"+"<<a[j]<<"="<<dst<<endl;
}
int main() {
int a[9]={9,7,4,9,5,5,0,7,3};
int dst=9;
int size= sizeof(a)/ sizeof(int);
merge_sort(a,0,size-1,b);
search_result(a,dst,size-1);
return 0;
}
题目二
Lower Bound
写一个函数Lower_Bound,在包含size个元素中找到比给定整数p小的,下标最大的元素。找到则返回其下标,未找到则返回-1
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int lower_bound(vector<int> a,int dst,int size);
int lower_bound(vector<int> a,int dst,int size)
{
int best_pos=-1;
int L=0;
int R=size;
while (L<=R)
{
int mid=L+(R-L)/2;
if(a[mid]<dst)
{
best_pos=mid;
L=mid+1;
}
else
{
R=mid-1;
}
}
return best_pos;
}
int main() {
vector<int> a;
a.push_back(9);
a.push_back(7);
a.push_back(4);
a.push_back(5);
a.push_back(7);
sort(a.begin(),a.end());
int size=a.size();
int result=lower_bound(a,7,size-1);
cout << result<< endl;
return 0;
}
归并排序时间复杂度
快速排序时间复杂度
由于归并排序在平均情况下,每次调用quick_sort函数都能够将原规模,转换成两个规模为原规模一半的子问题,所以在这种情况下与归并排序的情况是时间复杂度的分析是一样的,平均时间复杂度为O(nlogn)。
最坏时间复杂度分析:如果待排序的数列本来就是有序的,那么每调用一次quick_sort函数,仅仅是把原规模为n的问题,转化为一个规模为1和规模为n-1的问题,那么这种情况下的最坏时间复杂度为O(n^2).
快速排序算法
#include <iostream>
using namespace std;
void swap(int& a,int& b)
{
int temp=a;
a=b;
b=temp;
}
void quick_sort(int a[],int start,int end)
{
if(start>=end)
return;
int i=start;
int j=end;
int mid=a[start];
while (i<j)
{
while (j>i && a[j]>=mid)
j--;
swap(a[i],a[j]);
while (i<j && a[i]<=mid)
i++;
swap(a[i],a[j]);
}
quick_sort(a,start,i-1);
quick_sort(a,i+1,end);
return;
}
int main()
{
int a[9]={9,7,4,9,5,5,0,7,3};
int size= sizeof(a)/ sizeof(int);
quick_sort(a,0,size-1);
for(int i=0;i<size;i++)
{
cout<<a[i]<<" "<<endl;
}
return 0;
}
归并排序与快速排序对比
归并排序相比于快速排序优点在于它是一个稳定的算法,能够将时间复杂度保持在O(nlogn),缺点是空间复杂度提高了,需要额外分配O(n)的内存。
快速排序优点是不用额外分配内存,一般情况下时间复杂度也能保持在O(nlogn),但是最坏情况下时间复杂度退化为O(n^2).
利用快速排序算法得到问题最优解
输出最大的m个数
给定一个数组,要求输出最大的m个数
#include <iostream>
using namespace std;
void swap(int& a,int& b)
{
int temp=a;
a=b;
b=temp;
}
void quick_sort(int a[],int start,int end,int n)
{
if(start>=end)
return;
int i=start;
int j=end;
int mid=a[start];
while (i<j)
{
while (j>i && a[j]>=mid)
j--;
swap(a[i],a[j]);
while (i<j && a[i]<=mid)
i++;
swap(a[i],a[j]);
}
if((end-i+1)>=n)
{ quick_sort(a,i+1,end,n);
}
else
{
quick_sort(a,start,i-1,n-end-1+i);
quick_sort(a,i+1,end,end-i);
}
return;
}
int main()
{
int a[9]={9,7,4,9,5,5,0,7,3};
int size= sizeof(a)/ sizeof(int);
quick_sort(a,0,size-1,3);
for(int i=0;i<size;i++)
{
cout<<a[i]<<" "<<endl;
}
return 0;
}
利用归并算法得到问题最优解
求排列的逆序数
考虑1,2,3…,n(n<=10000)的排列,如果其中存在j,k,满足j<k且a[j]>a[k],那么就称(a[j],a[k])是这个排列的一个逆序。
#include <iostream>
using namespace std;
int b[10];
int inverse_count=0;
void merge_sort(int a[],int start,int end,int temp[]);
void merge(int a[],int start,int mid,int end,int temp[]);
void merge_sort(int a[],int start,int end,int temp[])
{
if(start<end)
{
int mid =start+(end-start)/2;
merge_sort(a,start,mid,b);
merge_sort(a,mid+1,end,b);
merge(a,start,mid,end,b);
}
return;
}
void merge(int a[],int start,int mid,int end,int temp[])
{
int p1=start;
int p2=mid+1;
int pb=start;
while (p1<=mid && p2<=end)
{
if (a[p1]<=a[p2])
temp[pb++]=a[p1++];
else {
temp[pb++] = a[p2++];
inverse_count+=(mid-p1+1);
}
}
//将剩下的数装到数列里
while (p1<=mid)
{
temp[pb++]=a[p1++];
}
while (p2<=end)
temp[pb++]=a[p2++];
for(int i=start;i<=end;i++)
{
a[i]=temp[i];
}
}
int main() {
int a[6]={2,6,3,4,5,1};
int size= sizeof(a)/ sizeof(int);
merge_sort(a,0,size-1,b);
cout<<"The num of inverse is"<<inverse_count<<endl;
return 0;
}
注明:这篇文章是我在学习郭炜老师的算法设计课程写的一个总结,题目和思路均来自这位老师,代码是我自己写的,希望大家给我提出指教!