题目:

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:

Input:
[4,3,2,7,8,2,3,1] Output:
[5,6]

代码:

在网上搜了搜,找到了几种解法,写好程序后整理整理。

解法一(取余法):

数组的元素范围为1~n,第一次循环首先把每个元素对应的位置加上(n+1);第二次循环把每个位置除以(n+1),如果该位置为0,表示某个元素没有出现;如果该位置等于2,表示出现两次。 
原理是什么呢?在第一次循环中,我们其实是将每个位置变成k*(n+1)+i,其中k表示该位置加(n+1)的次数,取值为0、1、2,i表示该位置本来的元素。在第二次循环中,因为i的范围是1~n,所以除以(n+1)就等于0,从而我们就获得了k的值。根据k的值,我们就很容易知道哪些元素没有出现,哪些元素出现了多次。

 class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int length = nums.size()+;
for (int i = ; i < length-; i++)
nums[nums[i]%length-] += length;
for (int i = ; i < length-; i++){
if ((nums[i]/length) == )
result.push_back(i+);
}
return result;
}
};

解法二(元素归位法):

元素归位法很容易理解,就是将n个元素交换到它应该在的位置。例如,元素5就放到位置4(下标从0开始)。这里需要注意一点,将某个元素交换到正确位置可能会导致当前位置的元素还不在正确位置,需要继续交换直到不能交换为止,伪代码如下:

 for i=:n
while canSwap(i) do swap(i);

将元素归位之后,我们就很容易获得哪些元素没有出现。当某个位置不是正确元素的时候,就意味着这个元素没有出现。也即针对没有出现的元素,我们只需要返回下标;针对出现两次的元素,我们只需要返回该位置的值。 
这里有一个疑问,伪代码有两个for循环,复杂度是不是O(n2)呢?不是,复杂度还是O(n),这个可以通过均摊分析来解释:如果满足交换条件,则每次都会使一个元素处在正确位置,因为总共有n个元素,所以至多需要n-1次交换(交换完n-1个元素,第n个元素自动满足)即可使所有的元素处在正确位置,也即while循环至多执行O(n)次,每次的平摊代价是O(1)。所以上述交换操作的复杂度为O(n)。

 class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int length = nums.size()+;
for (int i = ; i < length-; i++){
while((nums[i] != i+ )&& (nums[nums[i]-] != nums[i]))
swap(nums[i],nums[nums[i]-]);
} for (int i = ; i < length-; i++){
if (nums[i] != i+)
result.push_back(i+);
}
return result;
}
};

运行最快。

解法三(取负法):

含义是:将元素对应的位置取负。简单一句话可能不好理解,我们举个例子。假设在位置k放了元素i,则在取负的过程中i的取值有两种可能:为正,表示当前尚未遇到元素k将该位置取负;为负,表示当前已经有元素k出现,并将元素取负。但是我们不关心k,我们关心元素i。元素i既然出现,我们就看一下位置i:为正,表示这是元素i第一次出现,我们将位置i取负;为负,表示元素i已经出现过一次,我们不做任何操作。不管一个元素出现一次还是两次,只要出现它对应的位置就会被取负。当某个元素不出现的时候,该元素对应的位置始终访问不到,所以还是正值,通过这种方法我们就可以找到哪些元素没有出现。 
通过上面的分析我们也很容易知道,在取负的过程中,如果发现要取负的位置已经为负,说明这个元素已经出现过,也即该元素出现了两次,我们可以将该元素保留下来。

 class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int length = nums.size();
for (int i = ; i < length; i++){
int index = abs(nums[i])-;
if(nums[index]>)
nums[index] = -nums[index];
} for (int i = ; i < length; i++){
if (nums[i] > )
result.push_back(i+);
}
return result;
}
};

这三种方法都是通过某种方式将index与元素对应起来操作。

LeetCode: 448 Find All Numbers Disappeared in an Array(easy)的更多相关文章

  1. leetcode 448. Find All Numbers Disappeared in an Array -easy (重要)

    题目链接: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/ 题目描述: Give ...

  2. LeetCode 448. Find All Numbers Disappeared in an Array (在数组中找到没有出现的数字)

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  3. LeetCode "448. Find All Numbers Disappeared in an Array"

    My first reaction is to have an unlimited length of bit-array, to mark existence. But if no extra me ...

  4. 5. Leetcode 448. Find All Numbers Disappeared in an Array

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  5. LeetCode 448 Find All Numbers Disappeared in an Array 解题报告

    题目要求 Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice a ...

  6. LeetCode 448. Find All Numbers Disappeared in an Array找到所有数组中消失的元素

    题目 给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现在数组中的数字. 您能 ...

  7. [LeetCode] 448. Find All Numbers Disappeared in an Array 找到数组中消失的数字

    题目描述 给定n个数字的数组,里面的值都是1-n,但是有的出现了两遍,因此有的没有出现,求没有出现值这个数组中的值有哪些. 要求不能用额外的空间(除了返回列表之外),时间复杂度n 思路 因为不能用额外 ...

  8. 【leetcode】448. Find All Numbers Disappeared in an Array

    problem 448. Find All Numbers Disappeared in an Array solution: class Solution { public: vector<i ...

  9. leetcode 217. Contains Duplicate 287. Find the Duplicate Number 442. Find All Duplicates in an Array 448. Find All Numbers Disappeared in an Array

    后面3个题都是限制在1-n的,所有可以不先排序,可以利用巧方法做.最后两个题几乎一模一样. 217. Contains Duplicate class Solution { public: bool ...

随机推荐

  1. project 2013 激活 key 7YHNW-RVCQY-VBDB2-QX69Q-B96WK viso 66DNF-28W69-W4PPV-W3VYT-TJDBQ

    project 2013 激活 key :7YHNW-RVCQY-VBDB2-QX69Q-B96WK viso2013  激活 key:66DNF-28W69-W4PPV-W3VYT-TJDBQ 软件 ...

  2. g++ 6.4编译opencv-2.4.10报错记录

      fetch公司的项目进行编译,此项目依赖opencv库.由于本人一直比较偏爱fedora,但也因此给我带来了许多"乐趣"(麻烦).fedora一直走得比较前沿,g++ 6.3了 ...

  3. webpack打包问题

    最近项目里需要替换一个logo,原先的logo打包后生成的静态文件里有对应的图片,替换了新的的图片打包后并没有生成相应的静态文件,两个图片都在同一个文件目录下,而且图片是直接引入并不会出现打包不到图片 ...

  4. JSP学习笔记(一)

    JSP是基于JAVA语言的,区分大小写,HTML不区分大小写 如何建立Web服务目录? 1.在Webapps下面建立Web服务目录MYJSP 在Webapps下面新建文件夹MYJSP,将写好的jsp文 ...

  5. JAVA调用命令行2

    package loadMBQL; import java.io.File; import java.io.FilenameFilter; public class LoadMBQL { /** * ...

  6. PythonCookBook笔记——数据结构和算法

    数据结构和算法 解包赋值 p = [1, 2, 3] a, b, c = p # _表示被丢弃的值 _, d, _ = p # 可变长解包 *a, b = p # 字串切割解包 line = 'nob ...

  7. Hadoop集群_Hadoop安装配置

    1.集群部署介绍 1.1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distributed Filesy ...

  8. Struts MVC工作原理(转载)

    1.Struts MVC中Model 1 和Model 2简介 我们在开发Web应用时经常提到的一个概念是Model 1/Model 2,那么到底它是什么意思呢?其实它是对采用JSP技术构成Web应用 ...

  9. Running several name-based web sites on a single IP address.

    VirtualHost Examples - Apache HTTP Server Version 2.2 http://httpd.apache.org/docs/2.2/vhosts/exampl ...

  10. SPDY: An experimental protocol for a faster web HTTP/2

    http://www.chromium.org/spdy/spdy-whitepaper https://en.wikipedia.org/wiki/SPDY Internet protocol su ...