算法学习100天——3 二分查找2

题目地址(540. 有序数组中的单一元素)

https://leetcode-cn.com/problems/single-element-in-a-sorted-array/

题目描述

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
请你找出并返回只出现一次的那个数。
你设计的解决方案必须满足 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

代码

  • 语言支持:Java
class Solution {
    public int singleNonDuplicate(int[] nums) {
        // 二分查找  时间复杂度是logN;
        // 但是我不知道target, 这是我不理解的地方
        // 考虑直接比较mid左右两边,如果没有与mid相等的,那就是mid,但是最坏的情况就是O(N)了

        // 看了评论提示,关键点:数组元素是2*M + 1, 长度永远为奇数,可以二分中点来判断,
        // 两种思考角度如下

        // 4种情况(先考虑目标点位置):
        // 1. 目标点在左边,中点与左邻点相等,则执行right = mid;
        // 2. 目标点在左边,中点与右邻点相等,则执行right = mid - 1;(或者+1)
        // 3. 目标点在中间或者右边,中点与左邻点相等,则执行left = mid + 1;(或者-1)
        // 4. 目标点在中间或者右边,中点与右邻点相等,则执行left = mid;

        // 5种情况(先判断中点值与左右邻点值的关系):
        // 1. 中点与左邻点相等,目标点在左边,则执行right = mid;
        // 2. 中点与左邻点相等,目标点在右边,则执行left = mid + 1;(或者-1)
        // 3. 中点与右邻点相等,目标点在左边,则执行right = mid - 1;(或者+1)
        // 4. 中点与右邻点相等,目标点在右边,则执行left = mid;
        // 5. 中点与左右邻点都不相等,目标点就是中点,直接return nums[mid];



        // 数组长度为1的情况
        if(nums.length == 1){
            return nums[0];
        }

        int left = 0;
        int right = nums.length - 1;
        while(left < right){
            // 找到中点
            int mid = left + ((right - left) >> 1);
            // 判断中点与两边的大小
            if(nums[mid] == nums[mid - 1]){
                if(mid % 2 == 0) {
                    right = mid;
                }else {
                    left = mid + 1;
                }
            }else if(nums[mid] == nums[mid + 1]){
                if(mid % 2 == 0) {
                    left = mid;
                }else {
                    right = mid - 1;
                }
            }else{
                // 两边都不相等,直接返回它
                return nums[mid];
            }
        }
        return nums[left];
    }
}

结果

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:47 MB, 在所有 Java 提交中击败了54.85%

posted @ 2022-02-27 23:31  浪漫主义程序员  阅读(24)  评论(0编辑  收藏  举报