【LeetCode-数组】有序数组中的单一元素

时间:2020-08-26 22:35:43   收藏:0   阅读:114

题目描述

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

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

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

注意:
您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
题目链接: https://leetcode-cn.com/problems/single-element-in-a-sorted-array/

思路1

将数组中的值进行异或,最终的结果就是只出现一次的数字。

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int ans = nums[0];
        for(int i=1; i<nums.size(); i++){
            ans ^= nums[i];
        }
        return ans;
    }
};

这种思路没有用到数组有序这个条件,而且时间复杂度为 O(n),不是题目要求的 O(log n)。

思路2

题目要求时间复杂度为 O(log n),这就在暗示我们使用二分查找来做。二分查找的关键点就是如何更新 left 和 right。假设当前查找的范围为 [left, right],mid = (left+right)/2。如果 mid 为偶数,则说明 mid 前面有偶数个数,例如 mid = 2,则 mid 前面有 2 个数(下标为 0, 1);如果 mid 为奇数,则说明 mid 前面有奇数个数。

如果 mid 为偶数,则 mid 前面有偶数个数,我们判断 nums[mid] 和 nums[mid+1] 是否相等。

如果 mid 为奇数,则 mid 前面有奇数个数,我们同样判断 nums[mid] 和 nums[mid+1] 是否相等。

总结一下:

代码如下:

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(left<=right){
            int mid = left+(right-left)/2;
            if(mid%2==0 && mid+1<nums.size()){ // mid 为偶数
                if(nums[mid]==nums[mid+1]) left = mid+1;   // nums[mid]==nums[mid+1]
                else right = mid-1;
            }else if(mid%2!=0 && mid+1<nums.size()){  // mid 为奇数
                if(nums[mid]==nums[mid+1]) right = mid-1;  // nums[mid]==nums[mid+1]
                else left = mid+1;
            }else return nums[mid];  // 注意这一步说明 mid 为最后一个元素
        }
        return nums[left];  // 最后返回 nums[left]
    }
};

参考

https://leetcode-cn.com/problems/single-element-in-a-sorted-array/solution/python3-qing-xi-si-lu-yong-shi-ji-bai-97nei-cun-ji/

原文:https://www.cnblogs.com/flix/p/13568355.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!