首页 > 其他分享 >力扣 第540题 有序数组中的单一元素

力扣 第540题 有序数组中的单一元素

时间:2024-11-11 11:47:43浏览次数:3  
标签:判断 nums 重复 左边 元素 mid 力扣 540 数组

解题思路:

        因为解决方案必须满足 `O(log n)` 的时间复杂度,和 `O(1)` 的空间复杂度。所以我们首先考虑用二分查找的思想。这个问题的关键是找到我们要找的元素在左边还是右边的判断条件。

        要找的元素在左边还是右边的判断条件是什么呢?题目告诉我们每个元素都会出现两次,唯有一个数只会出现一次。以数组nums = [1,1,2,3,3,4,4,8,8]为例,第一次二分查找时,记录中间元素下标的变量为mid为4,此时num[4]是第二个3,我们将mid减1,得到第一个3,再进行判断:此时mid前面的元素为1,1,2有奇数个,说明在mid左边有一个元素不是重复出现两次,则要找到元素在mid的左边。

把上面的思维转化成代码:

第一步:二分查找 先折半 计算出记录中间元素下标的变量mid

第二步:令mid为此时两个重复元素中的第一个。判断num[mid]是否是重复元素中的第一个,即判断nums[mid] 是否等于nums[mid - 1],如果等于,说明第一个重复元素不是nums[mid],而是nums[mid - 1],所以令mid - = 1。

第三步:判断nums[mid]之前的元素个数是偶数还是奇数。数组中元素下标为当前元素的个数加1,所以mid的前一个元素下标为mid-1,则mid之前有mid-1+1个也就是mid个元素,如果 mid %2 等于 1 说明mid之前有奇数个元素,否则,反之。

第四步:如果mid之前有奇数个元素,说明要找的元素在mid左边,我们令 right = mid - 1。如果mid之前有偶数个元素,说明要找的元素在mid右边,我们令 left = mid + 2。加2是因为mid在重复元素第一个,所以加2而不是加1,是为了避免让mid记录为此时两个重复元素中的第二个,影响后续判断。

注意:有几种特殊情况应提前判断。

  • nums的长度为1.直接返回nums[0]。判断条件为:nums.length = 1
  • 重复元素在第一个。判断条件为:mid == 0 && nums[mid] != nums[mid + 1]
  • 重复元素在最后一个。判断条件为:mid == nums.length-1 && nums[mid] != nums[mid - 1]
    public static int singleNonDuplicate(int[] nums) {
            // 先判断特殊情况
            // 特殊情况1:nums的长度为1.直接返回
            if(nums.length <= 1) {
                return nums[0];
            }
            int left = 0, right = nums.length - 1;
            for( ;left <= right;) {
                int mid = (right + left) / 2;
                // 特殊情况2:重复元素在第一个
                if(mid == 0 && nums[mid] != nums[mid + 1]){
                    return nums[mid];
                }
                // 特殊情况3:重复元素在最后一个
                if(mid == nums.length-1 && nums[mid] != nums[mid - 1]){
                    return nums[mid];
                }
                if(nums[mid] != nums[mid + 1] && nums[mid] != nums[mid - 1]) {
                    return nums[mid];
                }else if(nums[mid] == nums[mid - 1]) {
                    mid = mid -1;
                }
                // 判断前面元素是否是偶数,是,则在右边
                if(mid %2 ==1){  // mid为奇数,则前面元素位奇数个,在左边
                    right = mid - 1;
                }else {
                    left = mid + 2;  // mid在重复元素第一个,所以加2
                }
            }
            return 0;
        }

标签:判断,nums,重复,左边,元素,mid,力扣,540,数组
From: https://blog.csdn.net/2301_77830460/article/details/143666156

相关文章

  • 数组算法练习题
    第一题:寻找锦鲤公司年会有一个寻找锦鲤的游戏,每一个员工随意写一个字,如果在“锦鲤”词库中有这个字,那么就奖励500元锦鲤红包,否则就没有,每人只能玩一次。现有锦鲤字库如下,它们按照Unicode编码值从小到大排序:char[]koiFishWords={'一','今','地','定','年','开','我','果','......
  • [数组排序] 0384. 打乱数组
    文章目录1.题目大意2.题目大意3.示例4.解题思路5.参考代码1.题目大意384.打乱数组-力扣(LeetCode)2.题目大意描述:给定一个整数数组nums。要求:设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是等可能的。实现Solutionclass:Sol......
  • 力扣 3059.找到所有不同的邮件域名
    3059.找到所有不同的邮件域名目标编写一个解决方案来找到所有不同的电子邮件域名并且计数与每个域名相关联的记录。只考虑以.com结尾的域名。返回结果表以email_domains升序排列。2.输入:Emails表:+-----+-----------------------+|id|email......
  • C小题目:有一个一维数组score,放10个学生的成绩,求平均成绩。
    #include<stdio.h>intaverage(intx[],intlen){inti,sum=0;for(i=0;i<len;i++){sum+=x[i];printf("%d\n",x[i]);};inta=sum/len;printf("theaverageis%d\n",a);};intmain(){......
  • 912. 排序数组
    题目链接本题使用的是快排解决。思路:「荷兰国旗」问题,具体思路跳转75.颜色分类代码classSolution{public:voidswap(vector<int>&nums,inti,intj){inttmp=nums[i];nums[i]=nums[j];nums[j]=tmp;}//[L,......
  • 关于我,穿越异世界,凭c语言搅动风云vlog----利用数组进行大数相关计算
    关于我,穿越异世界,凭c语言搅动风云vlog----利用数组进行大数相关计算一.有关大数你应该要知道的那些事1.大数的概念我们一般将计算机基本数据类型无法存储的数称之为大数,本文涉及的大数均为整数,不包含小数。而且下文代码实现中的数组大小可根据需要修改。2.问题引入在c......
  • 53. 最大子数组和
    题目链接解题思路最大子数组问题,有两个基本的想法,以i开头的子数组结果是怎样的,求出所有的结果,最优的那个,就是答案;以i结尾的子数组结果是怎样的,求出所有的结果,最优的那个,就是答案。本题我们可以考虑,「以i结尾的结果是怎样的」,为啥?因为我们要求的是最大的累加和,我们求出了re......
  • 工作学习笔记(五)数组
    在Java中,数组有以下重要作用:存储数据可以将同类型的多个数据组合在一起。例如,存储一个班级学生的考试成绩。如果有50个学生,就可以创建一个 int 类型的数组 int[]scores=newint[50]; 来存放所有成绩。除了基本数据类型,也能存储对象。比如, String[]names=newStri......
  • 实验4 C语言数组应用编程
    实验任务1:task1.c源代码:1#include<stdio.h>2#defineN43#defineM245voidtest1(){6intx[N]={1,9,8,4};7inti;89printf("sizeof(x)=%d\n",sizeof(x));1011for(i=0;i<N;++i)......
  • 一道题把我气笑了:) 力扣.53 最大子数组和 leetcode maximum-subarray
    数组系列力扣数据结构之数组-00-概览力扣.53最大子数组和maximum-subarray力扣.128最长连续系列longest-consecutive-sequence力扣.1两数之和N种解法two-sum力扣.167两数之和IItwo-sum-ii力扣.170两数之和IIItwo-sum-iii力扣.653两数之和IVtwo-sum-IV力......