268. Missing Number

Swift 3.0


//
//  E_268_MissingNumber.swift
//  AlgorithmLeetCode
//
//  Created by okerivy on 2017/3/9.
//  Copyright © 2017年 okerivy. All rights reserved.
//  https://leetcode.com/problems/missing-number

import Foundation




// MARK: - 题目名称: 268. Missing Number

/* MARK: - 所属类别:
 标签: Array, Math, Bit Manipulation
 
 相关题目:
  (H) First Missing Positive
  (E) Single Number
  (M) Find the Duplicate Number
 
 */

/* MARK: - 题目英文:
 
 Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.
 
 For example,
 Given nums = [0, 1, 3] return 2.
 
 Note:
 Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
 
 Credits:
 Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
 
 */


/* MARK: - 题目翻译:
 
 给定一个数组,数组包含 n 个取自 0, 1, 2, ..., n 的不同的数字,从数组中找到丢失的那个数字。
 
 例如:给定 nums = [0, 1, 3] 返回 2.
 
 注意:
 你的算法应当使用线性的时间复杂度(即时间复杂度为O(n))。你能够只使用常量的额外空间来解决这题吗?
 
 */



/* MARK: - 解题思路:
 
 1.
 从 0, 1, 2, ..., n 中取 n 个不同的数字组成数组 nums,寻找丢失的那个数字,非常自然的想法就是将 0, 1, 2, ..., n 加和之后,减去数组 nums 的和就得到了丢失的那个数字。
 
 思路非常简单。但是为了避免加和造成的溢出,
 这里有一个小技巧:即不需要将两个数组先加起来之后再做减法,可以边加边减。
 例如 数组
 数字     0   1   3   4   5   6   7   8   // 缺失的是 2
 下标     0   1   2   3   4   5   6   7   // 8个元素
 
 进行相加相减运算 上下全部进行 (i - nums[i])
 0-0+1-1+3-2+4-3+5-4+6-5+7-6+8-7 = 0-0 1-1 3-3 4-4 5-5 6-6 7-7 2-8 = 2-8
 
 (i - nums[i]) = 2-8
 
 可以看到 2 已经出来了 因为 nums.count = 8 所以再次相加一次 ans + (i - nums[i])
 nums.count + 2-8 = 8 + 2-8 = 2
 
 
 2.
 其基本思想是利用异或XOR运算。我们都知道一个a^b^b =a,这意味着相同数量的两异或操作将消除数量和揭示原数。
 在这个解决方案中,我运用异或XOR操作的指标和数组的值。
 在一个没有缺数字完整的阵列,指标值应完全对应(nums[index] = index),所以在丢失数组,剩下的最后是失踪数字。
 
 例如 数组
 数字     0   1   3   4   5   6   7   8   // 缺失的是 2
 下标     0   1   2   3   4   5   6   7   // 0..7 有8个元素
 
 进行异或运算 上下全部进行 (i ^ nums[i])
 0^0^1^1^3^2^4^3^5^4^6^5^7^6^8^7 = 0^0^1^1^3^3^4^4^5^5^6^6^7^7^8^2 = 8^2
 
 (i ^ nums[i]) = 8^2
 
 可以看到 2 已经出来了 因为 xor = nums.count = 8 所以再次异或一次 xor ^ (i ^ nums[i])
 8^2^nums.count = 8^2^8 = 2
 
 
 ---------------------------------
 异或是一种基于二进制的位运算,用符号XOR或者 ^ 表示,
 
 其运算法则是对运算符两侧数的每一个二进制位,同值取0,异值取1。
 
 异或的性质
 交换律:a ^ b = b ^ a
 结合律:a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
        d = a ^ b ^ c 可以推出 a = d ^ b ^ c
 自反性:a ^ b ^ a = b
 
 
 
 算法题目
 
 ①1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
 
 前面提到异或具有交换律和结合律,所以1^2^...^n^...^n^...^1000,无论这两个n出现在什么位置,都可以转换成为1^2^...^1000^(n^n)的形式。
 
 其次,对于任何数x,都有x^x=0,x^0=x。
 
 所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有数的异或)。
 
 令,1^2^...^n^..^1000(序列中包含一个n)的结果为T
 则1^2^..^n^..^n^..^1000(序列中包含2个n)的结果就是T^n。
 T^(T^n)=n。
 
 所以,将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。
 
 */


/* MARK: - 复杂度分析:
 间复杂度是O(n),空间复杂度为O(1)
 
 */


// MARK: - 代码:
private class Solution {
    
    // 加法求和
    func missingNumber(_ nums: [Int]) -> Int {
        var ans = 0
        for i in 0..<nums.count {
            ans = ans + i - nums[i]
        }
        ans += nums.count
        return ans
    }
    
    // 异或运算
    func missingNumber2(_ nums: [Int]) -> Int {
        var xor = nums.count
        for i in 0..<nums.count {
            xor = xor ^ i ^ nums[i];
        }
        return xor;
    }

}



// MARK: - 测试代码:
func missingNumber() {
  
    print(Solution().missingNumber([0, 1, 3, 4, 5, 6, 7]))
    print(Solution().missingNumber([1, 2, 3, 4, 5]))
    print(Solution().missingNumber([0, 1, 2, 4, 5]))
    print(Solution().missingNumber([5, 1, 2, 0, 4]))

}



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容