zoukankan      html  css  js  c++  java
  • [LeetCode] 540. Single Element in a Sorted Array

    You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once.

    Example 1:

    Input: [1,1,2,3,3,4,4,8,8]
    Output: 2
    

    Example 2:

    Input: [3,3,7,7,10,11,11]
    Output: 10

    Note: Your solution should run in O(log n) time and O(1) space.

    有序数组中的单一元素。

    题意是给一个排好序的数组,所有的元素都成对出现,请你找出唯一的单独元素。有时间复杂度O(log n)的要求。既然是这个要求,所以一定是二分法做。注意到 input 有一个现象,就是落单的元素的 index 一定是偶数,所以我给出的二分法做了一点变化,end 只取了数组长度的一半,但是在找 mid 的时候我再乘以2,这样保证了 mid 一定是偶数。如果 nums[2 * mid] != nums[2 * mid + 1] ,那么说明单独的元素一定在前半段,否则就在后半段。这个题的官方题解写的很详细,我参考了方法三

    时间O(logn)

    空间O(1)

    Java实现

     1 class Solution {
     2     public int singleNonDuplicate(int[] nums) {
     3         int start = 0;
     4         int end = nums.length / 2;
     5         while (start < end) {
     6             int mid = start + (end - start) / 2;
     7             if (nums[2 * mid] != nums[2 * mid + 1]) {
     8                 end = mid;
     9             } else {
    10                 start = mid + 1;
    11             }
    12         }
    13         return nums[2 * start];
    14     }
    15 }

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @return {number}
     4  */
     5 var singleNonDuplicate = function(nums) {
     6     let start = 0;
     7     let end = nums.length / 2;
     8     while (start < end) {
     9         let mid = Math.floor((start + end) / 2);
    10         if (nums[mid * 2] != nums[mid * 2 + 1]) {
    11             end = mid;
    12         } else {
    13             start = mid + 1;
    14         }
    15     }
    16     return nums[start * 2]
    17 };

    二刷的时候我写了一个比较常规的二分法,因为第一种做法面试的时候除非遇到原题否则不太容易想得到。常规的二分法的右边界是 end = nums.length - 1,当 mid 是奇数的时候,我们会通过对其减一,强行让其变成偶数,这样如果 nums[mid] == nums[mid + 1] 的话,说明单一元素还在右边,要 start = mid + 2。这里 mid + 2 的原因在于 mid 和 mid + 1 背后指向的元素是相等的。因为会涉及到 mid + 2 的操作,所以第五行的 while 判断是 start < end 而不是 start <= end,这一点跟模板有区别。

    Java实现

     1 class Solution {
     2     public int singleNonDuplicate(int[] nums) {
     3         int start = 0;
     4         int end = nums.length - 1;
     5         while (start < end) {
     6             int mid = start + (end - start) / 2;
     7             // 强行把mid变为偶数,因为落单的数字只会在偶数index上
     8             if (mid % 2 == 1) {
     9                 mid--;
    10             }
    11             if (nums[mid] == nums[mid + 1]) {
    12                 start = mid + 2;
    13             } else {
    14                 end = mid - 1;
    15             }
    16         }
    17         return nums[start];
    18     }
    19 }

    LeetCode 题目总结

  • 相关阅读:
    《metasploit渗透测试魔鬼训练营》靶机演练之第五章实战案例KingView 6.53版本CVE-2011-0406漏洞
    《metasploit渗透测试魔鬼训练营》学习笔记第五章--网络服务渗透攻击
    《metasploit渗透测试魔鬼训练营》靶机演练之第五章实战案例Oracle数据库
    《metasploit渗透测试魔鬼训练营》学习笔记第四章—web应用渗透
    《metasploit渗透测试魔鬼训练营》学习笔记第三章----情报搜集
    Kali-linux Arpspoof工具
    Kali-linux攻击路由器
    Kali-linux在树莓派上破解无线网络
    Kali-linux使用Easy-Creds工具攻击无线网络
    20155225 2016-2017-2 《Java程序设计》第五周学习总结
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12879920.html
Copyright © 2011-2022 走看看