JavaScript算法46- 最长连续序列(leetCode:128middle)
128. 最长连续序列
一、题目
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
提示:
- 0 <= nums.length <= 105
- -109 <= nums[i] <= 109
二、题解
初版
栗子: [100,4,200,200,1,3,2]
思路:
- 原数组从小到大排序
[1,2,3,4,100,200,200] - 去重
[1,2,3,4,100,200] - 找出连续片段
[1,2,3,4][100,200] - 取最长 [1,2.,3,4] ⇒
4
/*** @param {number[]} nums* @return {number}*/
var longestConsecutive = function(nums) {if(nums.length < 2) return nums.length;// 排序 + 去重const orderNums = [...new Set(nums.sort((a,b)=>a-b))];let maxLength = 1;let curLength = 1;for(let i = 1; i< orderNums.length; i++){if((orderNums[i]-orderNums[i-1]) === 1){curLength++;}else{maxLength = Math.max(maxLength,curLength);curLength = 1;}}return Math.max(maxLength,curLength);
};
优化版
优化点:相较于初版,少了排序
栗子: [100,4,200,200,1,3,2]
思路:
- 去重
[100,4,200,1,3,2] - 找出连续片段的起点值(即数组中不存在这个值-1) 起点值
1、100 - 继而得到完整片段
[1,2,3,4][100,200] - 比较各个片段的长度,得到最大值 [1,2.,3,4] ⇒
4
/*** @param {number[]} nums* @return {number}*/
var longestConsecutive = function(nums) {if(nums.length < 2) return nums.length;// 去重const numsSet = new Set(nums);let maxLength = 1;for(const num of numsSet){if(!numsSet.has(num-1)){let curNum = num;let curLength = 1;while(numsSet.has(curNum + 1)){curNum++;curLength++;}maxLength = Math.max(maxLength,curLength); }}return maxLength;
};
三、补充
Math.max()
返回输入参数的最大数字,如果没有参数,则返回 -Infinity。(参数可以是多个)
语法:Math.max(value0, value1, /* … ,*/ valueN)
详情参考:Math.max()
// case1
const array1 = [1, 3, 2];
console.log(Math.max(...array1)); // 3// case2
console.log(Math.max(-1, -3, -2)); // -1
集合 Set
Set详解
集合(set)中的元素只会出现一次,可以按照插入顺序迭代集合中的元素。
构造函数
Set()
const mySet= new Set();
const mySet= new Set([1, 2, 3, 4, 5]);
属性
size
mySet.size; // 5
方法
add()
mySet.add(10)
delete()
console.log(mySet.delete(1)); // true
console.log(mySet.delete(20)); //false 集合中没有要删的值
clear()
mySet.clear();
console.log(mySet()); // Set(0) {size: 0}
has()
console.log(mySet.has(1)); // trueconsole.log(mySet.has(99)); // false
values()
返回一个新的集合迭代器对象,该对象包含此集合对象中每个元素的值,按插入顺序排列。
keys()
keys() 返回一个迭代器,其值为集合中的所有键名。
如果是数组,返回的是索引;如果是Set集合,返回的是值(Set的值被同时用作键和值)。
const mySet = new Set();
mySet.add("foo");
mySet.add("bar");
mySet.add("baz");const setIter = mySet.keys();console.log(setIter.next()); // { value: 'foo', done: false }
console.log(setIter.next()); // { value: 'bar', done: false }
console.log(setIter.next()); // { value: 'baz', done: false }
entries()
此方法返回一个新的集合迭代器对象,该对象包含了此集合中每个元素的[value, value]数组,按插入顺序排列。
注:Set 对象没有类似于 Map 对象中的 key,为了保持 API 与 Map 对象类似,这里每个 entry 的 key 和 value 都相同,所以返回的数组为 [value, value]。
forEach()
语法
- forEach(callbackFn)
- forEach(callbackFn, thisArg)
// 方式一
function logSetElements(value1, value2, set) {console.log(`s[${value1}] = ${value2}`);
}new Set(['foo', 'bar', undefined]).forEach(logSetElements);
// s[foo] = foo
// s[bar] = bar
// s[undefined] = undefined// 方式二
new Set(['foo', 'bar', undefined]).forEach((value1, value2, set) => {console.log(`s[${value1}] = ${value2}`);
})
// s[foo] = foo
// s[bar] = bar
// s[undefined] = undefined
迭代器和生成器
迭代器
迭代器是一个对象,它定义了一个序列,通过使用next()方法迭代任何一个对象,
该方法返回的对象包含两个属性 {value:xxx, done:false}
value:迭代序列的下一个值done: 如果已经迭代到序列的最后一个值,则为true
const mySet = new Set();
mySet.add("foo");
mySet.add("bar");
mySet.add("baz");const setIter = mySet.keys();console.log(setIter.next()); // { value: 'foo', done: false }
console.log(setIter.next()); // { value: 'bar', done: false }
console.log(setIter.next()); // { value: 'baz', done: false }
console.log(setIter.next()); // { value: undefined, done: true }
console.log(setIter.next()); // { value: undefined, done: true }
可迭代对象
若一个对象拥有迭代行为,比如在for…of …中会循环一些值,那么这个对象便是一个可迭代对象。在ES6中,所有的集合对象(数组、Set集合及Map集合)和字符串都是可迭代对象,可迭代对象都绑定了默认的迭代器,而其它类型(比如Object)则没有。
- 访问默认迭代器
- 可迭代对象,都有一个
Symbol.iterator方法,for-of循环时,通过调用Symbol.iterator方法来获取默认迭代器的,这一过程是在JavaScript引擎背后完成的。 - 可以主动获取一下这个默认迭代器来感受一下:
// 迭代字符串
const myString = 'abcdef';// 方式一
const setIter2 = myString[Symbol.iterator]();
console.log(setIter2.next()); // { value: 'a', done: false }
console.log(setIter2.next()); // { value: 'b', done: false }
console.log(setIter2.next()); // { value: 'c', done: false }// 方式二
for(let char of myString) {console.log(char)
}
// a
// b
// c
// d
// e
// f
- 内建迭代器
- ES6中的集合对象,数组、Set集合和Map集合,都内建了三种迭代器:
- entries() 返回一个迭代器,其值为多个键值对。
如果是数组,第一个元素是索引位置;如果是Set集合,第一个元素与第二个元素一样,都是值。 - values() 返回一个迭代器,其值为集合的值。
- keys() 返回一个迭代器,其值为集合中的所有键名。
如果是数组,返回的是索引;如果是Set集合,返回的是值(Set的值被同时用作键和值)。
// 迭代数组
const myArray = [1,8,5,7,6,];
const setIter1 = myArray.values();
console.log(setIter1.next()); // { value: 1, done: false }
console.log(setIter1.next()); // { value: 8, done: false }
console.log(setIter1.next()); // { value: 5, done: false }
生成器
生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。
function *createIterator(items) {for(let i=0; i<items.length; i++) {yield items[i];}
}let iterator = createIterator([1, 2, 3]);// 既然生成器返回的是迭代器,自然就可以调用迭代器的next()方法
console.log(iterator.next()); // "{ value: 1, done: false}"
console.log(iterator.next()); // "{ value: 2, done: false}"
console.log(iterator.next()); // "{ value: 3, done: false}"
console.log(iterator.next()); // "{ value: undefiend, done: true}"
// 之后所有的调用都会返回相同内容
console.log(iterator.next()); // "{ value: undefiend, done: true}"
上面,我们用ES6的生成器,大大简化了迭代器的创建过程。我们给生成器函数createIterator()传入一个items数组,函数内部,for循环不断从数组中生成新的元素放入迭代器中,每遇到一个yield语句循环都会停止;每次调用迭代器的next()方法,循环便继续运行并停止在下一条yield语句处。
生成器的创建方式
生成器是个函数
function *createIterator(items) { ... }
也可以用函数表达式方式书写
let createIterator = function *(item) { ... }
也可以添加到对象中,ES5风格对象字面量:
let o = {createIterator: function *(items) { ... }
};let iterator = o.createIterator([1, 2, 3]);
ES6风格的对象方法简写方式:
let o = {*createIterator(items) { ... }
};let iterator = o.createIterator([1, 2, 3]);
相关文章:
JavaScript算法46- 最长连续序列(leetCode:128middle)
128. 最长连续序列 一、题目 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 输入:nums [100,4,200,1,3,2] 输出…...
提升 API 可靠性的五种方法
API 在我们的数字世界中发挥着关键的作用,使各种不同的应用能够相互通信。然而,这些 API 的可靠性是保证依赖它们的应用程序功能正常、性能稳定的关键因素。本文,我们将探讨提高 API 可靠性的五种主要策略。 1.全面测试 要确保 API 的可靠性…...
【K8S 系列】认识k8s、k8s架构
一、什么是k8s? Kubernetes 简称 k8s,是支持云原生部署的一个平台,k8s 本质上就是用来简化微服务的开发和部署的,用于自动化部署、扩展和管理容器化应用的开源容器编排技术。对于传统的docker其实也提供了容器编排的技术docker-compose&…...
通过这5步,快速成为数据分析师
1. 学习基础知识:掌握统计学、数学和编程等基础知识是成为数据分析师的第一步。你可以参加在线课程、教育平台或自学来提高自己的技能。 2. 学习数据分析工具:熟练使用数据分析工具如Python、R和SQL等是必要的。这些工具可以帮助你处理和分析大量的数据…...
深入解析 Spring 和 Spring Boot 的区别
目录 引言 1. 设计理念 1.1 Spring 框架的设计理念 1.2 Spring Boot 的设计理念 2. 项目配置 2.1 Spring 框架的项目配置 2.2 Spring Boot 的项目配置 3. 自动配置 3.1 Spring 框架的自动配置 3.2 Spring Boot 的自动配置 4. 微服务支持 4.1 Spring 框架的微服务支持…...
Python日期范围按旬和整月以及剩余区间拆分
昨天见到了一个比较烧脑的问题: 咋一看可能理解问题比较费劲,可以直接看结果示例: 当然这个结果在原问题上基础上有一定改进,例如将同一天以单个日期的形式展示。 如何解决这个问题呢?大家可以先拿测试用例自己试一下…...
windows安装sqlserver2008后连接失败问题
刚安装好的sqlserver在安装服务器上,直接使用Windows身份认证登录就报错 未找到或无法访问服务器。请验证实例名称是否正确并且SQL Server已配置为允许远程连接。(provider:命名管道提供程序,error:40 -无法打开到SQLS…...
mysql innodb知识记录
官方文档 官网架构图 innodb 特性 内存 buffer pool 采用优化后的LRU算法, 3/8 of the buffer pool is devoted to the old sublist.The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist.When In…...
在排序数组中查找元素的第一个和最后一个位置(Java详解)
一、题目描述 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示…...
k8s 安装firewalld导致的网络疑难问题处理
场景 ubuntu 操作系统,部署了k8s集群,n 台 机器,某些机器之间 telnet ip 10250不通。 ufw 是关闭的,然后抓包会看到如下错误 04:43:09.154362 IP 192.168.1.3.56608 > 192.168.1.183.8000: Flags [S], seq 3664350430, win 64240, options [mss 1460,sackOK,TS val 281…...
人工智能中的巨兽:图神经网络大模型的崛起
导言 图神经网络大模型的涌现标志着人工智能领域的一次革命。本文将深入研究这些庞大而强大的模型,探讨其背后的技术原理、关键应用以及引发的社会影响。 1. 技术原理 图神经网络大模型以其对图结构数据的卓越处理能力而著称。其技术原理包括: 图卷积神…...
【LeetCode刷题笔记(6-2)】【Python】【三数之和】【双指针】【中等】
文章目录 引言三数之和题目描述示例示例1示例2示例3 提示 解决方案3:【双指针】结束语 三数之和 引言 编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程…...
02_Web开发基础之JavaScript
Web开发基础之JavaScript 学习目标和内容 1、能够描述Javascript的作用 2、能够使用分支结构if语句逻辑判断 3、能够使用其中一种循环语句 4、能够定义javaScript中的函数 5、能够定义javaScript中的对象 6、能够描述DOM的作用 7、能够通过DOM操作HTML标签元素及其属性 8、能够…...
如何控制Elasticsearch搜索的相关性?
控制相关性 纯粹处理结构化数据(例如日期、数字和 字符串枚举)很简单:他们只需要检查一个文档(或 行,在关系数据库中)与查询匹配。 虽然布尔值是/否匹配是全文搜索的重要组成部分,但它们 光靠自己是不够的。相反,我们还需要知道每个的相关性 document 是查询。全文搜索…...
基于urllib库的网页数据爬取
实验名称: 基于urllib库的网页数据爬取 实验目的及要求: 【实验目的】 通过本实验了解和掌握urllib库。 【实验要求】 1. 使用urllib库爬取百度搜索页面。 2. 使用urllib库获取百度搜索的关键字搜索结果(关键字任选)。 实验原理及…...
Python如何匹配库的版本
目录 1. 匹配库的版本 2. Python中pip,库,编译环境的问题回答总结 2.1 虚拟环境 2.2 pip,安装库,版本 1. 匹配库的版本 (别的库的版本冲突同理) 在搭建pyansys环境的时候,安装grpcio-tools…...
日志审计在网络安全中的重要性
日志审计是一种通过分析、识别和验证各种日志信息,以帮助企业了解其网络和系统的安全状态和活动的过程。这些日志信息可能来自各种来源,包括服务器、网络设备、应用程序、操作系统等。 日志审计的主要功能包括: 1.识别潜在的安全威胁&#…...
浅谈基于不信任的防御性编程
背景 在实际开发过程中,我们经常遇到这样的场景: 后端报错了,手忙脚乱一顿排查,发现是前端传的参数为空,或者格式不对;后端又报错了,传参没问题,根据日志流发现,是某“给…...
线性代数(一)
1.标量:标量由只有⼀个元素的张量表⽰。 x np.array(3.0) y np.array(2.0) x y, x * y, x / y, x ** y (array(5.), array(6.), array(1.5), array(9.))2.向量:向量可以被视为标量值组成的列表,列向量是向量的默认⽅向。 x np.arange(4…...
k8s-learning-why we need pod
应用场景 应用从虚拟机迁移到容器中 为什么虚拟机中的应用不能无缝迁移到容器中 虚拟机中应用:一组进程,被管理在systemd或者supervisord中 容器的本质:一个容器一个进程 所以将运行在虚拟机中的应用无缝迁移到容器中,与容器…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
Vue 实例的数据对象详解
Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...
