计算机面试常见题目-算法

数据结构

冒泡排序优化

普通

//优化版本一:设置flag及时停止比较
void Bubble(int arr[],int length)
{
    int temp=0;
    int flag=0;

    //最少一趟 最多n-1趟
    for(int i=0;i<length-1;i++)
    {
         //一趟开始
        flag=0;

    for(int j=0;j<length-1;j++)
    {

        if(arr[j]>arr[j+1])
           {
           temp=arr[j+1];
            arr[j+1]=arr[j];
            arr[j]=temp;
            flag=1;
            }
    }
    if(flag==0)
        break;
}
}

改进版二:对数列有序区界定。每一轮理论上有界区+1(实际后面有界区可能远远大于理论上的,例如第一轮后面一半已有序)
我们可以在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。


void Bubble2(int arr[],int length)
{
    int temp=0;
    int flag=0;

int     terminal = length-1;

    //最少一趟 最多n-1趟
    for(int i=0;i<length-1;i++)
    {
         //一趟开始 趟交换标志清零
        flag=0;

//从下标0到下标terminal为无序区
    for(int j=0;j<terminal;j++)
    {

        if(arr[j]>arr[j+1])
           {
           temp=arr[j+1];
            arr[j+1]=arr[j];
            arr[j]=temp; //temp执行交换终结任务,temp原有值不影响任务
            
            temp = j;  //temp执行记录右交换位置下标
            
            flag=1;  //趟交换标志为1
            }
    }
    
    terminal = temp;  //terminal记录最后交换位置,下标terminal之后为有序区

    if(flag==0)
        break; //一趟无交换则结束排序
}

}




递归策略:

递归:是函数直接或间接调用自身的一种方法。它通常可以把一个重复的大型问题转化为较小规模的问题来求解。

递归需要有结束条件,并且每次调用本身都使问题更接近于解。

递归包括:递推,将原问题分解为子问题,并使子问题变成已知解,也就是到达递归结束条件。
回归,从已知的条件(子问题的已知解)出发,不断求值回归,最终回到递推的开始处。

应用:斐波那契数列,定义:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)

int fib(int i)
{
    if(i <= 1)
    {
        return 0;
    }
    return fib(i - 1) + fib(i - 2);
}



分治策略

分而治之,就是把一个复杂的问题分成两个或更多个相互独立的子问题,之后再把子问题分成更小的子问题以此类推。
知道最后的子问题可以简单地直接求解,原问题的解即子问题解的合并。



动态规划:常用于求解最优子问题。

(与分治法相同),将复杂的问题分解成若干子问题,先求解子问题,然后从子问题的解得到原问题的解。

(与分治法不同),经分解的子问题往往不是相互独立的,动态规划会将已解决的子问题的解保存下来,在需要子问题的解时可以直接获得,而不需要重复计算。


0/1背包问题

问题:
有N件物品和一个容量为V的背包,第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

2.2 解题思路:用动态规划的思路,阶段就是“物品的件数”,状态就是“背包剩下的容量”,那么很显然f [ i , v ] 就设为从前 i 件物品中选择放入容量为 v 的背包最大的价值。那么状态转移方程为:

    f[i][v]=max{
      f[i-1][v] , f[i-1][v-w[i]]+val[i] 
      
      //  f[i-1][v]  不放入第i件物品
      
      // f[i-1][v-w[i]]+val[i] ,放入第i件物品
     }

实例:
原文链接:https://blog.csdn.net/shanghairuoxiao/article/details/62426727

有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,
现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
在这里插入图片描述

这个方程可以如下解释:只考虑子问题“将前 i 个物品放入容量为 v 的背包中的最大价值”那么考虑如果不放入 i ,最大价值就和 i 无关,就是 f[ i - 1 ][ v ] , 如果放入第 i 个物品,价值就是 f[ i - 1][ v - w[i] ] + val[ i ],我们只需取最大值即可。



贪心算法简介:常用于最优化问题

贪心算法核心思想:(每一步)总是选择当前状态下最优的策略,也就是说不易整体最优解为考虑,而是一个个局部最优解来接近整体最优解。

例如求图的源点最短路径和,则每一步都选取最短权值的边。
可想而知,这并不一定是最优解。

在这里插入图片描述111
图片来自:https://blog.csdn.net/liushengxi_root/article/details/86676382



实例

求质数(素数)

质数:大于1的自然数中,除了1和自身不再有其他因子
其他的自然数称为合数。

算法思想:合数能分解成a*b,假设a<=b;则a<=sqrt(n),所以求到sqrt(n)即可

for(int i=2;i<sqrt(n);i++)
if(n%i==0) 
  printf("是质数");

十进制整数转二进制(除2取余,逆序排序)

int i=0;
do
{
bin[i++]=n%2+'0';
n=n/2;
}while(n!=0)
bin[i]='\0';
reverse(bin);

void reverse(char s[])
{
int temp,i,j;
for(i=0,j=strlen(s);i<j;i++,j--)
{
temp=s[i];s[i]=s[j];s[j]=temp;
}
}

逆序输出整数

算法思想:tmp=原来数字都升一位+新个位数

void Print(int num)
{
	int tmp = 0;
	while (num != 0)
	{
		tmp = tmp * 10 + num % 10;
		num /= 10;
	}
	printf("%d\n", tmp);
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值