【C刷题初阶】刷爆力扣第一弹


🌕 前言:关于C刷题

🤙关于C的学习出了看视频以外,那就是刷题了,朋友们,你们有没有过这样的感觉,在网上看了视频过后感觉自己什么都听懂了,但就是写题和做项目时无从下手,或者就是因为某个细节一直错一直改,那背后的原因是什么呢?四个字——题刷少了,这里新一建议去Leetcode看看,那里的题库资源很丰富,并且在全球都有广泛涉猎。不仅如此,这里还有 课程 + 刷题 + 面经 + 求职 + 讨论区分享解题思路,用过的人都说好😜
在这里插入图片描述
👉除此之外,我的建议是初学者从简单题开始练习,因为简单题是一切题的基础,一切的困难题都是从简单题衍生而来的,每天刷那么2~3题,后期再慢慢刷中等题,困难题,经过一段时间后会有很不错的提升
在这里插入图片描述
此外,在我们有一定的提升之后,我们便可以去刷剑指offer了,在这里预祝各位大学生以及初学者都拿到自己满意的offer!💖


第一题:旋转数组的最小数字

👇👇👇
做题链接戳这里:JZ11.旋转数组的最小数字

🍂 题目描述

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤n≤10000,数组中任意元素的值: 0≤val≤10000
要求:空间复杂度:O(1) ,时间复杂度:O(logn)

🍂示例

输入:[3,4,5,1,2]
返回值:1

示例2

输入:[3,100,200,3]
返回值:3

🍃题解

这道题有点清奇,首先它是部分有序数组,而且要求时间复杂度O(log n),且空间复杂度为O(1),意思说我们不能直接遍历数组找最小值,那该怎么办呢?我们查找有序数组最高效的方法是什么?——那当然是我们的二分查找,但是这和普通的二分查找又有所区别,我们需要找到它的规律:我们拿mid值与右值进行比较:

  1. 中间大于右边 [3, 4, 5, 1, 2],这种情况下,最小数一定在右边;则left = middle + 1
  2. 中间等于右边 [1, 0, 1, 1, 1], 这个是[0, 1, 1, 1, 1] 旋转过来的,这时候需要缩小范围 right–;,注意不能是left++,因为是非降序数组,所以要缩小右边范围,把较小值向右推,符合我们的判断规则。
  3. 中间小于右边 [5, 1, 2, 3, 4], 这种情况下,最小数字则在左半边;则right = middle
int minNumberInRotateArray(int* rotateArray, int rotateArrayLen) {
    // write code here
    int left = 0;
    int right = rotateArrayLen - 1;

    int mid = 0;

    while (left < right){
        mid = left + (right - left) / 2;
        if (rotateArray[mid] > rotateArray[right]) {
            left = mid + 1;
        }
        else if (rotateArray[mid] == rotateArray[right]) {
            right--;
        }
        else {
            right = mid;
        }
    }
    return rotateArray[left];
}

第二题:错误的集合

👇👇👇
做题链接戳这里:645.错误的集合

🍂 题目描述

集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。

给定一个数组 nums 代表了集合 S 发生错误后的结果。

请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

🍂示例

输入:nums = [1,2,2,4]
输出:[2,3]

示例2

输入:nums = [1,1]
输出:[1,2]

🍂提示

● 2 <= nums.length <= 104
● 1 <= nums[i] <= 104

🍃题解

我们如果只需要找到缺失的数字,那不就很简单了,我们根据题设可以直接用1-n的数字减去整个数组即可,但这道题怪就怪在它为什么要放一个重复数字在其中,那样我们的刚开始的设想也不能实现了,那么到底该怎么办呢?我们想题设为什么要只放1-n的数字,不随便放数字,题目的突破点就在于此,问题在于:1-n的数字可以当做我们的下标,从而就找到了题解,我们可以自己定义一个全为0的数组,然后将目标数组作为下标,即可排除我们的重复数字

int* findErrorNums(int* nums, int numsSize, int* returnSize) {
    *returnSize = 2;
    int* ret = (int*)calloc(numsSize + 1, sizeof(int));
    int* answer = (int*)calloc(2, sizeof(int));
    int old_size = 0, new_size = 0;
    for (int i = 0; i < numsSize; i++)
    {
        if (ret[nums[i]] == 1)
        {
            answer[0] = nums[i];
        }
        ret[nums[i]] = 1;
        old_size += nums[i];
        new_size += i + 1;
    }
    answer[1] = new_size - (old_size - answer[0]);

    return answer;
}

在这里插入图片描述

第三题:密码检查

👇👇👇
做题链接戳这里:OR141.密码检查

🍂 题目描述

小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:

  1. 密码只能由大写字母,小写字母,数字构成;

  2. 密码不能以数字开头;

  3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;

  4. 密码长度至少为8

现在小明受到了n个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。

输入描述:
输入一个数n,接下来有n(n≤100)行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写字母,小写字母和数字,字符串长度不超过100。
输出描述:
输入n行,如果密码合法,输出YES,不合法输出NO

🍂示例

输入:1
CdKfIfsiBgohWsydFYlMVRrGUpMALbmygeXdNpTmWkfyiZIKPtiflcgppuR
输出:YES

🍃题解

这里我们就需要注意了,我们需要用字符数组来存储字符串,然后1-3条很简单直接判断即可,第四条我们需要遍历我们的字符串,用四个变量将每种元素的值存储下来,然后最后一步比较即可

#include <string.h>
int main()
{
	int n = 0;
	while (~scanf("%d", &n))
	{
		for (int i = 0; i < n; i++)
		{
			char password[100] = { 0 };
			int upper = 0, lower = 0, digit = 0, other = 0;
			scanf("%s", password);
			if (strlen(password) < 8)
			{
				printf("NO\n");
				continue;
			}
			if (password[0] >= '0' && password[0] <= '9')
			{
				printf("NO\n");
				continue;
			}
			char* ptr = password;
			while (*ptr != '\0')
			{
				if (*ptr >= 'a' && *ptr <= 'z')
				{
					lower++;
				}
				else if (*ptr >= 'A' && *ptr <= 'Z')
				{
					upper++;
				}
				else if (*ptr >= '0' && *ptr <= '9')
				{
					digit++;
				}
				else other++;
				ptr++;
			}
			if (other > 0)
			{
				printf("NO\n");
			}
			if ((upper > 0) + (lower > 0) + (digit > 0) < 2)
			{
				printf("NO\n");
				continue;
			}
			printf("YES\n");
		}
	}
	return 0;
}

🚀今日份客观题

🍂 ONE.题目描述

有如下定义语句,则正确的输入语句是【多选】( )
int b;
char c[10];

A: scanf(“%d%s”,&b,&c); B: scanf(“%d%s”,&b,c);
C: scanf(“%d%s”,b,c); D: scanf(“%d%s”,b,&c);

🍃题解

正确答案:AB &cc两个地址值是一样的,程序的效果相同,也没错,但同时也必须把变量b的地址给scanf,故CD错误,AB正确。

本题易错点在于漏选C,因此要牢记&c 跟 c是一样的。

🍂 TWO.题目描述

对于下面的说法,正确的是( )

A: 对于 struct X{short s;int i;char c;},sizeof(X)等于sizeof(s) + sizeof(i) + sizeof©
B: 对于某个double变量 a,可以使用 a == 0.0 来判断其是否为零
C: 初始化方式 char a[14] = “Hello, world!”; 和char a[14]; a = “Hello, world!”;的效果相同
D: 以上说法都不正确

🍃题解

A选项,没有考虑内存对齐。B选项,考察double类型的比较,由于浮点数存在误差,不能直接判断两个数是否相等,通常采 用比较两数之差的绝对值是否小于一个很小的数字(具体的可自己设定这样一个数,作为误差)来确定是否相等。C选项,a 为数组首地址是常量不能改变,所以A,B,C都是错的,选择D

本题易错在于错选B,没考虑浮点数在内存中的存储有差异

🍂 THREE.题目描述

以下程序的输出结果为( )

#include <stdio.h> 
int i; 
void prt() 
{ 
  for (i = 5; i < 8; i++)
  printf("%c", '*');
  printf("\t"); 
}
int main() 
{ 
for (i = 5; i <= 8; i++)
  prt(); 
  return 0; 
}

A: *** B: *** *** *** *** C: *** *** D: * * *

🍃题解

答案解析: 正确答案:A 全局变量i,在main()中修改为5,第一次在prt()中执行循环输出三次’*',i被修改为8,回到main()中第二次调用prt() 时,i<8为假,循环结束没输出,执行一次print(“\t”),再次回到主函数后i++变为9,i<=8为假,循环结束;

本题易错在于错选B,没考虑 i 是个全局变量

🍂 FOUR.题目描述

int main() {
int a=3;
printf(“%d\n”,(a+=a-=a*a)); return 0;
}
A: -6 B: 12 C: 0 D: -12

🍃题解

答案解析: 正确答案:C 给定条件表达式(M)?(a++):(a–)。 (表达式1)? (表达式2): (表达式3)为三目运算符。 计算规则为:先判断表达式1是否为真,若为真,则计算表达式2,并将表达式2的结果作为整个表达式最终的结果,表达式3 不计算;否则,表达式3的结果为最终结果,表达式2不计算。 在此表达式中,若M=0,为假,计算a–; 若M≠0,为真,计 算a++; 若要求与M等价,则要满足M取0时为假,取非0数值时为真。 c选项中:假定M取0,则M表示假,当M是0时,表达式 M!=0不成立,为假,计算a–; 当M取非0数值时,M为真,表达式M!=0成立,为真,计算a++; 符合题意,选C

本题易错在于错选B,首先a* a = 9 ,a = a - 9; a = -6;最后 a = a + -6 = -12;

🍂 FIVE.题目描述

1、设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )
A: n=0;while(ch=getchar()!=‘\n’)n++;
B: n=0;while(getchar()!=‘\n’)n++;
C: for(n=0;getchar()!=‘\n’;n++);
D: n=0;for(ch=getchar();ch!=‘\n’;n++);

🍃题解

答案解析: 正确答案:D 对于for循环,其中第一项初始化表达式只执行一次,因此ch只从输入流中取一个字符,之后就再不会取字符,因此会死循环

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
题目描述: 给你两个版本号 version1 和 version2 ,请你比较它们。 版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由多位数字组成,可能包含前导零。每个版本号至少包含一个字符。修订号从左到右编号,下标从0开始,最左边的修订号下标为0 ,下一个修订号下标为1,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。也就是说,修订号1和修订号001相等。如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,版本1.0 小于版本1.1,因为它们下标为0的修订号相同,而下标为1的修订号分别为0和1,0 < 1。 返回规则如下: 如果 version1 > version2 返回 1, 如果 version1 < version2 返回 -1, 否则返回 0。 示例 1: 输入:version1 = "1.01", version2 = "1.001" 输出:0 解释:忽略前导零,"01" 和 "001" 都表示相同的整数 "1" 示例 2: 输入:version1 = "1.0", version2 = "1.0.0" 输出:0 解释:version1 没有指定下标为 2 的修订号,即视为 "0" 示例 3: 输入:version1 = "0.1", version2 = "1.1" 输出:-1 解释:version1 中下标为 0 的修订号是 0,version2 中下标为 0 的修订号是 1 。0 < 1,所以 version1 < version2 示例 4: 输入:version1 = "1.0.1", version2 = "1" 输出:1 示例 5: 输入:version1 = "7.5.2.4", version2 = "7.5.3" 输出:-1 提示: 1 <= version1.length, version2.length <= 500 version1 和 version2 仅包含数字和 '.' version1 和 version2 都是 有效版本号

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Corwttaml

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值