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

滑动窗口:最短的连续子串(r++可行解->l--最短解)

初始化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++;}
}

最小长度的子数组

给定一个含有 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:
  1. left=arr.slice(0,mid)
  2. mergeLeft=mergeSort(left)
  3. res.push(leftArr.shift())
  4. 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}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车类、TPS7B8225QDGNRQ1、TPS7B8233EPWPRQ1、TPS7B8601QKVURQ1 40V、低压降 (LDO) 线性稳压器

一、TPS7B82-Q1 汽车类 300mA、高压、超低 IQ 低压降稳压器 &#xff08;介绍&#xff09;在汽车电池连接应用中&#xff0c;低静态电流 (IQ) 对于省电和延长电池寿命而言至关重要。对于始终开启的系统&#xff0c;必须要实现超低 IQ。 TPS7B82-Q1 是一款旨在在 3V 至 40V&…

【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )

文章目录 一、左移运算符重载1、友元函数 / 成员函数 实现运算符重载2、类对象 使用 左移运算符3、左移运算符 << 重载 二、完整代码示例 一、左移运算符重载 1、友元函数 / 成员函数 实现运算符重载 运算符重载 的正规写法一般都是 使用 成员函数 的形式 实现的 ; 加法…

Llama2-Chinese项目:8-TRL资料整理

TRL&#xff08;Transformer Reinforcement Learning&#xff09;是一个使用强化学习来训练Transformer语言模型和Stable Diffusion模型的Python类库工具集&#xff0c;听上去很抽象&#xff0c;但如果说主要是做SFT&#xff08;Supervised Fine-tuning&#xff09;、RM&#x…

Python脚本实现xss攻击

实验环境&#xff1a;zd靶场、vscode 知识点 requests.session() 首先我们需要先利用python requests模块进行登录&#xff0c;然后利用开启session记录&#xff0c;保持之后的操作处于同一会话当中 requests.session()用于创建一个会话(session)的实例对象。使用requests库…

【JavaEE】多线程进阶(一)饿汉模式和懒汉模式

多线程进阶&#xff08;一&#xff09; 文章目录 多线程进阶&#xff08;一&#xff09;单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式&#xff0c;为后面的大冰山做铺垫 代码案例介绍 单例模式 非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”…

Python无废话-办公自动化Excel格式美化

设置字体 在使用openpyxl 处理excel 设置格式&#xff0c;需要导入Font类&#xff0c;设置Font初始化参数&#xff0c;常见参数如下&#xff1a; 关键字参数 数据类型 描述 name 字符串 字体名称&#xff0c;如Calibri或Times New Roman size 整型 大小点数 bold …

做外贸独立站选Shopify还是WordPress?

现在确实会有很多新人想做独立站&#xff0c;毕竟跨境电商平台内卷严重&#xff0c;平台规则限制不断升级&#xff0c;脱离平台“绑架”布局独立站&#xff0c;才能获得更多流量、订单、塑造品牌价值。然而&#xff0c;在选择建立外贸独立站的过程中&#xff0c;选择适合的建站…

TinyWebServer整体流程

从main主函数开始&#xff1a; 一、定义MySQL数据库的账号、密码和用到的数据库名称。 二、调用Config获得服务器初始化属性 在这一步确定触发模式端口等信息。 三、创建服务器实例对象 设置根目录、开辟存放http连接对象的空间&#xff0c;开辟定时器空间。 四、利用Confi…

《视觉 SLAM 十四讲》V2 第 5 讲 相机与图像

文章目录 相机 内参 && 外参5.1.2 畸变模型单目相机的成像过程5.1.3 双目相机模型5.1.4 RGB-D 相机模型 实践5.3.1 OpenCV 基础操作 【Code】OpenCV版本查看 5.3.2 图像去畸变 【Code】5.4.1 双目视觉 视差图 点云 【Code】5.4.2 RGB-D 点云 拼合成 地图【Code】 习题题…

Clion中使用C/C++开发stm32程序

前言 从刚开始学习阶段&#xff0c;一直是用的keil5开发stm32程序&#xff0c;自从看到稚晖君推荐的CLion开发嵌入式程序后&#xff0c;这次尝试在CLion上开发stm32程序。 1、配置CLion用于STM32开发的环境 这里我就不详细写了&#xff0c;没必要重新写&#xff0c;网上教程很多…

Http常见问题

说说 HTTP 常用的状态码及其含义&#xff1f; HTTP 状态码首先应该知道个大概的分类&#xff1a; 1XX&#xff1a;信息性状态码2XX&#xff1a;成功状态码3XX&#xff1a;重定向状态码4XX&#xff1a;客户端错误状态码5XX&#xff1a;服务端错误状态码 301&#xff1a;永久性…

突破封锁|华为芯片10年进化史:从K3V1到麒麟9000S

华为海思麒麟芯片过去10年研发历程回顾如下&#xff1a; 2009年&#xff1a;华为推出第一款手机芯片K3V1&#xff0c;采用65nm工艺制程&#xff0c;基于ARM11架构&#xff0c;主频600MHz&#xff0c;支持WCDMA/GSM双模网络。这款芯片搭载在华为U8800手机上&#xff0c;标志着华…