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

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

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

你设计的解决方案必须满足 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;
    }
}
相关推荐
GreenTea19 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
fqq320 小时前
力扣刷题前置Java语法
算法·leetcode·职场和发展
半夏微凉半夏殇1 天前
x11与weston对比,优先选哪个
leetcode·均值算法·eclipse
2501_906565121 天前
数学之美探究
算法
oier_Asad.Chen1 天前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
leisoo80971 天前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
luj_17681 天前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
wuyk5551 天前
3.链表:用指针串联的动态数据结构
c语言·开发语言·数据结构·链表
郝学胜-神的一滴1 天前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆1 天前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill