leetcode 540. Single Element in a Sorted Array(排序数组中的单个元素)

news2025/2/28 5:10:22

在这里插入图片描述

给一个已经排好序的升序数组,其中每个元素都会重复2次,只有一个元素只有一个,
找出这个只有一个的元素。
要求时间复杂度在O(logn), 空间复杂度在O(1).

思路:

时间复杂度为O(logn), 让人想到了binary search.

因为时间复杂度为O(1), 所以不能用一个数组来保存每个元素出现的次数。

不过,每个元素也就出现2次,而且是排好序的,也就是说相同的元素都是在一起的。
可以用一个cnt, 元素第一次出现时cnt = 1, 第2次出现时cnt = 0,
那么只出现一次的元素,cnt就无法清0,于是就被找出来了。
但是这种方法需要遍历数组,时间复杂度为O(n), 也能通过测试。

    public int singleNonDuplicate(int[] nums) {
        int cnt = 1;
        int n = nums.length;

        if(n == 1) return nums[0];
        for(int i = 1; i < n; i++) {
            if(nums[i] != nums[i-1]) {
                if(cnt == 1) return nums[i-1];
                else cnt = 1;
            } else {
                cnt = 0;
            }
        }
        return nums[n-1];
    }

下面看一下binary search.

为什么能用binary search呢?
因为每个元素出现2次(长度为偶数),只有一个元素出现了1次,
包含出现了1次的元素的部分,长度一定是奇数。

我们可以判断奇数的长度出现在左边还是右边,把left, right指针卡在奇数长度的部分。

举个例子:
2,2,3,3,4
[0] [1] [2] [3] [4]
left = 0, right = 4, mid = 2
右半边的长度(不含mid本身)为right - mid = 2, 长度为偶数,

但是发现没有,nums[mid]和nums[mid+1]两个数是一样的,
现在的长度right-mid 把两个相同的元素拆开了,违背了刚才判断的标准,
2个相同的元素都在一起才符合长度为偶数的标准,拆开了就不能按照长度为奇偶来判断了。

所以要比较nums[mid]和nums[mid+1]两个元素,如果相同,把nums[mid]也算进右边,
所以现在右边长度为奇数,可以判断单个的元素在右边,移动left = mid + 2(跳过重复元素)。
那如果是下面的例子:
1,2,2,3,3,
可以看到右边长度为偶数,这时要移动right = mid - 2(跳过重复元素)

直到nums[mid] 和 nums[mid + 1], nums[mid-1]都不相等, 返回nums[mid].

    public int singleNonDuplicate(int[] nums) {
        int n = nums.length;
        if(n == 1) return nums[0];

        int left = 0;
        int right = n - 1;

        while(left <= right) {
            int mid = left + (right - left)/2;
            boolean isEvenLen = ((right - mid) % 2 == 0);
            if(mid >= 1 && nums[mid] == nums[mid-1]) {
                if(isEvenLen) right = mid-2;
                else left = mid + 1;
           //重复元素算进右边长度
            } else if(mid < n - 1 && nums[mid] == nums[mid+1]) {
                if(isEvenLen) left = mid + 2; //算进重复元素后,右边长度为奇数,单个元素在右边
                else right = mid - 1;
            } else {
                return nums[mid];
            }
        }
        return -1;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

keil5安装了pack包但是还是不能选择device

一开始&#xff0c;我以为是keil5无法安装 STM32 芯片包&#xff0c;打开device倒是可以看到stm公司的芯片包&#xff0c;但是没有我想要的stm32f1。 我按照网上的一些说法&#xff0c;找到了这个STM32F1 的pack芯片包&#xff0c;但是我双击安装的时候&#xff0c;它的安装位…

(HP)新手引导使用react-shepherd

1&#xff0c;官方参数文档&#xff1a;https://shepherdjs.dev/docs/tutorial-02-usage.html 2&#xff0c;基本代码 import { ShepherdTour } from react-shepherd; import ./index.less; // 自己的样式文件&#xff0c;用来修改样式 import ./shepherd.less; // 将shephe…

嵌入式C语言自我修养:从芯片、编译器到操作系统-习题、笔记

前沿 C语言测试(1):基本概念考查 什么是标识符、关键字和预定义标识符? 三者有何区别? 标识符&#xff08;Identifier&#xff09;:由程序员定义&#xff0c;用来表示变量&#xff0c;包括了变量名、函数名、宏名、结构体名等。 标识符的命名规范&#xff1a;C语言规定&…

Android架构设计——【 APT技术实现butterknife框架 】

APT简介 APT英文全称&#xff1a;Android annotation process tool是一种处理注释的工具&#xff0c;它对源代码文件进行检测找出其中的Annotation&#xff0c;使用Annotation进行额外的处理。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文…

100种思维模型之启发式偏差思维模型-017

曾国藩在给儿子的一封家书中曾写道&#xff1a;余于凡事皆用困知勉行工夫&#xff0c;尔不可求名太骤&#xff0c;求效太捷也。熬过此关&#xff0c;便可少进。再进再困&#xff0c;再熬再奋&#xff0c;自有亨通精进之日。 不急躁不求捷径&#xff0c;小火慢炖&#xff0c;将事…

burp小程序抓包

身为一名码农&#xff0c;抓包肯定是一项必备技能。工作中遇到很多次需要对小程序进行抓包排查问题。下面分享一下我的抓包方式&#xff0c;使用的是电脑版小程序抓包&#xff0c;跟手机的方式都差不多的。 一、环境 微信版本&#xff1a;3.6.0.18 Burpsuite版本&#xff1a…

Python容器

容器 容器是一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素&#xff0c;每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 数据容器根据特点的不同&#xff0c;如&#xff1a; 是否支持重复元素是否可以修改是否…

k8s1.17.2+centos7.7+docker18.06

1.简介 1.1pod网络 总述&#xff1a;Kubernetes 的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中 Flannel&#xff1a;基于L2&#xff0c;构建用于各个pod通信的网络架构。使用iptables进行数据包过滤。Calico&#xff1a;纯L3&#xff0c;构建用于各个pod通…

【Java基础】反射

概述 引入 package ref;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.r…

VUCA项目环境中如何提升项目进度计划与控制工作有效性的系统思考【一杯咖啡谈项目】

VUCA环境下&#xff0c;项目进度延迟是经常遇见的问题&#xff0c;如何解决此类问题&#xff1f;今天分享一个案例&#xff0c;在这个案例中&#xff0c;基于“根因分析法”&#xff0c;对某主题客户端项目的进度延迟问题进行了分析&#xff0c;找到根本原因&#xff0c;提出了…

鼠标指针文件格式解析

鼠标指针文件格式解析 文章目录鼠标指针文件格式解析windowsico文件格式分析文件头&#xff1a;图像数据头段&#xff1a;图像数据段&#xff1a;Ani动态光标格式解析数据结构&#xff1a;anihseq **rate**LISTcur静态光标文件格式解析macOSLinuxwindows ico文件格式分析 是一…

2023年PMP考试复习攻略

如何备考PMP呢&#xff1f; 这本书是PMP认证考试的官方教材&#xff0c;体系完善&#xff0c;可以迅速帮助入门者搭建项目管理知识体系&#xff0c;备考PMP考试的伙伴&#xff0c;这本书一定要读一遍&#xff01; 经验都是积累出来的&#xff0c;交流小队里有很多分享面试经验…

Vue3 中生命周期的使用

目录前言&#xff1a;一、什么是生命周期函数二、什么是 Keep-Alive 组件三、生命周期函数分为几种&#xff0c;分别有什么用&#xff1f;1. beforeCreate2. created3. beforeMount/onBeforeMount4. mounted/onMounted5. beforeUpdate/onBeforeUpdate6. updated/onUpdated7. be…

spring之事务概述

文章目录前言一、事务概述1、什么是事务2、事务的四个处理过程3、事务的四个特性二、引入事务场景1、引入依赖2、数据库创建3、建包4、spring.xml配置文件5、测试程序6、运行结果&#xff08;成功&#xff09;7、模拟异常三、Spring对事务的支持1、Spring实现事务的两种方式2、…

数值方法笔记4:插值、近似和拟合

1. 插值1.1 插值的一些概念1.1.1 插值的定义1.1.2 插值的存在性1.1.3 插值的误差分析1.2 拉格朗日插值(Lagrange Interpolation)1.2.1 拉格朗日插值误差分析1.3 Newton多项式插值1.3.1 Newton多项式插值误差分析1.4 Chebyshev多项式确定插值点1.4.1 Chebyshev多项式性质1.5 有理…

Green Hills Software(GHS)的安装

Green Hills Software(GHS)简介 Green Hills Software(GHS)是美国Green Hills软件公司提供的一种具有调试、编译器和闪存编程工具的集成开发环境,是汽车电子行业常用且重要的开发环境之一。它支持的功能包括:AUTOSAR感知、项目构建器、代码覆盖、运行时错误检查、MISRA C…

【HEC-RAS水动力】HEC-RAS 1D基本原理(恒定流及非恒定流)

一、数据说明 HEC-RAS模型主要由工程文件 (.prj) 文 件 、 河道地形数据文件 ( .g01)、运行文件(p01)、非恒定流文件 ( .u01) 等部分组成。 1. 一般数据 在创建并保存project文件(*.prj)后,其他data文件均会自动以同样的名字保存,但采用不同的后缀来区分各类文件。 &qu…

网络编程之IP 地址的介绍

IP 地址的介绍学习目标能够说出IP 地址的作用1. IP 地址的概念IP 地址就是标识网络中设备的一个地址&#xff0c;好比现实生活中的家庭地址。网络中的设备效果图:2. IP 地址的表现形式说明:IP 地址分为两类&#xff1a; IPv4 和 IPv6IPv4 是目前使用的ip地址IPv6 是未来使用的i…

Redis进阶-缓存问题

Redis 最常用的一个场景就是作为缓存&#xff0c;本文主要探讨Redis作为缓存&#xff0c;在实践中可能会有哪些问题&#xff1f;比如一致性、击穿、穿透、雪崩、污染等。 为什么要理解Redis缓存问题 在高并发业务场景下&#xff0c;数据库大多数情况都是用户并发访问最薄弱的…

计算机是怎么读懂C语言的?

文章目录前言程序环境翻译环境翻译环境分类编译预处理预处理符号预定义符号#define#undef命令行定义条件编译文件包含头文件包含查找规则嵌套文件包含其他预处理指令编译阶段汇编链接&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;博主大一智能制造在读&#xff…