常见的算法面试问题以及代码实现

1 时间复杂度分析
一个简单的时间测试代码如下:

#include<iostream>
#include<cmath>
#include<ctime>

using namespace std;

int main(){
	for(int x=1;x<=9;x++){
		int n=pow(10,x);
		
		clock_t startTime=clock();
	    
	    int sum=0;
	    for(int i=0;i<n;i++)
	        sum+=i;
	
	    clock_t endTime=clock();
	
	    cout<<"10^"<<x<<":"<<double(endTime-startTime)/CLOCKS_PER_SEC<<"s"<<endl; 
	}
	return 0;	
} 

结果如下:
在这里插入图片描述
在这里插入图片描述
2空间复杂度的分析:多开一个辅助的数组:O(N)
多开一个二维的数组:O(n*n)
多开一个常数空间:O(1)
实例:O(1),两个整数进行互换

#include<iostream>

void swapTwoInts(int &a,int &b){
	int temp=a;
	a=b;
	b=temp;
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	swapTwoInts(a,b);
	printf("%d  %d",a,b);
}

在这里插入图片描述
例2 单词翻转+全局翻转+局部翻转+去掉空格

#include<iostream>
#include<stdio.h>

using namespace std;
 
void reverse(char * s, int first, int last)
{
	while (first < last)
	{
		char tmp = s[first];
		s[first++] = s[last];
		s[last--] = tmp;
	}
}
 
void reverseWords(char *s) {
	int last = 0, now = 0;
	//翻转每个单词,同时翻转整个字符串,则对应单词拼写正确
	while (s[now])
	{
		while (s[now] == ' ') now++;
		last = now;
		while (s[now] != ' ' && s[now] != '\0') now++;
		reverse(s, last, now - 1);
	}
	reverse(s, 0, now - 1);
	last = 0;
 
	//删除多余的空格
	for (int i = 0; i < now; i++)
	{
        if(!isblank(s[i]) || (last && s[last - 1] != s[i]))
		s[last++] = s[i];
	}
	s[last] = 0;
	if (last && s[last - 1] == ' ')
		s[last - 1] = 0;
}
int main()
{
    //char str[] = "I am from Shanghai";
    char str[100];
    scanf("%[^\n]",str);//scanf("%[^\n]",str);其中的%[^\n]" 可以读取空格,回车结束输入
    //scanf("%s",str) 比如字符串:what are you doing. 它 只读到what就结束 
    printf("str = %s\n",str);

    reverseWords(str);
    printf("src = %s\n", str);
    return 0;
}

输出结果:
在这里插入图片描述
简单选择法排序

 #include<stdio.h>
    int main()
    {
    	int i, index, k, n, temp;
    	int a[10];
    	scanf("%d", &n);
    	for(i=0; i<n; i++)
    		scanf("%d", &a[i]);
    	for(k=0; k<n-1; k++){
    		index=k;//保持前k个元素是有序的,要么前面保持最大的或者最小的k个元素 
    		for(i=k+1; i<n; i++)
    			if(a[i]>a[index])//该行决定了输出数组从大往小排序
    			//if(a[i]<a[index]//表示输出数组从小到大进行排列,相对于冒牌排序不用进行很多次的两两交换,
    			//才将最小的元素放在委派部分的第一个位置 
    			index=i;
    			temp=a[index];
    			a[index]=a[k];
    			a[k]=temp;
    			    //for(i=1; i<n; i++)
    		            //printf(" %d", a[i]);
    		    printf("\n");
    		     
	}
	printf("%d", a[0]);
	for(i=1; i<n; i++)
		printf(" %d", a[i]);
 
	return 0;	
}

快速排序:

#include<iostream>
using namespace std;
void quick_sort(int left,int right);
int a[100001];
int main()
{
    int n,i;
    cin>>n;
    for(i=0;i<n;i++)	cin>>a[i];
    quick_sort(0,n);
    for(i=1;i<=n;i++)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}
 
void quick_sort(int left,int right)
{
    int i=left,j=right;
    int mid,temp;
    
    mid=a[(i+j)/2];
   
    while(i<j)
    {
        while(a[i]<mid)	i++;
        while(a[j]>mid)	j--;
        
        if(i<=j)
        {
            temp=a[i];a[i]=a[j];a[j]=temp;
            i++;j--;            
        }
    }
    if(left<j)	quick_sort(left,j);
    if(right>i)	quick_sort(i,right);
}

归并排序:

#include <iostream>
#include <stdlib.h>
void print_array(int nums[], int n);
using namespace std;

void mergeOne(int nums[], int l, int m, int r){
    int nl = m - l + 1;
    int nr = r - m;
    int *p = NULL, *q = NULL;
    p = (int *) malloc (nl * sizeof(int));
    q = (int *) malloc (nr * sizeof(int));

    //将数组输入到两个空间中
    for(int i = 0; i < nl; i++) {
        p[i] = nums[l + i];
    }
    for(int j = 0; j < nr; j++) {
        q[j] = nums[m + 1 + j];
    }

    //合并两个数组
    int i = 0;
    int j = 0;
    int k = l;
    while(i < nl && j < nr) {
        if(p[i] < q[j]) {
            nums[k++] = p[i++];
        }else{
            nums[k++] = q[j++];
        }
    }

    //将剩余的元素合并
    while(i < nl) {
        nums[k++]  = p[i++];
    }
    while(j <nr) {
        nums[k++] = q[j++];
    }
}

//注意:此处的left和right必须是数组下标能取到的有效值
void mergeSort(int nums[], int left, int right) {
    int mid = (left + right) >> 1;
    if(left < right) {
        mergeSort(nums, left, mid);
        mergeSort(nums, mid+1, right);
        mergeOne(nums, left, mid, right);
    }
}

int main()
{
    //int nums[]={9, 3, 5, 2, 7, 6, 4, 1};
    //int n = sizeof(nums)/sizeof(nums[0]);
    int n;
    cin>>n;
    int nums[n];
    for(int i=0;i<n;i++)
        scanf("%d",&nums[i]);
    mergeSort(nums, 0, n - 1);
    print_array(nums,n);
    return 0;
}
void print_array(int nums[], int n) {
    for(int i = 0; i<n; i++){
    	printf("%d ", nums[i]);
        //cout<<nums[i]<<" ";
    }
    //cout<<endl;
}

最长回文子串+最长长度

#include<stdio.h>
#include<string.h>
#include<stdbool.h>

char* longestpalindrome(const char *str)
{
	bool dp[100][100];
	int i,j,len;
	int longest=1;
	int tmp;
	int n= strlen(str);
	char a[n];
	for(i=0;i<n;i++)
	{
		dp[i][i]=1;
		if(str[i]==str[i+1])
		{
			dp[i][i+1]=1;
			longest=2;
			strncpy(a,str+i,2);
		}
	}
	for(len=3;len<=n;len++)
	{
		for(i=0;i<=n-len;i++)
		{
			j=i+len-1;
			if(str[i]==str[j])
			{
				dp[i][j]=dp[i+1][j-1];
				if(dp[i][j]==1)
				{
					tmp=j-i+1;
					if(longest<tmp)
					{
						longest=tmp;
						strncpy(a,str+i,tmp);
					}
				}
			}
			else
			    dp[i][j]=0;
		}
	}
	printf("%d\n",longest);
	char *s = a;
	//printf("%s\n",s); 
	return s;
 } 
 
int main()
{
	char a[20];
	scanf("%s",a);
	char*s=longestpalindrome(a);
	printf("%s\n",s); 
}

0-1背包动态规划实现+完整的输入和输出

#include<iostream>
using namespace std;
#define N 10
int n;//共有n个物品
int c;//背包总重量为c
int v[N];//物品i价值为vi
int w[N];//物品i的重量为wi
int m[N][N];//m(i,j):背包容量为j,可选择物品为i
int x[N];//x[i]=0,第i件物品不装入背包,x[i]=1,第i件物品装入背包
void Knapsack(int v[],int w[],int c,int n,int m[][10])
{
    //由n→1计算
    //i=n时
    int jMax=min(w[n]-1,c);//背包剩余容量上限
    for(int j=0;j<=jMax;j++)
    {
        m[n][j]=0;
    }
    for(int j=w[n];j<=c;j++)
    {
        m[n][j]=v[n];
    }
    //从第n-1个到第2个
    for(int i=n-1;i>1;i--)
    {
        jMax=min(w[i]-1,c);
        for(int j=0;j<=jMax;j++)
        {
            m[i][j]=m[i+1][j];
        }
        for(int j=w[i];j<=c;j++)
        {
            m[i][j]=max( m[i+1][j],m[i+1][j-w[i]]+v[i]  );
        }
    }
    //第1个
    if(c>=w[1])
    {
        m[1][c]=max( m[2][c],m[2][c-w[1]]+v[1] );
    }
 
}
//x[i]=0,第i件物品不装入背包,x[i]=1,第i件物品装入背包
void Traceback(int m[][10],int w[],int c,int n,int x[])//构造最优解(x1,x2,…,xn)算法
{
    for(int i=1;i<n;i++)
    {
        if(m[i][c]==m[i+1][c])
        {
            x[i]=0;
        }
        else
        {
            x[i]=1;
            c-=w[i];
        }
    }
    x[n]=(m[n][c])?1:0;
}
int main()
{
 
    cin>>n>>c;
    for(int i=1;i<=n;i++)
    {
        cin>>w[i]>>v[i];
    }
    for(int i=1;i<=n;i++)//初始化
        for(int j=0;j<=c;j++)
            m[i][j]=0;
    Knapsack( v, w, c, n, m);
    Traceback(m,w,c, n, x);
     for(int i=1;i<=n;i++)
    {
        if(i==1)
            cout<<x[i];
        else
            cout<<" " <<x[i];
    }
    cout<<endl;
 
    cout<<m[1][c];
    return 0;
}

求解剩余最大数
示例数据:
92081346717538 10
输出:9878

#include<iostream> 
#include<string.h>
int main(){
	char a[101];
	int m;
	scanf("%s %d",a,&m);
	while(m--){
		int i=0;
		while(a[i+1] && a[i]>a[i+1])
		i++;
		
		a[i]=0;
		strcat(a,a+1+i);
		
	}
	puts(a);
	return 0;	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值