开启我的LeetCode刷题日记:540. 有序数组中的单一元素

84 阅读1分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

今天题目:540. 有序数组中的单一元素

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

示例 1:

输入: nums = [1,1,2,3,3,4,4,8,8] 输出: 2 示例 2:

输入: nums = [3,3,7,7,10,11,11] 输出: 10  

提示:

1 <= nums.length <= 105 0 <= nums[i] <= 105

我的思路

对于num,有如下关系

num偶数,则mid + 1 === mid ^ 1

num奇数,则mid - 1 === mid ^ 1

单独的那个数,其左边索引满足:

偶数:nums[x] === nums[x+1]

奇数:nums[x] === nums[x-1]

不满足以上,则说明该索引在其右边

以这个为分界线,二分查找单独的数,并应用第一条的关系,简化判断逻辑

代码实现

const singleNonDuplicate = nums => {
  let [left, right] = [0, nums.length];
  while (left <= right) {
    const mid = (left + right) >> 1;
    if (nums[mid] === nums[mid ^ 1]) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  return nums[left];
};

或者通过异或每个元素,即可返回出现依次的数字

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNonDuplicate = function(nums) {
    let res = nums[0];

    for(let i=1; i<nums.length; i++) {
        res ^= nums[i]
    }

    return res;
};


总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹