C语言简单算法(二)

1、 删除下标为k的元素
2、找出常用的数字
3、丢失的数字
4、将0放在数组最后
5、找出数组的单个数字
6、画三角形星星
7、啤酒与饮料
8、求最大公约数

一、删除下标为k的元素

删除下标为k的元素

void deleteK(int arr[],int n,int k)
{
	for(int i = k;i<n-1;i++)
	{
		arr[i] = arr[i+1];
	}

}

二、找出常用的数字

题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
举例:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2},由于数字2在数组中出现了5次,超过数组长度一半,因此输出2。

解法:不允许修改输入的数组,时间复杂度为O(n) 原理:
  假设在数组中出现的次数超过数组长度一半的数字位x,x出现的次数比其他所有数字出现的次数的和都要多。设用于存储x的整形变量res,一个用于存储x出现次数的整形变量count。res初始值为number[0],count初始值为1。当遍历到下一个数组元素时,如果当前元素和res相同,则count+1,否则count-1。如果count=0,则保存下一个数字,并设置count=1.
在这里插入图片描述

int MoreThanHalfNum_Solution(int numbers[],int n)
{
	int res = 0;
	int count = 0;
	if(n==0)
	{
		return 0;
	}
	else
	{
		res = numbers[0];
		count = 1;
		for(int i = 1;i<n;i++)
		{
			if(numbers[i]==res)
			{
				count++;
			}
			else
			{
				count--;
			}
			if(count==0)
			{
				res = numbers[i];
				count = 1;
			}
		}
	
	}
	//做一个出错判断
	count = 0;
	for(int i = 0;i<n;i++)
	{
		if(numbers[i] == res)
		{
			count++;
		}
	}
	if(2*count>n)
	{
		return res;
	}
	
	return 0;
	


}

3、丢失的数字

给你一个数组{0,1,2,3,….n},其中有一个数字缺失,请把缺失的数字找出来

题目给出的数组{0,1,2,3,4,5,…n}其中缺失一个数字,要把缺失的数字找出来…我们可以回顾一下高中学过的等差求和公式:Sn=(a1+an)n/2

假设我们没有缺失数字,等差求和公式可以快速得出答案。比如:{0,1,2,3}—>(0+3)*4/2—>6,如果此时缺失的是2呢,就是说题目的给出的数组是:{0,1,3},我们利用等差公式求和之后减去数组每个元素,最后剩下的数就是缺失的数字!6-1-3-0—>2

int missingNumber2(int arrays[],int n) {

        // 套用等差求和公式  n+1是因为要把那个没在的元素一起加上
        int sum = ((arrays[0] + arrays[n-1]) * (n+1)) / 2;  //(1+7)*6 
        // 遍历数组,得出的sum减去数组每一位元素,最后即是缺失的数字
		for(int i = 0;i<n;i++)
		{
			sum = sum - arrays[i];
		}
		return sum;


 }

四、将 " "放在数组最后

void moveZero2(char arrays[],int n)
{
	int j = 0;
	int len = strlen(arrays);
    for (int i = 0; i <len; i++) 
	{

        if (arrays[i] != ' ') 
		{
            // 跟j进行交换,保证j的前面都不是 ' ' 
            char temp = arrays[i];
            arrays[i] = arrays[j];
            arrays[j]  = temp;
            j++;
        }
	}
}

五、找出数组的单个数字

给你一个数组,除了一个数字外,其他的数字都出现了多次,请把这个只出现一次的数字找出来。
思路:

将该数组遍历一次,记录每个数字出现的次数
如果该数字出现的次数只有1,那么该数字就是单个数字~

    /**
     * 找出每个元素出现的次数
     * @param nums 数组
     * @param value 想知道出现次数的元素
     */

int countNumber(int nums[],int n,int value)
{

        int count = 0;
        for (int i = 0; i < n; i++) 
		{
            if (value == nums[i]) 
			{
                count++;
            }
        }
        // 返回该元素出现的次数
        return count;
 }




int  singleNumber(int nums[],int n)
{

        for (int i = 0; i < n; i++)
		{

            int count = countNumber(nums,n,nums[i]);
            // 如果该元素只出现一次,那么就是它了!
            if (count == 1) 
			{
                return nums[i];
            }
        }
		return 0;
  }


六、画三角形星星

思路:

首先,我们可以发现:每行星星的个数是(2*行数-1),每行的空格数就是最大行数减去第n行(最大4行,第4行没有空格,最大4行,第三行1个空格)
有了上面的规律,套个for循环即可生成三角形星星~

 void drawStar() 
 {

        // 我要画5行的星星
    int row = 5;

    for (int i = 1; i <= 5; i++)
	{

        // 空格数等于最大行数 - 当前行数
        for (int j = 1; j <= row - i; j++)
		{
			printf(" ");
        }

        // 星星数等于(当前行数*2-1)
        for (int j = 1; j <= i * 2 - 1; j++) 
		{

           printf("*");

        }

        // 每画一行就换一次行
		printf("\n");
        
    }
 }

七、啤酒与饮料

啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。

这是蓝桥杯的一道题,我们可以使用暴力搜索即可解出:

如果82.3全买啤酒最多能买82.3/2.3=35瓶
如果82.3全买饮料最多能买82.3/1.9=43瓶
以此作为控制条件

void beerAndDrink() 
{

    // 啤酒
    for (int i = 0; i < 36; i++)
	{

        // 饮料
        for (int j = 0; j < 44; j++) 
		{

            // 钱刚好花光了,并且啤酒比饮料少
            if (2.3 * i + j * 1.9 == 82.3 && i < j)
			{
				printf("啤酒买了%d,饮料%d\n", i,j);
            }
        }
    }
}

八、求最大公约数

算法:是两个数相余,直到余数为0,如果余数不为0,就用除数和余数求余


 int gcd(int num1, int num2)
 {


        // 求余数
        int r = num1 % num2;

        // 如果余数为0,那么除数就是最大公约数
        if (r == 0) 
		{
            return num2;
        } 
		else 
		{

            // 否则,则用除数和余数来进行运算
            return gcd(num2, r);
        }

  }

非递归版本:

 int gcd(int num1, int num2)
 {
	 int r = num1 %num2;
	 while(r!=0)
	 {
		num1 = num2;
		num2 = r;
		r = num1%num2;
	 }
	 return num2;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值