力扣每日一题 有序数组中的单一元素

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 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

思路

题目要求时间复杂度在log n,也就是说不能遍历全部的数字

除了我们要求出的数字以外,其他都是成对出现的,并且该数组是有序的,与之相等的数组不是在它左边就是在它右边

同时如果我们把数组分割成两段来看,答案数字肯定只会出现在一边,并且出现单个数字的那边的数字个数肯定是奇数,所以我们就可以考虑二分了

下面是题目样例中的示意图,单个数字所在的那一边一定是奇数个数字

每次取中点的数看是和它右边的相等还是和它左边的相等

如果都不想等那么这就是要找的数

如果相等,判断对应的那边剩下的数字是否是成对的 成对则单个数字肯定在另一边,如果不是成对的那么肯定就在判断的这一边,同时缩小边界

Code

java 复制代码
class Solution {
    public int singleNonDuplicate(int[] nums) {
        int n=nums.length;
        int i=0,j=n-1;

        while(i<=j){

            int mid=(i+j)/2;
            //右
            if(mid+1<n&&nums[mid+1]==nums[mid]){

                int len=n-mid-2;//右边还剩几个元素

                if(len%2==0){
                    j=mid-1;

                }else{
                    i=mid+1;
                }

            }
            else  //左
                if(mid-1>=0&&nums[mid-1]==nums[mid]){

                    int len=mid-1;//左边还剩几个元素
                    if(len%2==0){


                        i=mid+1;
                    }else{

                        j=mid-1;
                    }
                }else 
                    return nums[mid];
        }

        return 1;
    }
}
相关推荐
JieE21214 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2122 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2123 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2123 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术3 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦3 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050733 天前
(一)小红的数组操作
算法·编程语言