268. 缺失数字

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 268. 缺失数字

268. 缺失数字

本题来自 LeetCode:268. 缺失数字[1]

题目描述

给定一个包含 0, 1, 2, …, n  中  n  个数的序列,找出 0 .. n  中没有出现在序列中的那个数。
示例 1:


输入: [3,0,1]
输出: 2

示例  2:


输入: [9,6,4,2,3,5,7,0,1]
输出: 8

说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?

解法一

题目分析

本题的题意是从 0...n n + 1个数字中,选取 n个数,要找到其中缺失的那个数。

  • 由于是从长度为`n`的数组`nums`中查找,那么可以将数字`i`放到数组的位置`nums[i]`上,然后遍历遍历整个数组,判断`nums[i] == i`是否成立。
  • 但是由于数字`n`等于数组的长度,没有位置可放。而从题意中只缺少一个数字,故可以将数字`n`存放在缺少的数字的位置(前提是缺失的不是`n`)。
  • 题目解答

    
    class Solution {
        public int missingNumber(int[] nums) {
            int n = nums.length;
            // 记录
            int indexN = -1;
            for(int i = 0; i  n; i ++) {
                // 将除n以外的数放到正确的位置上
                while(nums[i] != n && nums[i] != i) {
                    swap(nums, nums[i], i);
                }
                // 记录n的位置
                if(nums[i] == n) {
                    indexN = i;
                }
            }
            // 若没有找到n则缺少n,若找到了n,则n元素所处的位置就是缺失的数
            return indexN == -1 ? n : indexN;
        }
        public void swap(int[] nums ,int i, int j) {
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
    

    复杂度分析:
    时间复杂度: O(n)
    空间复杂度: O(1)

    解法二

    题目分析

    本题也可以采用位运算异或来解答。由于 i ^ i = 0,故可以将 0...n n个数进行异或运算,然后再和数组 nums中的所有数组进行异或运算,最后剩下的数就是缺失的数。

    题目解答

    
    class Solution {
        public int missingNumber(int[] nums) {
            int n = nums.length;
            int missing = n;
            for(int i = 0; i  n; i ++) {
                missing = missing ^ i ^ nums[i];
            }
            return missing;
        }
    }
    

    复杂度分析:
    时间复杂度: O(n)
    空间复杂度: O(1)

    136. 只出现一次的数字

    本题来自 LeetCode:136. 只出现一次的数字[2]

    题目描述

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
    说明:
    你的算法应该具有线性时间复杂度。你可以不使用额外空间来实现吗?
    示例 1:

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

    示例  2:

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

    题目分析

    本题可以采用位运算异或来解答。由于 i ^ i = 0,除了某个元素只出现一次以外,其余每个元素均出现两次,故将数组 nums中的所有数组进行异或运算,最后剩下的数就是只出现一次的数。

    题目解答

    
    class Solution {
        public int singleNumber(int[] nums) {
            int single = 0;
            for(int i = 0; i  nums.length; i ++) {
                single = single ^ nums[i];
            }
            return single;
        }
    }
    

    复杂度分析:
    时间复杂度: O(n)
    空间复杂度: O(1)

    参考资料

    1. 缺失数字: https://leetcode-cn.com/problems/missing-number

    2. 只出现一次的数字: https://leetcode-cn.com/problems/single-number

    原文始发于微信公众号(xiaogan的技术博客):

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 268. 缺失数字


      转载请注明: 好好学java 268. 缺失数字

     上一篇
    257. 二叉树的所有路径 257. 二叉树的所有路径
    257. 二叉树的所有路径本题来自 LeetCode:257. 二叉树的所有路径[1] 题目描述给定一个二叉树,返回所有从根节点到叶子节点的路径。说明:  叶子节点是指没有子节点的节点。示例: 输入: 1 / 2
    2021-04-05
    下一篇 
    54&59. 螺旋矩阵I&II 54&59. 螺旋矩阵I&II
    54. 螺旋矩阵本题来自 LeetCode:54. 螺旋矩阵[1] 题目描述给定一个包含  m x n  个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。示例  1: 输入: [ [ 1, 2, 3 ],
    2021-04-05