剑指 Offer II 070. 排序数组中只出现一次的数字(540. 有序数组中的单一元素)

题目:

 

思路:

【0】首先常规的做法必然是不符合进阶的,毕竟要满足O(log n),那么只能二分了,不过幸好的是,数组是有序的。

【1】全数组的二分查找的方式

【2】偶数下标的二分查找的方式

代码展示:

偶数下标的二分查找的方式:

//时间0 ms击败100%
//内存41.8 MB击败22.25%
//时间复杂度:O(log⁡n),其中 n 是数组 nums 的长度。
//需要在偶数下标范围内二分查找,二分查找的时间复杂度是 O(log⁡n)。
//空间复杂度:O(1)。
class Solution {
    public int singleNonDuplicate(int[] nums) {
        int low = 0, high = nums.length - 1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            mid -= mid & 1;
            if (nums[mid] == nums[mid + 1]) {
                low = mid + 2;
            } else {
                high = mid;
            }
        }
        return nums[low];
    }
}

 

全数组的二分查找的方式:

//时间0 ms击败100%
//内存41.6 MB击败51.97%
//时间复杂度:O(log⁡n),其中 nnn 是数组 nums 的长度。
//需要在全数组范围内二分查找,二分查找的时间复杂度是 O(log⁡n)。
//空间复杂度:O(1)。
class Solution {
    public int singleNonDuplicate(int[] nums) {
        int low = 0, high = nums.length - 1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            if (nums[mid] == nums[mid ^ 1]) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return nums[low];
    }
}

 

常规的做法一般都是O(N)的方式:

//时间1 ms击败22.66%
//内存47.3 MB击败26.81%
//这种是利用数组中必定是2(n-1)+1的个数,其中n为不同数值的个数。
//假设单独只有一个的数为x,那么必然存在x的左边的个数是2k个。所以存在下标偶数的0与下标奇数的1的数值是一样的。
//同理,由于X的占位是偶数,所以右边是下标奇数的x+1与存在下标偶数的x+2的数值是一样的。
class Solution {
    public int singleNonDuplicate(int[] nums) {
        int res = -1;
        for (int i = 0; i < nums.length; i += 2){
            if (i == nums.length-1 || nums[i] != nums[i + 1]){
                res = nums[i];
                break;
            }
        }
        return res;
    }
}

//时间1 ms击败22.66%
//内存47.1 MB击败71.6%
//这种是利用两相同数值异或为0的特性
class Solution {
    public int singleNonDuplicate(int[] nums) {
        int res = 0;
        for (int i = 0; i < nums.length; i++){
            res ^= nums[i];
        }
        return res;
    }
}

 

posted @ 2023-03-29 14:33  忧愁的chafry  阅读(14)  评论(0编辑  收藏  举报