找出数组中重复的元素

2024-04-25

有一个大小为 n 的数组,数组中包含的元素在 1 到 n-1 之间,每个元素出现一次,只有一个元素出现多次。我们需要找到这个元素。

尽管这是一个非常常见的常见问题解答,但我仍然没有找到正确的答案。大多数建议是我应该将数组中的所有元素相加,然后从中减去所有索引的总和,但如果元素数量非常大,这将不起作用。它会溢出。还有关于使用异或门的建议dup = dup ^ arr[i] ^ i,我不清楚。

我想出了这个算法,它是加法算法的增强,将在很大程度上减少溢出的机会!

for i=0 to n-1
  begin :
    diff = A[i] - i;
    sum  = sum + diff;
  end

diff包含重复元素,但使用此方法我无法找到重复元素的索引。为此,我需要再次遍历数组,这是不可取的。谁能想出一个更好的解决方案,不涉及加法或 XOR 方法在 O(n) 中工作?


您可以通过多种方式来思考这个问题,具体取决于问题描述的限制。

如果您确实知道有一个元素是重复的,那么解决这个问题的方法有很多种。一种特别聪明的解决方案是使用按位异或运算符。 XOR 具有以下有趣的属性:

  1. XOR 是结合律,因此 (x ^ y) ^ z = x ^ (y ^ z)
  2. XOR 是可交换的:x ^ y = y ^ x
  3. XOR 是它自己的逆: x ^ y = 0 iff x = y
  4. XOR 以零作为恒等式:x ^ 0 = x

这里的属性 (1) 和 (2) 意味着当对一组值进行异或时,将异或应用于元素的顺序并不重要。您可以根据需要对元素重新排序或分组。属性 (3) 意味着,如果对相同的值进行多次异或,则会返回零,而属性 (4) 意味着,如果将任何值与 0 进行异或,则会返回原始数字。将所有这些属性放在一起,您会得到一个有趣的结果:如果对一组数字进行异或,则结果是该组中出现奇数次的所有数字的异或。这样做的原因是,当您将出现偶数次的数字异或在一起时,您可以将这些数字的异或分解为一组对。每对通过 (3) 与 0 进行异或,所有这些零的组合异或通过 (4) 返回零。因此,所有偶重数的数字都相互抵消。

要使用它来解决原始问题,请执行以下操作。首先,将列表中的所有数字异或在一起。这给出了所有出现奇数次的数字的异或,最终得到从 1 到 (n-1) 的所有数字,除了重复的数字。现在,将此值与从 1 到 (n-1) 的所有数字的 XOR 进行异或。然后,这会使之前未取消的 1 到 (n-1) 范围内的所有数字取消,只留下重复的值。此外,它的运行时间为 O(n),并且仅使用 O(1) 空间,因为所有值的 XOR 都适合单个整数。

In your original post you considered an alternative approach that works by using the fact that the sum of the integers from 1 to n-1 is n(n-1)/2. You were concerned, however, that this would lead to integer overflow and cause a problem. On most machines you are right that this would cause an overflow, but (on most machines) this is not a problem because arithmetic is done using fixed-precision integers, commonly 32-bit integers. When an integer overflow occurs, the resulting number is not meaningless. Rather, it's just the value that you would get if you computed the actual result, then dropped off everything but the lowest 32 bits. Mathematically speaking, this is known as modular arithmetic, and the operations in the computer are done modulo 232. More generally, though, let's say that integers are stored modulo k for some fixed k.

Fortunately, many of the arithmetical laws you know and love from normal arithmetic still hold in modular arithmetic. We just need to be more precise with our terminology. We say that x is congruent to y modulo k (denoted x ≡k y) if x and y leave the same remainder when divided by k. This is important when working on a physical machine, because when an integer overflow occurs on most hardware, the resulting value is congruent to the true value modulo k, where k depends on the word size. Fortunately, the following laws hold true in modular arithmetic:

例如:

  1. If x ≡k y and w ≡k z, then x + w ≡k y + z
  2. If x ≡k y and w ≡k z, then xw ≡k yz.

这意味着,如果您想通过查找数组元素的总和并减去预期总数来计算重复值,即使存在整数溢出,一切都会正常进行,因为标准算术仍然会产生相同的值(模 k)在硬件中。也就是说,您也可以使用基于 XOR 的方法,它根本不需要考虑溢出。 :-)

如果不能保证恰好有一个元素重复,但可以修改元素数组,然后有一个漂亮的算法来查找重复值。这个较早的问题 https://stackoverflow.com/questions/5739024/finding-duplicates-in-on-time-and-o1-space/5739336#5739336描述了如何实现这一点。直观地说,这个想法是您可以尝试使用桶排序 http://en.wikipedia.org/wiki/Bucket_sort,其中元素数组本身也被回收以保存存储桶的空间。

如果不能保证恰好有一个元素是重复的,并且无法修改元素数组,那么问题就困难得多。这是一个经典(而且很难!)的面试问题,据说 Don Knuth 花了 24 小时才解决。诀窍是将问题简化为一个实例周期发现 http://en.wikipedia.org/wiki/Cycle_detection通过将数组视为从数字 1-n 到 1-(n-1) 的函数,然后查找该函数的两个输入。然而,生成的算法称为Floyd 的环路查找算法 http://en.wikipedia.org/wiki/Floyd%27s_cycle-finding_algorithm#Tortoise_and_hare,极其美丽和简单。有趣的是,它与用于检测线性时间和恒定空间中链表中的循环的算法相同。我建议您查阅一下,因为它会定期出现在软件采访中。

有关算法的完整描述以及分析、正确性证明和 Python 实现,请查看这个实现 http://keithschwarz.com/interesting/code/?dir=find-duplicate这解决了问题。

希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

找出数组中重复的元素 的相关文章

  • flock():在没有竞争条件的情况下删除锁定的文件?

    我使用flock 来实现进程间命名互斥 即某个进程可以决定锁定 some name 这是通过锁定临时目录中名为 some name 的文件来实现的 lockfile tmp some name lock fd open lockfile O
  • 如何使用C#检测IIS版本?

    如何使用C 检测IIS版本 更新 我的意思是来自 winapp 实际上该场景是开发一个自定义安装程序 想要检查已安装 IIS 的版本以调用适当的 api 在这里找到了答案 链接文本 http forums iis net p 1162404
  • C 程序的“编译器正确”命令

    这是关于中提到的编译步骤Linux 期刊文章 https www linuxjournal com article 6463 C 程序是使用编译的cpp cc1 as and ld该文章中的命令 我能够执行这些步骤cpp as and ld
  • 与智能指针的返回类型协方差

    在 C 中我们可以这样做 struct Base virtual Base Clone const virtual Base struct Derived Base virtual Derived Clone const overrides
  • 同步和异步 API

    我正在开发一个库 它提供一些耗时的服务 我需要每个 API 有两个版本 一个用于同步函数调用 另一个用于异步 图书馆用户应决定使用哪个版本 服务结果可能对于系统继续运行 同步调用 至关重要 可能需要在不同的工作线程中完成相同的操作 因为结果
  • 将supportedRuntime嵌入到exe文件中

    我需要将仅包含supportedRuntime 设置的app config 文件嵌入到我的exe 文件中 我尝试执行构建操作嵌入资源 但它现在没有从配置文件中读取值 并且它不起作用 这是我的配置文件
  • 创建新视图时如何初始化视图模型中的属性?

    我有一个应用程序 可以打开一个视图 允许您搜索数据 然而 为了进行搜索 用户必须选择他想要在什么类别下进行搜索 目前 我正在尝试弄清楚如何将所选类别从主视图模型 作为 int 传递到新搜索视图的视图模型 目前我正在尝试在主视图中使用类似的东
  • C 预处理器“/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cpp”未通过完整性检查

    在使用 Xcode 11 3 的 macOS Mojave 上 我有一个基于 Autotool 的第三方库 在终端中运行我的构建脚本时构建得很好 但在 Xcode 中运行时失败Run Script步骤为 BuildScript Showin
  • C++ 标准是否保证未使用的私有字段会影响 sizeof?

    考虑以下结构 class Foo int a 在 g 中测试 我明白了sizeof Foo 4但这是由标准保证的吗 是否允许编译器注意到a是一个未使用的私有字段并将其从类的内存表示中删除 导致更小的 sizeof 我不希望任何编译器真正进行
  • 仅使用 url 嵌入视频

    给定一个 youtube url 我如何使用 net c 将视频嵌入到页面中 只需添加如下一行 将 autoplay 设置为 0 或 1 取决于您是否希望人们真正留在您的页面上
  • GoogleTest:如何跳过测试?

    使用 Google Test 1 6 Windows 7 Visual Studio C 如何关闭给定的测试 又名如何阻止测试运行 除了注释掉整个测试之外 我还能做些什么吗 The docs https github com google
  • ASP.NET MVC C#:将多个表/查询中的数据引入视图中

    好吧 我仍在掌握 ASP NET 和 MVC 框架的窍门 并将我的知识从经典的 ASP 和 VB 转换过来 所以请保持温柔 我的第一个视图 home details X 运行良好感谢之前的帮助为我指明了正确的方向 https stackov
  • List.Except 不起作用

    我尝试减去 2 个列表 如下代码所示 assignUsers已获得 3 条记录assignedUsers有 2 行 后Except方法我仍然得到 3 行 尽管我应该得到 1 条记录 因为 2 行assignedUsers类似于assignU
  • HTTP 错误 500.35 - ANCM 同一进程中的多个进程内应用程序 ASP.NET Core 3

    从今天早上开始 没有对项目代码进行任何更改 一个非常简单的 Web API 一个控制器和 3 个方法 使用 Swagger 它不再启动 我收到错误 HTTP 错误 500 35 ANCM 同一进程中有多个进程内应用程序 事件查看器报告最无用
  • 图像处理编程

    我想知道是否有任何方法可以使用某种编程语言检测图像中对象的位置 例如 如果我有一个球的图像 每 100 毫秒更新一次 是否可以通过某些程序使用某些东西来获取球的坐标 看一下OpenCV http opencv willowgarage co
  • 绑定到 ListView 项目从视图模型中点击的属性

    我正在尝试使用 itemtapped 属性将事件绑定到菜单页面上的 ListView 目前我在我的应用程序中使用 MVVM Xamarin 表单实验室 框架 我想要完成的是当用户点击菜单项时应用程序导航到正确的视图 这是xaml代码
  • Qt 对象的生命周期

    Qt 对象的生命周期是多少 Such as QTcpSocket socket new QTcpSocket 套接字什么时候会被销毁 我应该使用 delete socket 有什么区别吗 QTcpSocket socket 我找不到有关此的
  • 如何为 Blazor MapFallbackToFile() 生成正确的错误

    我有一个项目想要用作 Web API 和 Blazor wasm UI 该 API 也可以从其他项目访问 因此我希望该 API 向消费者提供有用的错误详细信息 我现在通过使用该网站来实现这两个目的MapFallbackToFile 方法 但
  • 使用 MVVM 绑定 Xamarin.Forms 中的属性

    我在使用 Xamarin Forms 和 MVVM 制作游戏时遇到问题 游戏中有一艘由用户控制的潜艇 并且有水雷掉落 因此用户必须避开这些水雷 这些地雷是在运行时使用 2 个计时器生成的 因此我用 XAML 中的 CollectionVie
  • 提高大型结构列表的二进制序列化性能

    我有一个以 3 个整数保存 3d 坐标的结构 在测试中 我将 100 万个随机点放在一起 List 然后对内存流使用二进制序列化 内存流大小约为 21 MB 这似乎非常低效 因为 1000000 点 3 坐标 4 字节应该至少为 11MB

随机推荐

  • 在以下任何来源中均未找到插件 [id: 'org.jetbrains.kotlin.jvm', 版本: '1.2.71']

    我全新安装了 IntelliJ 使用以下设置创建了一个新的 kotlin gradle 项目 这会生成以下 build gradle kts 完全相同的文件在我的 Windows 计算机上运行 import org jetbrains ko
  • 创建可以传递参数而无需创建新组件的函数

    我的问题与这个问题有关React用于渲染函数中的绑定函数 以下不是好的做法 render div 因为每次重新渲染都会向页面添加一个新功能 最终导致浏览器内存不足 解决方案是这样做 constructor this callFunction
  • Google Chrome 中 array.splice() 的时间复杂度是多少?

    如果我使用 splice 从数组中删除一个元素 如下所示 arr splice i 1 这会是O n 在最坏的情况下 因为它会移动 i 之后的所有元素 或者它是常数时间 下面有一些链表魔法 最坏的情况下should be O n 复制所有n
  • .NET:属性何时实例化?我可以获得它们所修饰的类型的引用吗?

    关于属性的两个问题 属性类什么时候实例化 当第一次访问类型时 还是在开始执行时 从属性类中 我可以找出该属性是为哪种类型实例化的吗 我的想法是 我想列出程序集中应用了我的属性的所有类的列表 我当然可以通过反射和检查来迭代所有这些 但如果该属
  • r中的模糊字符串匹配

    我有 2 个数据集 每个数据集超过 100K 行 我想根据匹配一列 电影标题 的模糊字符串以及使用发布日期来合并它们 我提供了下面两个数据集中的样本 数据集 1 itemid userid rating time title release
  • 更改 UISearchBar 的大小

    无法找到答案 也无法做我想做的事 CGSize searchBarSize self searchDisplayController searchBar frame size searchBarSize width
  • 如何使用 URLSession 从 url 获取 JSON 数据?

    我正在开发一个 iOS 应用程序 我必须从中获取数据this url https dl dropboxusercontent com s 2iodh4vg0eortkl facts json 我可以看到这个 url 包含 JSON 数据 所
  • Android FloatingActionButton 带有片段和底部导航栏

    我正在创建一个具有以下结构的 Android 应用程序 主要活动有一个底部导航栏 可在 3 个不同的片段之间切换 其中 2 个片段将显示项目列表 并使用浮动操作按钮 FAB 添加新项目 第三个片段将显示不同的内容 不需要 FAB 基于此 F
  • 使用 gradle 进行简单的 protobuf 编译

    如果您正在寻找示例 gradle protobuf 项目 请查看here https github com google protobuf gradle plugin tree master examples exampleProject
  • “没有路线匹配”错误?

    我是新的 Rspec 刚刚开始在 Rails 3 上生成一个新的控制器 它默认生成一些 Rspec 测试 我有一个关于如何让它们通过的问题 就目前情况而言 我在我的终端中看到了这个测试 1 BuildingsController GET s
  • 将数据写入文本文件

    我有一个简单的程序 将 7 个数字中的 6 个写入文本文件 从逻辑上讲 一切似乎都很好 但是 数字并未按预期写入文件 Random random new Random Console WriteLine Please enter the n
  • 将 json 数据 objectForKey 分配给类的属性的替代语法

    我可以将最后三行代码写在一行中吗 NSArray latestLoans self JsonData objectForKey loans for id object in latestLoans NSDictionary loan obj
  • 使用 Testcafe 访问 OpenVPN 限制的网站

    有一个网站只有在运行 OpenVPN Connect 2 1 3 111 配置文件时才能访问 我需要使用 Testcafe 访问该网站 但到目前为止我还没有找到任何有关使用 Testcafe 与 VPN 的文档 有什么我可能错过的吗 测试通
  • git clone 永远挂在 github 上

    当我按照 github 中的第 5 点 测试所有内容 时guide http help github com linux set up git ssh 命令也永远挂起 根据该指南 我应该看到一条消息 Github 不提供 shell 访问
  • Python 使 UMAP 更快(呃)

    我正在使用 UMAP https umap learn readthedocs io en latest https umap learn readthedocs io en latest 以减少数据的维度 我的数据集包含 4700 个样本
  • Math.min.apply 对于 null 返回 0

    我想从数组中获取最小值 如果数据包含null value Math min apply回报0 for null价值 请参见这个 JSFiddle 示例 http jsfiddle net jeryslo 7DCXw 即使数组中存在空值 如何
  • 使用 DirectSound 向后读取声音

    是否可以使用 DirectSound 的托管版本向后读取声音 如果没有 是否有另一个库可以轻松实现 您可以使用 WaveFileReader 和 WaveFileWriter 类NAudio http www codeplex com na
  • 如何在 python-docx 中将页面大小更改为 A4

    我尝试使用 python docx 创建 Word 文档 创建的文件的字母尺寸为 8 5 x 11 英寸 但在德国 标准格式是 A4 8 27 x 11 69 英寸 from docx import Document from docx s
  • 从工作线程 C# CF 在主线程中抛出事件

    我有 可能是 一个简单的问题 我正在使用互操作来调用 CompactFramework 中的异步函数 获得执行结果后 我想引发一个事件 该事件将被表单捕获 并根据结果 我将在屏幕上呈现一些数据 然而 问题是 当互操作函数返回结果时 它会在工
  • 找出数组中重复的元素

    有一个大小为 n 的数组 数组中包含的元素在 1 到 n 1 之间 每个元素出现一次 只有一个元素出现多次 我们需要找到这个元素 尽管这是一个非常常见的常见问题解答 但我仍然没有找到正确的答案 大多数建议是我应该将数组中的所有元素相加 然后