C语言刷题~Leetcode与牛客网简单题

简介: C语言刷题~Leetcode与牛客网简单题

前言

作者:小蜗牛向前冲

名言:我可以接收失败,但我不能接收放弃

如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。

为了提高自己编写代码的能力,特意开设刷题专题,记录自己刷题的思路和理解。欢迎❀大家的指正。

1 复写零

思路:

对于这道题目我们很容易想到,进行数组遍历,若发现某个元素为0,则从这个元素之后的元素整体向后移动1个元素的大小,但很快会发现这样效率不高。

下面我将用双指针的方法进行解题:

首先,我们用指针top标记数组的栈顶位置,用指针i标记现在需要放置元素位置,

其次,我们要找到原数组中对应放置在最后位置的元素位置,

最后,在数组最后从该位置元素往前来进行模拟放置即可。

//遍历二遍数组就可以完成任务
void duplicateZeros(int* arr, int arrSize)
{
  int top = 0;//用来标记数组
  int i = -1;//用来标记要放置元素的数组
  //开始第一遍遍历数组
  while (top < arrSize)
  {
    i++;
    if (0 == arr[i])
    {
      top += 2;//找到0top标记要向后跳2个元素
    }
    else
    {
      top++;
    }
  }
  int j = arrSize - 1;
  //判读top标记是否超出数组的范围
  if (top > arrSize)
  {
    arr[j] = 0;//新数组最后一个元素必定为0
    j--;
    i--;
  }
  //开始从后往前进行第二遍遍历
  while (j >= 0)
  {
    arr[j] = arr[i];
    j--;
    //若下个元素为0进行复写
    if (!arr[i])
    {
      arr[j] = arr[i];
      j--;
    }
    i--;//指向下个元素
  }
}

2 小乐乐与进制转换

要想将10进制数转转化为6进制数,可以用取余反序法解决。

思路:

将10机制数求余数,将余数存在数组中,在由数组倒序打印就可以了。

#include<stdio.h>
 
int main()
{
    int n = 0;
    int arr[10] = { 0 };//存放6进制的位数
    int i = 0;
    int j = 0;
    scanf("%d", &n);
    while (n)
    {
        arr[i] = n % 6;// 不断的求出6进制数的位数
        n = n / 6;
        i++;
    }
    //输出
    for (j = i - 1;j >= 0;j--)//注意指这里i要-1
    {
        printf("%d", arr[j]);
    }
    return 0;
}

3 小乐乐求和

这题的解题思路很简单,用个循环就可以解决,唯一要n输入的范围是1<=n<10^9。

《C和指针》中写过:long与int:标准只规定long不小于int的长度,int不小于short的长度。

所以intlong的范围都可以认为是(-2^31~(2^31-1)),这将有可能不满足n的取值范围,于是我们应该用long long来定义n的取值范围。

#include<stdio.h>
 
int main()
{
    //输入
    long long n = 0;
    scanf("%llu", &n);
    long long i = 1;
    long long sum = 0;
    while (n >= i)
    {
        sum = sum + i;
        i++;
    }
    //输出
    printf("%llu", sum);//注意这里是以%llu打印
    return 0;
}

4 小乐乐定闹钟

这题主要考察了对%与/运算符的用法,我们主要注意时和分都由二位数组成,所以我们要注意进行前导0补齐(%02d)

#include <stdio.h>
 
int main()
{
    int h = 0;//小时
    int m = 0;//分钟
    int k = 0;//要睡觉的时间
    scanf("%d:%d %d", &h, &m, &k);
    h = ((m+k)/60+h)%24;
    m = (m+k)%60;
    printf("%02d:%02d\n", h, m);
    return 0;
}

5小乐乐与欧几里得

这里我们很容易想到暴力求解,但真的能够通过吗?

#include<stdio.h>
 
int main()
{
    long long n = 0;
    long long m = 0;
    //输入
    scanf("%lld%lld", &n, &m);
    long long max = n > m ? m : n;//假设m和n中较小数位最大公约数
    long long min = n > m ? n : m;//假设m和n中较大数位最小公倍数
    //求最大公约数和最小公倍数
    while (1)
    {
        if (0 == n % max && 0 == m % max)
        {
            break;//找到最大公约数
        }
        max--;
    }
    while (1)
    {
        if (0 == min % n && 0 == min% m)
        {
            break;//找到最小公倍数
        }
        min++;
    }
    printf("%lld", max + min);
    return 0;
}

这里我们发现,这种算法用时会很长导致解题失败。那么还有更好的算法吗?

下面将为大家介绍用辗转相除法解题

辗转相除法(求最大公约数):如果有两个数n,m;且n>m,设n/m商q余c,则n和m的最大公约数也是m和c的最大公约数。这样辗转相除,直到余数为0时除式的商(也就相当于n/m时c那个位置的数字)即为最大公约数

而最小公倍数 = (n*m)/(最大公约数)

这里我们要注意是在求最大公约数的时候,n和m是发生改变了的,所以我们提前存储好他们。

//辗转相除法
int main()
{
    long long n = 0;
    long long m = 0;
    long long tmp = 0;
 
    scanf("%lld %lld", &n, &m);
    int a = n;
    int b = m;
    while (tmp = a % b)
    {
        a = b;
        b = tmp;
    }
    printf("%lld\n", b + m * n / b);
    return 0;
}

今天题就刷到这里了,希望大家能在评论积极分享自己的最优解。


 


相关文章
|
6天前
|
C语言
【C语言刷题系列】合并两个有序数组
【C语言刷题系列】合并两个有序数组
|
6天前
|
C语言
【C语言刷题系列】删除公共元素
【C语言刷题系列】删除公共元素
|
6天前
|
存储 C语言
【C语言刷题系列】对数字添加逗号
【C语言刷题系列】对数字添加逗号
|
6天前
|
C语言
【C语言刷题系列】喝汽水问题
【C语言刷题系列】喝汽水问题
|
6天前
|
存储 C语言
【C语言刷题每日一题#牛客网HJ73】——计算日期到天数转换(给定日期,计算是该年的第几天)
【C语言刷题每日一题#牛客网HJ73】——计算日期到天数转换(给定日期,计算是该年的第几天)
|
6天前
|
C语言
【C语言刷题每日一题#牛客网BC6】输入三个整数,输出第二个整数
【C语言刷题每日一题#牛客网BC6】输入三个整数,输出第二个整数
|
5天前
|
C语言
C语言刷题(函数)
C语言刷题(函数)
|
5天前
|
C语言
C语言刷题(数组)
C语言刷题(数组)
|
6天前
|
C语言
【C语言刷题每日一题】一维数组的交换
【C语言刷题每日一题】一维数组的交换
|
6天前
|
存储 C语言
【C语言刷题系列】求一个数组中两个元素a和b的和最接近整数m
【C语言刷题系列】求一个数组中两个元素a和b的和最接近整数m