从0备战蓝桥杯:找出只出现一次的数字,数单身狗

news2024/11/21 1:41:46

        前言:在部分大厂笔试时经常会使用OJ题目,这里对《剑指offer》中的俩个题目进行思路分析和讲解,希望对各位读者有所帮助。 题目来源选自力扣网

目录

单个只出现一次的数字:

力扣链接:

题目描述 :

思路分析: 

位运算

完整代码:

输出结果:

俩个只出现一次的数字:

思路分析:

完整代码:

输出结果:


单个只出现一次的数字:

力扣链接:

136. 只出现一次的数字 - 力扣(LeetCode)

题目描述 :

        给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

示例 1 :

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

示例 2 :

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

示例 3 :

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

思路分析: 

如果不考虑时间复杂度和空间复杂度的限制,这道题有很多种解法,可能的解法有如下几种

  • 使用集合存储数字:遍历数组中的每个数字,如果集合中没有该数字,则将该数字加入集合,如果集合中已经有该数字,则将该数字从集合中删除,最后剩下的数字就是只出现一次的数字。
  • 使用哈希表存储每个数字和该数字出现的次数:遍历数组即可得到每个数字出现的次数,并更新哈希表,最后遍历哈希表,得到只出现一次的数字。
  • 使用集合存储数组中出现的所有数字,并计算数组中的元素之和:由于集合保证元素无重复,因此计算集合中的所有元素之和的两倍,即为每个元素出现两次的情况下的元素之和。由于数组中只有一个元素出现一次,其余元素都出现两次,因此用集合中的元素之和的两倍减去数组中的元素之和,剩下的数就是数组中只出现一次的数字。

那有没有什么简单又高效的算法呢?

位运算

对于这道题,可使用 异或运算 ⊕,异或运算有以下三个性质:

  • 任何数和 0 做异或运算,结果仍然是原来的数
  • 任何数和其自身做异或运算,结果是 0
  • 异或运算满足交换律和结合律

我们举个例子进行说明,我们给定一个表达式,然后进行运算: 1⊕2⊕3⊕4⊕4⊕3⊕2⊕1

  1. 对于串表达式使用交换律,他就等价于 1⊕1⊕2⊕2⊕3⊕3⊕4⊕4
  2. 对其使用结合律就可以得到,(1⊕1)⊕(2⊕2)⊕(3⊕3)⊕(4⊕4)
  3. 我们再对其使用第二条性质,就可以得到他的结果:0⊕0⊕0⊕0
  4. 那么最后结果就是 0 

那我们要是再在上述表达式末尾再加一个数呢?我们给定如下:1⊕2⊕3⊕4⊕4⊕3⊕2⊕1⊕7

  1. 根据我们上述的推论,前 8 位数字亦或后的结果为 0 
  2. 也就是说表达式可以化简如下:0⊕7
  3. 那我们再根据第一条性质,表达式最后的结果就是 7 

        我们不妨再看看刚才的表达式,这不就是在一个大小为 9 的数组里面进行查找只出现一次的数字吗?那么到了这里思路就很清晰了,对整个数组进行异或运算,最后得出的结果就是我们要查找的 “只出现一次的数字” 

完整代码:

因此,我们给出代码如下:

int singleNumber(int* nums, int numsSize)
{
	int single = 0;
	for (int i = 0; i < numsSize; i++)
	{
		single ^= *(nums + i);
	}
	return single;
}

 我们也可以自己给出一个数组进行验证输出结果:

int main()
{
	int arr[] = { 5,3,2,2,3,4,5 };
	int single = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
		//single = single ^ arr[i];
		single ^= arr[i];
	}

	printf("单身狗 是%d\n", single);
	return 0;
}

输出结果:


俩个只出现一次的数字:

思路分析:

        题目描述还是和上题一样,但是如果有俩个只出现一次的数字呢?倘若还是按照上述的解决方法处理,我们对整个数组进行异或运算后得到的值就相当于是对俩个单身狗进行异或运算的值,比如数组中有2个单身狗,一个是 5,一个是 7,他们的异或的结果是 2,就结果而言,这个值既不是 5,也不是 7,这个值没有任何意义,它什么都不是

        对此,我们又该如何解决呢?

        其实如果我们可以成功的将俩个整个数组分成俩组每一组都只有一个只出现一次的数字,然后我们对这俩个数组分别使用第一道题目的方法就可以了,理论存在,那我们开始着手实现

        首先,怎么分,用什么分,怎么才能恰好的让俩个单独出现的数字分开,我们不妨想一想,可不可以利用刚才我们说到的那个没有意义的值,我们用二进制来思考思考

  • 5 的二进制:0101
  • 7 的二进制:0111
  • 2 的二进制:0010

        我们可以发现,俩个数字之所以不同,是因为他们的二进制不同,而俩个单身狗也是如此,那我们只需要找到他们某一位的二进制是不同的,然后以这一位二进制作为判定标准,然后就可以将俩个单身狗分别放入俩个数组

因此我们设计思路如下:

  1. 对整个数组进行异或,得到一个值(俩个单身狗异或的值)
  2. 对整个数从右往左数,找到第一位不是 0 的数,并且记录下该数的位数 count
  3. 对整个数组遍历判断,对整个数组往右右移 count 位,然后和 1 进行与运算如果为结果为 1 就放进一个数组,如果为 0 就放进另一个数组
  4. 然后对俩个数组分别进行异或操作,得到俩个单身狗

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };
	int arr1[10] = { 0 };
	int arr2[10] = { 0 };
	int diff = 0;
	int count = 0;
	int dog1 = 0;
	int dog2 = 0;
	//找到俩个单身狗的异或结果
	for (int i = 0; i < 10; i++)
	{
		diff ^= arr[i];
	}
	//找到需要判定的位数
	for (int i = 0; i < 32; i++)
	{
		if ((diff >> i) & 1)
		{
			count = i;
			break;
		}
	}
	int j = 0;
	int k = 0;
	//分组
	for (int i = 0; i < 10; i++)
	{
		if ((arr[i] >> count) & 1)
		{
			arr1[j++] = arr[i];
		}
		else
		{
			arr2[k++] = arr[i];
		}
	}
	//找出俩个单身狗
	for (int i = 0; i < 10; i++)
	{
		dog1^= arr1[i];
		dog2^= arr2[i];
	}
	printf("俩个单身狗分别是%d和%d", dog1, dog2);

	return 0;
}

输出结果:




本次的分享就到此为止了,如果您有更好的思路和算法,欢迎在评论区积极讨论,感谢您的支持

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

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

相关文章

1.Vue-在独立页面实现Vue的增删改查

题记 在独立页面实现Vue的增删改查&#xff0c;以下是具体的代码&#xff0c;和操作流程。 编写index.html页面 index.html文件如下&#xff1a; <!DOCTYPE html> <html> <head><title>Vue CRUD Example</title><!--在线导入vue文件-->&l…

【网络协议】聊聊网络分层

常用的网络协议 首先我们输入www.taobao.com&#xff0c;会先经过DNS进行域名解析&#xff0c;转换为59.82.122.115的公网IP地址。然后就会发起请求&#xff0c;一般来说非加密的使用http&#xff0c;加密的使用https。上面是在应用层做的处理&#xff0c;那么接下来就是到传输…

Ansible运行临时命令及常用模块介绍

目录 一.运行临时命令 1.基本语法格式 2.查看当前版本已安装的所有模块 二.ansible常见模块 1.command模块 2.shell模块 3.raw模块 4.script模块 5.file模块 参数列表&#xff1a; 示例&#xff1a; 6.copy模块 参数列表&#xff1a; 示例&#xff1a; 7.fetch模…

SSL证书能选择免费的吗?

当涉及到保护您的网站和您的用户的数据时&#xff0c;SSL证书是必不可少的。SSL证书是一种安全协议&#xff0c;用于加密在Web浏览器和服务器之间传输的数据&#xff0c;例如信用卡信息、登录凭据和个人身份信息。 但是&#xff0c;许多SSL证书都是付费的&#xff0c;这可能会…

Java应用的混淆、加密以及加壳

文章目录 前言问题代码混淆存在的问题Java类文件加密存在的问题虚拟化保护存在的问题AOT编译存在的问题 Java应用的打包混淆器类加载与类加密Bootstrap Class LoaderExtension Class LoaderSystem Class Loader自定义ClassLoaderprotector4j 加壳采用Golang打包Java程序xjar 参…

基于未来搜索优化的BP神经网络(分类应用) - 附代码

基于未来搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于未来搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.未来搜索优化BP神经网络3.1 BP神经网络参数设置3.2 未来搜索算法应用 4.测试结果…

2023年四川省安全员B证证考试题库及四川省安全员B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年四川省安全员B证证考试题库及四川省安全员B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

Filebeat 采集 k8s Pod 和 Events 日志实战操作

文章目录 一、概述1&#xff09;采集 Pod 日志流程介绍3&#xff09;采集 Events 日志流程介绍 二、K8s 集群部署三、ElasticSearch 和 kibana 环境部署四、Filebeat 采集配置1&#xff09;采集 Pod 日志配置2&#xff09;采集 Events 日志配置1、创建 filebeat 授权 token2、f…

网络 | 排错五大步骤,没有解决不了的网络故障准达信息准达信息

网络故障是我们工作中最易常见的问题&#xff0c;那么如何才能进行网络排查&#xff0c;快速解决问题呢&#xff1f; 一、网络排错五大基本步骤与命令 五大基本思路如下&#xff1a; &#xff08;1&#xff09;检查物理链路是否有问题&#xff1b; &#xff08;2&#xff09;…

【总结】两个独立同分布的随机变量相加还是原来的分布吗?

二项分布&#xff0c;泊松分布&#xff0c;正态分布&#xff0c;卡方分布&#xff0c;具有独立可加性。 图源自没咋了&#xff0c;面哥课程。

【软考】9.3 二叉树存储/遍历/线索/最优/查找/平衡

《树与二叉树》 二叉树的顺序存储结构 顺序存储只适用于完全二叉树和满二叉树&#xff0c;一般二叉树不适用i 2 的左孩子为 2i 4&#xff0c;右孩子为 2i 1 5 二叉树的链式存储结构 链式存储适用于二叉树&#xff1b;空结点用“∧”表示二叉链表&#xff1a;左孩子&#xff0…

论文阅读:CenterFormer: Center-based Transformer for 3D Object Detection

论文地址&#xff1a;[2209.05588] CenterFormer: Center-based Transformer for 3D Object Detection (arxiv.org) 代码地址&#xff1a;GitHub - TuSimple/centerformer: Implementation for CenterFormer: Center-based Transformer for 3D Object Detection (ECCV 2022) …

Java多线程下载文件

JVM是支持多线程程序的&#xff0c;当程序需要同时执行两个或多个任务&#xff0c;实现一些需要等待的任务时&#xff0c;如用户输入、文件读写、网络操作、搜索等多线程程序比单线程程序更具优势&#xff0c;可充分利用CPU资源&#xff0c;完成时间更短&#xff0c;提高应用程…

代码管理工具 gitlab实战应用

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay 第八章 Sprin…

Dokcer基础操作命令演示

Docker中的常见命令&#xff0c;可以参考官方文档&#xff1a;https://docs.docker.com/engine/reference/commandline/cli/ 1、命令介绍 其中&#xff0c;比较常见的命令有&#xff1a; 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerRegistr…

【大数据】Apache Hive数仓(学习笔记)

一、数据仓库基础概念 1、数仓概述 数据仓库&#xff08;数仓、DW&#xff09;&#xff1a;一个用于存储、分析、报告的数据系统。 OLAP&#xff08;联机分析处理&#xff09;系统&#xff1a;面向分析、支持分析的系统。 数据仓库的目的&#xff1a;构建面向分析的集成化数据…

【Eclipse】Plug-in Development 插件的安装

先按路线找到需要的页面&#xff1a;eclipse–Window–Preferences–Java–Editor–Content Assist 在Work with框中输入&#xff1a;http://download.eclipse.org/releases/2019-06 PS&#xff1a;后面的2019-06是eclipse发行的时间 选择&#xff1a;General Purpose Tools 下…

TwinCAT3添加伺服控制器的方法

文章目录 一. 主要参考二. 使用嵌入式控制器CX5140添加三菱MR-J4-TM伺服控制器的方法具体步骤 一. 主要参考 《TwinCAT NC 使用指南》第四章 TwinCAT NC 控制总线伺服 二. 使用嵌入式控制器CX5140添加三菱MR-J4-TM伺服控制器的方法 嵌入式控制器: 倍福CX5140伺服控制器&…

【Eclipse】解决插件下载速度太慢

解决方案&#xff1a;修改镜像 下面列出几个国内的镜像网站&#xff1a; 中国科学技术大学(5.6MB/s) http://mirrors.ustc.edu.cn/eclipse/ 北京理工大学&#xff08;600KB/s&#xff09; http://mirror.bit.edu.cn/eclipse/ 大连东软信息学院(400KB/s) http://mirrors.neuso…

入门小白拥有服务器的建议

学习网络知识 当我们拥有了一台服务器以后,需要提前准备学习一些网络、服务器、互联网方便的知识, 以备在后续学习工作中使用。 建议的网络知识学习清单: 1. 网络基础知识:包括网络拓扑结构、协议、IP地址、子网掩码、网关等基础概念。 2. 网络安全:包括网络攻击类型、防…