算法刷题Day5: BM52 数组中只出现一次的两个数字

描述:
一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
要求:空间复杂度 O(1),时间复杂度O(n)。

题目传送门 is here

思路:

方法一:最简单的思路就是使用字典记录每个数的出现次数,最后再遍历一遍字典出现次数为1的数。(空间复杂度 O(n),时间复杂度O(n)。空间复杂度不满足题目条件。)

:)小妙招:使用字典的mydict[key] = mydict.get(key, 0)函数可以轻松将字典不存在的值设置为初始值0。

方法二:还是要用一个字典记录,但是如果出现第二次就remove掉,因此最后字典就只剩下出现一次的数值。(空间复杂度 O(n),时间复杂度O(n)。空间复杂度不满足题目条件。)

基础知识: 使用mydict.get(key)获取key值,无就会返回None

方法三:利用 异或 和 与 运算。

假设只出现一次的数为ab。 大体思路分为三个步骤
步骤一
整个数组的数都异或一遍,最终的值为c = a^b
步骤二
打住!先花30秒思考如何利用c来得出a和b?
…1s…
…2s…
…3s…
.
.
…30s… okk 想到了吗?反正我没想到。[尬住哈]

答案:还记得异或特点是不同为1吗,a, b 两个不同的数异或出来,肯定会有至少某一位数是1。对吧。
上栗子! 100 ^ 110 = 010 中间那位不一样 001 ^ 100 = 101 头尾两位不一样。 所以我们可以利用c 中为1的那一位,用来区分出 ab
具体做法就是,找为1的那一位,将整个数组分成两组数,一组含a和重复数, 另一组含b和重复数。 至此橘事已定。
步骤三
最后梅开二度,再来一遍异或。分别对这两组数进行异或运算,最终得出一组异或值为a, 另一组的异或值为b

回忆那死去的数学:
异或特点就是:两个相同的数异或结果为0,a ^ a = 0 ,相互抵消掉了。一个数异或0结果不变。 b ^ 0 = b
因此1 ^ 1 ^ 4 = 4
与操作特点:相同为1,不同为0,可以区分某个位上是0还是1。举个栗子:使用001分别与上000, 001, 010, 011 可以将一组数区分成000、010001,011两组数,这两组数的特点是最后一位不相同。

代码:

#from typing import List
class Solution:# 方法一: count每个数的次数def FindNumsAppearOnce1(self , nums: List[int]) -> List[int]:# write code herecnt = {}for item in nums:cnt[item] = cnt.get(item, 0) + 1print(cnt)result = []for k ,v in cnt.items():if v == 1:result.append(k)return sorted(result)# 方法二:出现过就removedef FindNumsAppearOnce2(self , nums: List[int]) -> List[int]:# write code herecnt = {}for item in nums:if cnt.get(item) == None:cnt[item] = 1else:del cnt[item]result = []for k,_ in cnt.items():result.append(k)return sorted(result)# 方法三:使用异或def FindNumsAppearOnce(self , nums: List[int]) -> List[int]:# 步骤一:全部异或一遍tmp = nums[0]for i in range(1,len(nums)):tmp = tmp ^ nums[i]print(tmp)# 步骤二:得出只有两个数得异或之后,从低位开始选择,第一个为1的那位,可以对这两个数进行分组group_num = 1while group_num & tmp == 0:group_num = group_num << 1print(bin(group_num))# 步骤三:进行分组group1 ,group2 = 0,0list1 ,list2 = [],[] # 这两个list只是拿来看看分组情况,最后[1,4,1,6] 会分成 [1,4,1] [6]for item in nums:if item & group_num == 0:list1.append(item)group1 = group1^item    # 对组1的数进行异或else:list2.append(item)group2 = group2^item    # 对组2的数进行异或print("group: ",list1, list2)if group1 > group2:return [group2, group1]else:return [group1, group2]#so = Solution()
#exp1 = [1,4,1,6]
#print(so.FindNumsAppearOnce(exp1))

昨天做的题,今天写个博客梳理一下。方法三里面考到的数学知识已经忘了,复习起来花了不少时间。本来用方法一和方法二就能通过了,觉得方法三没必要了。但是仔细一看空间复杂度,居然是O(1) ,那方法一、二的空间复杂度是O(n),老不达标了。 牛客网放我过了,但是比赛或者面试的oj就没有那么仁慈了。因此还是要重视起时间复杂度和空间复杂度。有一位比赛大佬和我说,有时候呢,可以从这个时间复杂度还有数组的规模来判断用的是什么解法。比如时间复杂度为1s,数组长度>10^9次方。那肯定只能遍历一遍数组了,于是乎两层for循环那肯定过不了的。

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

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

相关文章

通俗易懂:序列标注与命名实体识别(NER)概述及标注方法解析

目录 一、序列标注&#xff08;Sequence Tagging&#xff09;二、命名实体识别&#xff08;Named Entity Recognition&#xff0c;NER&#xff09;**命名实体识别的作用****命名实体识别的常见实体类别** &#xff1a; 三、标签类型四、序列标注的三种常见方法1. **BIO&#xf…

wareshark分析mysql协议的数据包

使用wareshark 分析mysql协议的数据包&#xff0c;是每个dba都应该掌握的技能&#xff0c;掌握以后&#xff0c;就可以通过tcpdump抓包分析&#xff0c;得到连接报错的信息了。 tcpdump抓包命令&#xff1a; tcpdump -nn -i bond0 dst 10.21.6.72 and port 4002 -w 1129_tcpdu…

Shell脚本小练习

学习了这么长时间Shell脚本&#xff0c;总得来一次小小的练习吧&#xff0c;那么请看下文&#xff01; 1.用Shell写一个小计算器。 通过read命令获取用户输入的表达式&#xff0c;表达式的格式设定为操作数1 运算符 操作数2&#xff0c;例如53&#xff0c;然后利用设计的脚本…

leetcode102:二叉树的层序遍历

给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&#xff1a; 输入&a…

《操作系统 - 清华大学》6 -3:局部页面置换算法:最近最久未使用算法 (LRU, Least Recently Used)

文章目录 1. 最近最久未使用算法的工作原理2. 最近最久未使用算法示例3.LRU算法实现3.1 LRU的页面链表实现3.2 LRU的活动页面栈实现3.3 链表实现 VS 堆栈实现 1. 最近最久未使用算法的工作原理 最近最久未使用页面置换算法&#xff0c;简称 LRU&#xff0c; 算法思路&#xff…

3. STM32_串口

数据通信的基础概念 什么是串行/并行通信&#xff1a; 串行通信就是数据逐位按顺序依次传输 并行通信就是数据各位通过多条线同时传输。 什么是单工/半双工/全双工通信&#xff1a; 单工通信&#xff1a;数据只能沿一个方向传输 半双工通信&#xff1a;数据可以沿两个方向…

Postman设置接口关联,实现参数化

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 postman设置接口关联 在实际的接口测试中&#xff0c;后一个接口经常需要用到前一个接口返回的结果&#xff0c; 从而让后一个接口能正常执行&#xff0c;这…

Redis设计与实现 学习笔记 第二十二章 二进制位数组

Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理二进制位数组&#xff08;bit array&#xff0c;又称“位数组”&#xff09;。 SETBIT命令用于为位数组指定偏移量上的二进制位设置值&#xff0c;位数组的偏移量从0开始&#xff0c;而二进制位的值可以是0或1&…

Linux服务器安装Linux宝塔面板部署wordpress网站以及雷池WAF

一、Linux服务器安装Linux宝塔面板 这个步骤参考网上其他教程。 二、Linux宝塔面板部署wordpress网站 这个步骤参考网上其他教程&#xff0c;保证网站能够正常访问&#xff0c;并且使用Linux宝塔面板申请并部署了SSL证书&#xff0c;使用https协议正常访问。 三、Linux宝塔…

C++学习日记---第14天(蓝桥杯备赛)

笔记复习 1.对象的初始化和清理 对象的初始化和清理是两个非常重要的安全问题&#xff0c;一个对象或者变量没有初始状态&#xff0c;对其使用后果是未知&#xff0c;同样的使用完一个对象或者变量&#xff0c;没有及时清理&#xff0c;也会造成一定的安全问题 构造函数&…

算法编程题-煎饼排序 不含AAA或者BBB的字符串

算法编程题-煎饼排序 &&不含AAA或者BBB的字符串 煎饼排序原题描述思路简述代码实现复杂度分析 不含AAA或者BBB的字符串原题描述思路简述代码实现复杂度分析 摘要&#xff1a;本文将对两道LeetCode原题进行介绍&#xff0c;分别是煎饼排序和不含AAA或者BBB的字符串。在陈…

【C/C++】内存管理详解:从new/delete到智能指针的全面解析

文章目录 更多文章C/C中的传统内存管理方式new和delete运算符malloc和free函数传统内存管理的弊端 智能指针的崛起智能指针的定义与作用C11引入的标准智能指针 详解C标准智能指针std::unique_ptr特点使用方法适用场景 std::shared_ptr特点使用方法适用场景 std::weak_ptr特点使…

Vue进阶之单组件开发与组件通信

书接上篇&#xff0c;我们了解了如何快速创建一个脚手架&#xff0c;现在我们来学习如何基于vite创建属于自己的脚手架。在创建一个新的组件时&#xff0c;要在新建文件夹中打开终端创建一个基本的脚手架&#xff0c;可在脚手架中原有的文件中修改或在相应路径重新创建&#xf…

深度学习的python基础(1)

一.tensor创建 1.张量的定义 张量在形式上就是多维数组&#xff0c;例如标量就是0维张量&#xff0c;向量就是一维张量&#xff0c;矩阵就是二维张量&#xff0c;而三维张量就可以想象RGB图片&#xff0c;每个channel是一个二维的矩阵&#xff0c;共有三个channel&#xff0…

scss文件内引入其他scss文件报错

在 Sass (SCSS) 中&#xff0c;import 语句用于在当前文件中导入其他 Sass 文件&#xff0c;以便你可以重用样式和变量等。然而&#xff0c;从 Dart Sass 1.23.0 版本开始&#xff0c;import 语句已经被标记为弃用&#xff08;deprecated&#xff09;&#xff0c;并计划在未来的…

Unity3D模型场景等测量长度和角度功能demo开发

最近项目用到多段连续测量物体长度和角度功能&#xff0c;自己研究了下。 1.其中向量角度计算&#xff1a; 需要传入三个坐标来进行计算。三个坐标确定两条向量线段的方向&#xff0c;从而来计算夹角。 public Vector3 SetAngle(Vector3 p1, Vector3 p2,Vector3 p3) { …

【MATLAB】基于RSSI的蓝牙定位与例程,设置4个基站、二维定位

目录 ​编辑 商品描述 主要功能 技术细节 适用场景 下载链接 商品描述 这款基于接收信号强度指示&#xff08;RSSI&#xff09;原理的蓝牙定位程序&#xff0c;专为需要高效、可靠定位解决方案的开发者和研究人员设计。它能够在二维平面内&#xff0c;通过4个锚点实现对未…

【学习笔记】基于RTOS的设计中的堆栈溢出(Stack Overflow)-第1部分

本文由RTOS专家Jean J. Labrosse撰写。 基于RTOS的应用程序中的每个任务都需要自己的堆栈,堆栈的大小取决于任务的要求(例如,函数调用嵌套、传递给函数的参数、局部变量等)。 为了避免堆栈溢出,开发人员需要过度分配堆栈空间,但不要太多,以避免浪费RAM。 什么是堆栈溢…

ROC曲线

文章目录 前言一、ROC的应用&#xff1f;二、使用方式1. 数据准备2.绘图可视化 前言 在差异分析中&#xff0c;ROC曲线可以用来评估不同组之间的分类性能差异。差异分析旨在比较不同组之间的特征差异&#xff0c;例如在基因表达研究中比较不同基因在不同条件或组织中的表达水平…

基数排序(代码+注释)

#include <stdio.h> #include <stdlib.h>// 获取数组中的最大值 int GetMax(int* a, int n) {int max a[0];for (int i 1; i < n; i) {if (a[i] > max) {max a[i];}}return max; }// 对数组按照某个位数进行计数排序 void CountingSortForRadix(int* a, i…