Leetcode hot 100之双指针(快慢指针、滑动窗口)
目录
数组
有序的平方仍有序
删除/覆盖元素
移动零:交换slow和fast
滑动窗口:最短的连续子串(r++可行解->l--最短解)
最小长度的子数组
求和:sort、l = i + 1, r = len - 1
三数之和a+b+c=target
四数之和a+b+c+d=target
颜色分类(荷兰国旗):start=0、i、end=len-1
盛水最多:start=0、end=len-1 (水=哪边,则哪边往内走)
重复数:[1, n]
链表
相交点:长的链表先走len=long-short
倒数第n个:slow+1,fast+n
中点/回文/环:slow+1,fast+2
环入口:相遇点+1、头结点+1
归并排序
自底向上
自顶向下
双指针
数组
数组
有序的平方仍有序
删除/覆盖元素
if(nums[i] != val){nums[k++] = nums[i]}
移动零:交换slow和fast
滑动窗口
初始化left = right = 0
,把索引左闭右开区间[left, right)
称为一个「窗口」。
int left = 0, right = 0;while (right < s.size()) {// 增大窗口window.add(s[right]);right++;while (window needs shrink) {// 缩小窗口window.remove(s[left]);left++;}
}
最小覆盖子串
function minWindow(s, t) {const need = new Map();const window = new Map();for (const c of t) {need.set(c, (need.get(c) || 0) + 1);}let left = 0;let right = 0;let valid = 0;let start = 0;let len = Infinity;while (right < s.length) {const c = s[right];right++;if (need.has(c)) {window.set(c, (window.get(c) || 0) + 1);if (window.get(c) === need.get(c)) {valid++;}}while (valid === need.size) {if (right - left < len) {start = left;len = right - left;}const d = s[left];left++;if (need.has(d)) {if (window.get(d) === need.get(d)) {valid--;}window.set(d, window.get(d) - 1);}}}return len === Infinity ? "" : s.substr(start, len);
}
字符串排列/异位词
function checkInclusion(t, s) {const need = new Map();const window = new Map();for (const c of t) {need.set(c, (need.get(c) || 0) + 1);}let left = 0;let right = 0;let valid = 0;while (right < s.length) {const c = s[right];right++;if (need.has(c)) {window.set(c, (window.get(c) || 0) + 1);if (window.get(c) === need.get(c)) {valid++;}}
//与最小覆盖串的区别while (right - left >= t.length) {if (valid === need.size) {return true;}
//与最小覆盖串的区别 const d = s[left];left++;if (need.has(d)) {if (window.get(d) === need.get(d)) {valid--;}window.set(d, window.get(d) - 1);}}}return false;
}
最长无重复子串
function lengthOfLongestSubstring(s) {const window = new Map();let left = 0;let right = 0;let res = 0; // 记录结果while (right < s.length) {const c = s[right];right++;// 进行窗口内数据的一系列更新window.set(c, (window.get(c) || 0) + 1);// 判断左侧窗口是否要收缩while (window.get(c) > 1) {const d = s[left];left++;// 进行窗口内数据的一系列更新window.set(d, window.get(d) - 1);}// 在这里更新答案res = Math.max(res, right - left);}return res;
}
最小长度的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
类似于前缀和:区间求和
let ans = Infinitywhile(end < len){sum += nums[end];while (sum >= target) {ans = Math.min(ans, end - start + 1);sum -= nums[start];start++;}end++;}
求和:sort、l = i + 1, r = len - 1
三数之和a+b+c=target
arr.sort()let l = i + 1, r = len - 1, iNum = nums[i]// 数组排过序,如果第一个数大于0直接返回resif (iNum > 0) return res// 去重if (iNum == nums[i - 1]) continuewhile(l < r) {if (threeSum < 0) l++ else if (threeSum > 0) r--else {res.push([iNum, lNum, rNum])// 去重while(l < r && nums[l] == nums[l + 1]){l++}while(l < r && nums[r] == nums[r - 1]) {r--}l++r--} }
四数之和a+b+c+d=target
for(let i = 0; i < len - 3; i++) {// 去重iif(i > 0 && nums[i] === nums[i - 1]) continue;
颜色分类(荷兰国旗):start=0、i、end=len-1
盛水最多:start=0、end=len-1 (水=哪边,则哪边往内走)
重复数:[1, n]
T(n):O(n)。「Floyd 判圈算法」时间复杂度为线性的时间复杂度。
S(n):O(1)。只需要常数空间存放若干变量。
对 nums数组建图,每个位置 i连一条 i→nums[i] 的边。由于存在的重复的数字 target,因此 targe这个位置一定有起码两条指向它的边,因此整张图一定存在环,且我们要找到的 target就是这个环的入口
var findDuplicate = function(nums) {let slow = 0, fast = 0;do {slow = nums[slow];fast = nums[nums[fast]];} while (slow != fast);slow = 0;while (slow != fast) {slow = nums[slow];fast = nums[fast];}return slow;
};
链表
相交点:长的链表先走len=long-short
倒数第n个:slow+1,fast+n
中点/回文/环:slow+1,fast+2
环入口:相遇点+1、头结点+1
相遇时: slow指针走过的节点数为: x + y
, fast指针走过的节点数:x + y + n (y + z)
,n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A
(x + y) * 2 = x + y + n (y + z)
x = (n - 1) (y + z) + z
虽然实际中的n>1,当 n为1的时候,公式就化解为 x = z
从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
归并排序
自底向上
T(n):O(nlogn)
S(n):O(1)
空间复杂度不是累计的,而是计算使用空间的峰值,
C/C++ 没有回收资源(new完后需要delete,不然内存泄漏照样是O(logn)),
但是像 java ,js这类语言会自动回收资源的
每次将链表拆分成若干个长度为 subLength 的子链表(最后一个子链表的长度可以小于 subLength)
/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val = (val? 0 : val)* this.next = (next? null : next)* }*/
const merge = (head1, head2) => {let temp = new ListNode(0), temp1 = head1, temp2 = head2;while (temp1&& temp2) {if (temp1.val <= temp2.val) {temp.next = temp1;temp1 = temp1.next;} else {temp.next = temp2;temp2 = temp2.next;}temp = temp.next;}if (temp1 !== null) {temp.next = temp1;} else if (temp2 !== null) {temp.next = temp2;}return dummyHead.next;
}var sortList = function(head) {if (head === null) {return head;}//获取长度let length = 0;let node = head;while (node !== null) {length++;node = node.next;}const dummyHead = new ListNode(0, head);for (let subLength = 1; subLength < length; subLength <<= 1) {let prev = dummyHead, curr = dummyHead.next;while (curr !== null) {let head1 = curr;for (let i = 1; i < subLength && curr.next; i++) {curr = curr.next;}let head2 = curr.next;curr.next = null;curr = head2;for (let i = 1; i < subLength && curr&& curr.next; i++) curr = curr.next;}let next = null;if (curr) {next = curr.next;curr.next = null;}const merged = merge(head1, head2);//通过 prev 指针将已排序的子链表连接到一起prev.next = merged;while (prev.next) {prev = prev.next;}//用 curr 指针继续遍历未排序的部分curr = next;}}return dummyHead.next;
};
自顶向下
操作 | 内部排序 | 思想 | 稳定 | 平均 S(n) | T(n) | ||
平均 | 最坏 | 最好 |
2-路归并 | 分治;分组排序,两两合并 相邻 有序序列 | √ | n | nlog2n | nlog2n逆序 | nlog2n顺序 |
双指针
const merge = (head1, head2) => {const dummyHead = new ListNode(0);let temp = dummyHead, temp1 = head1, temp2 = head2;while (temp1 !== null && temp2 !== null) {if (temp1.val <= temp2.val) {temp.next = temp1;temp1 = temp1.next;} else {temp.next = temp2;temp2 = temp2.next;}temp = temp.next;}if (temp1 !== null) {temp.next = temp1;} else if (temp2 !== null) {temp.next = temp2;}return dummyHead.next;
}const toSortList = (head, tail) => {if (head === null) {return head;}if (head.next === tail) {head.next = null;return head;}let slow = head, fast = head;while (fast !== tail) {slow = slow.next;fast = fast.next;if (fast !== tail) {fast = fast.next;}}const mid = slow;return merge(toSortList(head, mid), toSortList(mid, tail));
}var sortList = function(head) {return toSortList(head, null);
};
数组
- key:
- left=arr.slice(0,mid)
- mergeLeft=mergeSort(left)
- res.push(leftArr.shift())
- res=res.concat(leftArr)
function mergesort(arr){if(arr.length<2)return arrlet len=arr.lengthlet mid=parseInt(len/2)let l1=arr.slice(0,mid)let r1=arr.slice(mid,len)let mergeleft=mergesort(l1)let mergeright=mergesort(r1)return merge(mergeleft,mergeright)function merge(left,right){let res=[]while(left.length&&right.length){if(left[0]<=right[0]){res.push(left.shift())}else{res.push((right.shift()))}}if(left.length){res=res.concat(left)}if(right.length){res=res.concat(right)}return res}}
相关文章:

Leetcode hot 100之双指针(快慢指针、滑动窗口)
目录 数组 有序的平方仍有序 删除/覆盖元素 移动零:交换slow和fast 滑动窗口:最短的连续子串(r可行解->l--最短解) 最小长度的子数组 求和:sort、l i 1, r len - 1 三数之和abctarget 四数之和abcdtarg…...

Bridge Champ助力我国桥牌阔步亚运, Web3游戏为传统项目注入创新活力
本届杭州亚运会,中国桥牌队表现杰出,共斩获1金1银1铜佳绩,其中女子团体夺得冠军,混合团体获得亚军。这充分展现了我国桥牌的实力,也彰显了桥牌作为亚运会体育竞技项目的影响力。与此同时,Web3游戏Bridge Champ为传统桥牌项目带来创新模式,将有望推动桥牌运动在亚运舞台上焕发新…...

云原生微服务 第六章 Spring Cloud中使用OpenFeign
系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…...
uniapp-vue3 抖音小程序开发(上线项目开源)
最近公司临时接一个项目来接手别人的流量,项目比较小,时间比较赶。 需求:一个答题小程序,通过答题来实现性格测算和分析。 之前开发过支付宝小程序和微信小程序,这次是首次开发抖音小程序,老板要求只能下…...

基于微信小程序的个人健康数据管理平台设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

真香!Jenkins 主从模式解决问题So Easy~
01.Jenkins 能干什么 Jenkins 是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。 中文官网:https://jenkins.io/zh/ 0…...

Win10系统打开组策略编辑器的两种方法
组策略编辑器是Win10电脑中很实用的工具,它可以帮助用户管理和设置计算机的安全性、网络连接、软件安装等各种策略。但是,很多新手用户不知道打开Win10电脑中组策略编辑器的方法步骤,下面小编给大家介绍两种简单的方法,帮助打开快…...
git 的行结束符
CR (Carriage Return) 表示<回车>LF (Line Feed) 表示<换行> 1. 不同系统的行结束符 系统名称行结束符意义释义git line endings选项DOS / Windows\r\nCRLF‘\r’是使光标移动到行首 ’\n’是使光标下移一行Windows-styleMacOS\rCRreturnAs-isUNIX / Linux\nLFne…...

buuctf PWN warmup_csaw_2016
下载附件,IDA查看 发现直接有显示flag函数 int sub_40060D() {return system("cat flag.txt"); }查看程序起始地址0x40060D ; Attributes: bp-based framesub_40060D proc near ; __unwind { push rbp mov rbp, rsp mov edi, offset comman…...

C++中的对象切割(Object slicing)问题
在C中,当我们把派生类对象向上强制转型为基类对象时,会造成对象切割(Object slicing)问题。 请看下面示例代码: #include <iostream> using namespace std;class CBase { public:virtual ~CBase() default;v…...

VxeTable 表格组件推荐
VxeTable 表格组件推荐 https://vxetable.cn 在前端开发中,表格组件是不可或缺的一部分,它们用于展示和管理数据,为用户提供了重要的数据交互功能。VxeTable 是一个优秀的 Vue 表格组件,它提供了丰富的功能和灵活的配置选项&…...

好消息:用 vue3+layui 共同铸造我们新的项目
前言: layui这个框架不知道多少人还在关注着,记得第一次接触它是在18年,后来随着vue,react的盛行,jquerylayui的模式受到了特别大的冲击,后来作者都放弃维护他的官方网站,转而在github/gitee上做…...
JS中 split(/s+/) 和 split(‘ ‘)的区别以及split()详细解法,字符串分割正则用法
博主: http://t.csdnimg.cn/e4gDi split用法详解: http://t.csdnimg.cn/6logr...
MySQL性能调优
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,…...

如何解决openal32.dll丢失,有什么办法解决
你第一次知道openal32.dll文件是在什么情况下,你了解过openal32.dll文件吗?如果电脑中openal32.dll丢失有什么办法可以解决,今天就教大家如何解决openal32.dll丢失,都有哪些办法可以解决openal32.dll丢失。 一.openal3…...
Nginx 如何配置http server 、负载均衡(反向代理)
目录 1. 关于 Nginx2. 配置http server3. 配置负载均衡 本文主要介绍 Nginx中如何配置 http server,负载均衡(反向代理)。 1. 关于 Nginx Nginx是一个开源的、高性能的、稳定的、简单的、功能丰富的HTTP和反向代理服务器,也可以用作IMAP/POP3/SMTP代理…...

windows docker desktop配置加速地址
目录 为什么常见加速地址在docker desktop上配置 为什么 https://hub.docker.com 是官方的镜像仓库地址,但是它的服务器地址是在国外,有时候访问和下载的速度差强人意。不过好在,我们可以进行远程仓库的设置,将仓库镜像地址设置为…...

戏剧影视设计制作虚拟仿真培训课件提升学生的参与感
说起影视制作,知名的影视制片人寥寥无几,大多数人还在依靠摄影机拍摄实景或搭建实体场景来不断精进场景布局和导演效果,成本高、投入人员多且周期长,随着VR虚拟现实技术的不断发展,利用VR模拟仿真技术进行影视制作实操…...

Transformer预测 | Pytorch实现基于Transformer的锂电池寿命预测(NASA数据集)
文章目录 效果一览文章概述模型描述程序设计参考资料效果一览 文章概述 Pytorch实现基于Transformer 的锂电池寿命预测,环境为pytorch 1.8.0,pandas 0.24.2 随着充放电次数的增加,锂电池的性能逐渐下降。电池的性能可以用容量来表示,故寿命预测 (RUL) 可以定义如下: SOH(t…...
取出SQLite数据(基本游标)
前面一节中已经为Starbuzz创建了一个SQLite帮助器。 目前还是从Java Drink类获取数据,这时候要修改这个应用从SQLite数据库获取数据。 本文所有代码均存放于 https://github.com/MADMAX110/Starbuzz 一、修改DrinkActivity来使用Starbuzz数据库 基本步骤ÿ…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...

Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...