leetcode 540. 有序数组中的单一元

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

示例 1:

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

输入: [3,3,7,7,10,11,11]
输出: 10
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

因为需要使用O(log n)时间复杂度和 O(1)空间复杂度,所以不能使用额外的空间来记录每个数字出现的频率,也不能使用异或来操作。不过条件给了排序。所以可以使用二分法。

1:若当前数字所在的索引是偶数,若它前面的数字都是出现两次的数字,则它和它后面的数字应该相同,否则他前面必定有一个数字出现了一次。
1:若当前数字所在的索引是奇数,若它前面的数字都是出现两次的数字,则它和它前面的数字应该相同,否则他前面必定有一个数字出现了一次。

为了防止边界判断,可以从1 到 (length - 2)范围内搜索。

    public int singleNonDuplicate(int[] nums) {
        int length = nums.length;
        if (length == 1 || nums[0] != nums[1]) {
            return nums[0];
        }
        if (nums[length - 1] != nums[length - 2]) {
            return nums[length - 1];
        }
        int st = 1;
        int end = length - 2;

        while (st < end) {
            int m = st + ((end - st) >> 1);
            if ((m & 1) == 0) {
                if (nums[m] == nums[m + 1]) {
                    st = m + 2;
                } else {
                    end = m;
                }
            }else {
                if (nums[m] == nums[m - 1]) {
                    st = m + 1;
                } else {
                    end = m;
                }
            }
        }
        return nums[st];
    }

posted @ 2021-05-23 13:02  旺仔古李  阅读(65)  评论(0编辑  收藏  举报