好题分享(2023.10.22——2023.10.28)

news2025/1/12 18:09:05

目录

​编辑

前言:

题目一:《消失的数字》

1.先排序再遍历

2.异或

3.等差数列求和,再相减 

题目二:《轮转数组》

1.开辟新的数组

2.原地逆序 

题目三:《移除元素》

题目四:《删除有序数组的重复项》

题目五:关于时间复杂度的好题分析

 总结:


前言:

本专栏每周都会有,用来记录自己这一周学习刷到的好题目,以及自己做错和理解错的题目。并且加以监督自己!!!

本文题目主要来自Leecode的OJ题,接下来我们来一道一道分析。。。

题目一:《消失的数字》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

对于该题目,我们将给出三种解法进行讲解。

1.先排序再遍历

int missingNumber(int* nums, int numsSize)
{
//先进行冒泡排序
	for(int i = 0;i<numsSize - 1;i++)
	{
		for(int j = 0;j<numsSize - i - 1;j++)
		{
			if(nums[j] > nums[j+1])
			{
				int tmp = nums[j+1];
				nums[j+1] = nums[j];
				nums[j] = tmp; 
			}
		}
	}
//遍历数组,再返回
    int i = 0;
	for(i = 0;i < numsSize; i++)
	{
		if(nums[i] != i)
		{
			return i;
		}
	}
    return i;
}

 该算法是最简单的方法,其中因为要进行冒泡排序,所以该算法的时间复杂度为O(N^2)

 本题的代码思路和实现较为简单,在这里我不做过多的赘述。

只是该算法效率很低,

2.异或

int missingNumber(int* nums, int numsSize)
{
	int sum = 0;
    //0——numsSize进行异或得到sum
	for (int i = 0; i < numsSize + 1; i++)
	{
		sum ^= i;
	}

    //sum与nums[0——numsSize-1]进行异或,剩下的值就是消失的数字
	for (int i = 0; i < numsSize; i++)
	{
		sum ^= nums[i];
	}
	return sum;
}

我们先简单了解了解异或这个概念。

所谓异或,就是相同为0,相异为1。 

那么对于第一个循环,得到sum可以这样理解: 

 

因为异或是可以实现交换律的,即3^5^4 == 3^5^4是一样的。

那么对于第二个循环的实现,可以这样理解:

由此一来就可以得到sum,也就可以得到消失的数字2。

该算法的时间复杂度为O(N) 。

3.等差数列求和,再相减 

int missingNumber(int* nums, int numsSize)
{
	int sum = ((0 + numsSize)*(numsSize + 1)) / 2;//等差求和
	for (int i = 0; i < numsSize; i++)
	{
		sum -= nums[i];//求和完后减去数组中的每一项,剩下的就是消失的数字
	}
	return sum;
}

这种算法相对好理解,其实就是将0——numsSize的等差数列进行求和

再对数组中的各个元素相减,最后相减完的数就是消失的数字。

该算法的时间复杂度为O(N) 

题目二:《轮转数组》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 对于本道题目,我们将给出两种方法进行讲解。

1.开辟新的数组

void rotate(int* nums, int numsSize, int k){
    int tmp[numsSize];
    //考虑到k可能大于nusSize,而轮转数组可以理解为一个圆
    k = k%numsSize;
    int j = k;
    //拷贝前numsSize - k 个
    for(int i = 0;i<numsSize -k;i++)
    {
        tmp[j++] = nums[i];
    }

    //拷贝后k个
    j = 0;
    for(int i = numsSize - k;i<numsSize;i++)
    {
        tmp[j++] = nums[i];
    }

    //将nums进行覆盖
    for(int i = 0;i<numsSize;i++)
    {
        nums[i] = tmp[i];
    }
}

这个算法很好理解。

 

该种算法属于是牺牲空间换取时间的做法,时间复杂度为O(N) 

 

2.原地逆序 

void reverse(int* nums, int numsSize)
{
	int left = 0;
	int right = numsSize - 1;
	int tmp = 0;
	while (left<right)
	{
		tmp = nums[left];
		nums[left] = nums[right];
		nums[right] = tmp;
		right--;
		left++;
	}
}

void rotate(int* nums, int numsSize, int k){
	k %= numsSize;
	reverse(nums, numsSize);//逆序整个数组
	reverse(nums + k, numsSize - k);//逆序后k个元素
	reverse(nums, k);//逆序前k个元素
}

在这里我们就要讲解一下为什么要进行k %= numsSize这个操作。

当k == 6的时候,轮转的数组应当是2,3,4,5,6,7,1.

而当k==7时,轮转的数组就是1,2,3,4,5,6,7

又当k == 8时,轮转的数组就是7,1,2,3,4,5,6

所以我们可以看出,k == 7时和 k ==0时没有区别,就像k == 8 与 k == 1没有区别。

因此我们就利用取余操作,来给k赋值,这样可以大大减少程序的计算。 

而对于这种算法来说,我们给出以下解释:

该算法的时间复杂度则为O(N) 

题目三:《移除元素》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

对于该题目,我们要注意的是我们是在空间复杂度为O(1)的情况下完成此题目,意思就是我们不能创建新的临时数组来接受元素并进行判断。

对于这道题目来说,我们可以参考之前讲解的模拟实现strstr来进行编写。

模拟实现strstr的blog如下,需要参考的可以访问以下链接

模拟字符串函数_无双@的博客-CSDN博客 

接下来就是本题目的一种算法,采取的是双指针的算法

int removeElement(int* nums, int numsSize, int val){
    int right = 0;
    int left = 0;

    while(right < numsSize)
    {
        if(nums[right] != val)
        {
            nums[left++] = nums[right++];
            continue;
        }
        right++;
    }
    return left;
}

该算法时间复杂度为O(N)

具体解法如下图所示

实现循环while(right<numsSize)

在这里我们假设val为2

如果我们nums[right]的值不等于val,将nums[right]的值覆盖到nums[left]

然后两指针都加加,直到如图:

此时直接跳到right++,left不动。

则right会到达

 

此时就又会进行覆盖操作,即

 

覆盖完后,两个都加加,则此时继续遍历

 

直到出现如图所示的结果,接下来return left,就得到了数组的元素个数,即5。

如此该算法实现完毕

 

题目四:《删除有序数组的重复项》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 对于本题目,我们采取的与上题的算法思路一样,运用双指针的方式来进行实现。

时间复杂度仍然为O(N)

int removeDuplicates(int* nums, int numsSize){
	int left = 0;
	int right = 0;
	while (right<numsSize)
	{
		if (nums[left] != nums[right])
		{
			nums[++left] = nums[right];
		}
		right++;
	}
	return left + 1;
}

 对于改题目,讲解如下

刚开始,先定义left和right,指向首元素地址。

刚开始循环的时候,nums[right]一直== nums[left]

所以right一直++直到,

 

 此时进入if语句中,实现覆盖操作:

再接下来,right一直++。

 

再进行覆盖操作, 

然后right继续++。

 

再进行覆盖。

 

如此就可以得到答案,这就是本算法的基本实现。

这里要注意的是,在覆盖的时候,我们应当先提前对left进行++操作,即前置++。

这样保证left可以先到下一元素,再进行覆盖 。

如果是后置++,则会覆盖上一次覆盖的值。

题目五:关于时间复杂度的好题分析

void fun(int n) {
  int i=l;
  while(i<=n)
    i=i*2;
}

求此代码的时间复杂度。

解析: 此函数有一个循环,但是循环没有被执行n次,i每次都是2倍进行递增,所以循环只会被执行log2(n)次。 

可以理解为:

 总结:

以上就是本周刷到的好题目。

本文的代码在我的Gitee仓库里:

Leecode_10.22-10.28_CSDN/Leecode_10.22-10.28_CSDN/test_10_28.c · 无双/Data structures amd algorithms - Gitee.com

编程题均来自Leecode,每道题我都有放置网站OJ题,希望大家可以下来做一做。

记住

坐而言不如起而行。

Action speak louder than words!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1146677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java每日一题】——第四十三题:USB接口程序设计。(2023.10.29)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

拉扎维模拟CMOS集成电路设计西交张鸿老师课程P2~5视频学习记录

目录 p2 p3 p4 p5 --------------------------------------------------------------------------------------------------------------------------------- p2 -----------------------------------------------------------------------------------------------------…

问题 U: 折线分割平面(类比+规律)

规律类比&#xff1a; 1.一个折线的角&#xff0c;只会对应一个部分 2.若反向延长&#xff0c;角对应的部分被分为3部分 &#xff08;即一条折现线改为两条直线&#xff09; 3.所以n条折线分成的平面数&#xff0c;等于2n条直线减去2n 代码实现&#xff1a;

小程序源文件的简单获取方法分享

小程序的源文件地址 在微信的服务器上。普通用户想要直接获取到在微信服务器去获取,肯定是十分困难的,有没有别的办法呢? 简单思考一下我们使用小程序的场景就会明白,当我们点开一个微信小程序的时候,其实是微信已经将它的从服务器上下载到了手机,然后再来运行的。所以我…

【AD9361 数字接口CMOS LVDSSPI】A 并行数据之CMOS

〇、综述 本章介绍并行数据端口&#xff08;P0_D P1_D&#xff09;和串行外设接口&#xff08;SPI&#xff09;&#xff0c;用于在AD9361和BBP之间传输数据和控制/状态信息。 下图显示了这些接口&#xff0c;并提供了AD9361和BBP在宽带无线系统中的使用方式的高级视图。数据接…

python无向图最短距离问题

题目&#xff1a; 如下图所示无向图&#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;&#xff0c;其中蓝色边的长度是 1、橘色边的长度是 2、绿色边的长度是 3&#xff0c;求从 A 点到 S 点的最短距离为多少&#x1f914; 我们得明白一…

人工智能在疾病治疗中的应用:机遇与挑战

人工智能在疾病治疗中的应用&#xff1a;机遇与挑战 随着人工智能技术的飞速发展&#xff0c;其在诸多领域的应用价值日益显现。本文将探讨人工智能技术在疾病治疗中的应用&#xff0c;包括其背景意义、技术概述、具体应用、发展前景以及总结。 一、背景意义 随着医学技术的…

【24.两两交换链表中的节点】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:ListNode* swapPairs(ListNode* head) {if(headnullptr||head->nextnullptr) return head;ListNode* curhead,*nexthead->next;ListNode* nnextswapPairs(n…

第 116 场 LeetCode 双周赛题解

A 子数组不同元素数目的平方和 I 枚举&#xff1a;枚举子数组&#xff0c;用集合记录当前子数组中不同元素的个数 class Solution { public:using ll long long;int sumCounts(vector<int> &nums) {ll mod 1e9 7;int n nums.size();unordered_set<int> s;l…

C++深度优先(DFS)算法的应用:收集所有金币可获得的最大积分

涉及知识点 深度优化(DFS) 记忆化 题目 节点 0 处现有一棵由 n 个节点组成的无向树&#xff0c;节点编号从 0 到 n - 1 。给你一个长度为 n - 1 的二维 整数 数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示在树上的节点 ai 和 bi 之间存在一条边。另给你一个下标从 0…

微信小程序项目案例之导游证考试刷题小程序

前言 很多计算机专业的同学在做毕设选题时不知道该如何选题&#xff0c;有的同学是已经选择了要开发一款小程序&#xff0c;但是又不知道开发哪类小程序。本篇将为大家介绍一个小程序的开发方向&#xff0c;考试刷题类小程序是目前比较火的小程序项目之一&#xff0c;在小程序…

施耐德Lexium23A运行JOG停止时无减速过程解决方案

在现场调试时发现&#xff0c;如果Lexium23A工作在Pr模式下&#xff0c;无论是通过CANopen总线控制软件DI接通&#xff08;相应DI点设置为JOG运行&#xff09;还是实际的物理点接通&#xff0c;在JOG停止时&#xff0c;伺服电机会瞬间停止&#xff0c;造成机械冲击&#xff0c;…

响应式家居设计工作室网站模板源码

模板信息&#xff1a; 模板编号&#xff1a;849 模板编码&#xff1a;UTF8 模板颜色&#xff1a;橙色 模板分类&#xff1a;设计、广告、文化、影视 适合行业&#xff1a;广告设计类企业 模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff…

Redis(09)| Reactor模式

我们在使用Redis的时候&#xff0c;通常是多个客户端连接Redis服务器&#xff0c;然后各自发送命令请求(例如Get、Set)到Redis服务器&#xff0c;最后Redis处理这些请求返回结果。 从上一篇博文《Redis&#xff08;08&#xff09;| 线程模型》中知道Redis是单线程。Redis除了处…

<蓝桥杯软件赛>零基础备赛20周--第3周

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

ChatGPT 介绍

目录 什么是 AIGC&#xff1f; 图灵测试 chatgpt的发展历史 聊天机器人 Eliza Eliza 后辈 Alice 机器学习 smaterChild 人工神经网络 Transformer OpenAI (Generative Pre-trained Transformer&#xff09; AI会导致我们失业吗 什么是 AIGC&#xff1f; AIGC&#x…

一键添加命名前缀(文件)

&#xff08;一&#xff09;需求描述 在上班摸鱼的我正准备打开手机刷会儿CSDN论坛&#xff0c;老板发给我一个压缩包并要求我给里面所有的文件的名称添加一个前缀”大项目_”。我本以为只有几个文件需要改&#xff0c;便没放在心上&#xff0c;反倒是心里暗暗吐槽老板“这么简…

『力扣刷题本』:反转链表

一、题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a;…

20.2 OpenSSL 非对称RSA加解密算法

RSA算法是一种非对称加密算法&#xff0c;由三位数学家Rivest、Shamir和Adleman共同发明&#xff0c;以他们三人的名字首字母命名。RSA算法的安全性基于大数分解问题&#xff0c;即对于一个非常大的合数&#xff0c;将其分解为两个质数的乘积是非常困难的。 RSA算法是一种常用…