Leetcode 540 题 有序数组中的单一元素

46 篇文章 0 订阅
18 篇文章 0 订阅
题目描述

给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。

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

注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。


思路分析

「思路一」
由于每个元素都会出现两次,寻找只出现一次的元素,我们可以想到的是使用异或,我们可以利用异或的特性,相同为0,那么出现两次的结果都会被异或为0,剩下的那一位就是我们需要的结果。

「思路二」
到目前为止,题目所给的有序数组这一条件我们似乎并没有使用到,题目要求我们的时间复杂度应该是 O(log n),因此我们可以确定这道题需要使用二分查找。

我们使用二分查找,首先需要判断每一次二分后,中间元素在我们需要查找的元素的左边还是右边。我们可以发现这样的一些规律:
在这里插入图片描述
1、在只出现一次的数之前,其偶数位的元素与后一位元素相同,奇数位的元素与前一位元素相同。
2、在只出现一次的数之后,其奇数位的元素与后一位元素相同,偶数位的元素与前一位元素相同。
3、如果某个元素和其前一位元素以及后一位元素都不相同,那么这个元素就是我们所要查找的 “单个元素”。

因此,我们每次取得中间元素,可以使用中间元素所处的奇偶位,以及该元素与之前、之后元素的关系,来判断这个中间元素在 “单个元素” 之前或者之后。


代码描述

下面使用 Java 对思路二进行代码描述:

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        while (left < right) {
            int mid = (left + right) / 2;
            if (mid == 0 || nums[mid] != nums[mid - 1] && nums[mid] != nums[mid + 1]) {
                return nums[mid];
            }
            if ((mid & 1) == 1 && nums[mid] == nums[mid - 1] || (mid & 1) == 0 && nums[mid] == nums[mid + 1]) {
                // 左指针向右移动
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return nums[left];
    }
}

欢迎关注

技术公众号:【小猿君的算法笔记】,一起学习,一起成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值