• leetcode 剑指 Offer 53


    剑指 Offer 53 - II. 0~n-1中缺失的数字

    题目描述

    一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

    示例 1:

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

    示例 2:

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

    限制:

    1 <= 数组长度 <= 10000

    思路一:直接遍历

    因为是每个元素唯一,且都是0-n-1内的,还是有序数组,所以如果没有缺失的话,每个元素应该刚好在等于它的下标,但是现在缺失了一个,说明从这个元素的下标开始,下标都不等于该下标对应的值了。

    那如果采用遍历的方式,碰到的第一个下标与值不一致的下标即是缺失的数字

    1 class Solution {
    2     public int missingNumber(int[] nums) {
    3         // 遍历数组,如果值和下标不相等,直接返回下标
    4         int i;
    5         for(i = 0; i < nums.length && nums[i] == i; i++);
    6         return i;
    7     }
    8 }

    leetcode运行时间为0ms - 100%, 空间为39.5MB - 45.05%

    复杂度分析:

    时间复杂度:最多就把整个数组遍历一遍,所以时间复杂度为O(n)

    空间复杂度:O(1)

    思路二:二分法

    如果arr[mid] == mid, 说明mid在缺失的元素之前,left = mid + 1, 否则说明mid在缺失的元素之后或者就是缺失的元素,right = mid - 1, 跳出时,变量 left 和 right分别指向 “右子数组的首位元素” 和 “左子数组的末位元素” 。因此返回 left 即可。

     1 class Solution {
     2     public int missingNumber(int[] nums) {
     3         // 二分法
     4         int left = 0, right = nums.length - 1;
     5         int mid = 0;
     6         while(left <= right){
     7             mid = (right + left) / 2;
     8             if(mid == nums[mid]){
     9                 left = mid + 1;
    10             }else{
    11                 right = mid - 1;
    12             }
    13         }
    14         // 跳出时left指向右子数组的首位元素,rihgt指向右子数组的第一个元素
    15         // 所以返回left
    16         return left;   
    17     }
    18 }

    leetcode运行时间为0ms - 100%, 空间为39.5MB - 45.05%

    复杂度分析:

    时间复杂度:二分法属于折半查找,所以时间复杂度为O(logn)

    空间复杂度:O(1)

     

  • 相关阅读:
    许可和授权的研究及其破解
    Citect:How do I translate Citect error messages?
    异步IO模型和Overlapped结构
    SanDisk SecureAccess™ Software
    Asynchronous socket communication
    一种字节转字符串的语法
    【转载】C# Tutorial
    保存项目文件“XXX.csprj”时出错。类没有注册。
    markdown中的注释
    ubuntu上nginx详细安装部署教程
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13765452.html
Copyright © 2020-2023  润新知