Leetcode刷题笔记3
18. 四数之和
18. 四数之和 - 力扣(LeetCode)

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
解法一:排序 + 暴力枚举 + 理由set去重
超时
解法二:排序 + 双指针
[-2, -1, 0, 0, 1, 2] target
[ ] target - a
a
b [ ] target - a - b
left right
1. 先依次固定一个a;
2. 在a后面的区间内,利用“三数之和”找到三个数,使这三个数的和等于target - a即可
三数之和的大体思路:
1. 依次固定一个b;
2. 在b后面的区间内,利用“双指针”找到两个数,使这两个数的和等于target - a - b即可
处理细节问题:
1. 不重
去重a,b,left,right
2. 不漏
时间复杂度:O(N^3)
代码:C++
class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;// 排序sort(nums.begin(), nums.end());// 利用双指针解决问题int n = nums.size();for(int i=0; i<n; ) //固定a{// 利用三数之和for(int j=i+1; j<n; ) //固定b{// 双指针int left = j+1, right = n-1;long long aim = (long long)target - nums[i] - nums[j];while(left<right){int sum = nums[left] + nums[right];if(sum < aim) left++;else if(sum > aim) right--;else{ret.push_back({nums[i], nums[j], nums[left++], nums[right--]});// 去重1while(left < right && nums[left] == nums[left - 1]) left++; //当left右移完之后和左边这个数相比,如果相同,说明重复元素,需要跳过while(left < right && nums[right] == nums[right + 1]) right--;}}// 去重2j++;while(j < n && nums[j] == nums[j - 1]) j++;}// 去重3i++;while(i < n && nums[i] == nums[i - 1]) i++;}return ret;}
};
209. 长度最小的子数组
209. 长度最小的子数组 - 力扣(LeetCode)

解法一:暴力枚举出所有子数组的和
时间复杂度:O(N^3)
R
[2, 3, 1, 2, 4, 3]
L
先定义一个sum,计算左区间的和
比如:sum + 2 + 3 + ...
这样可以省去再遍历一遍数组
R
[2, 3, 1, 2, 4, 3]
L
sum = 5
R
[2, 3, 1, 2, 4, 3]
L
sum = 6
len 2 -> 3
...
R
[2, 3, 1, 2, 4, 3]
L
sum = 12
len = 5
这个len是一直增长的,所以肯定不是最短的结果
接下来让L向左移动一位,然后继续让R从左开始移动
那这个时候从3开始的区间可以在上一个结果中找到
解法二:利用单调性,使用“同向双指针”来优化,也就是 滑动窗口
当使用暴力解法时。两个指针都可以做到不回退,都是向一个方向移动时就可以使用滑动窗口
1. 初始化;left = 0, right = 0
2. 进窗口
3. 判断是否是结果,然后更新结果(长度),再出窗口,判断len
2和3一直循环
以下是图解:






4. 为什么不往后枚举呢?因为已经知道接下来的情况再枚举也是白枚举,因为是正整数数组
利用单调性,规避了很多没有必要的枚举行为
5. 时间复杂度
进窗口要一个循环,判断也是一个循环,等于是两层循环套在一起
但是总的操作次数只是2n次
所以最终的时间复杂度是一个O(N)
代码:C++
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int sum = 0, len = INT_MAX; //如果定义0,那最终的求min结果就是0,所以定义一个大的变量,不干扰最终结果for(int left = 0, right = 0; right < n; right++){// 进入窗口sum += nums[right];//判断要不要缩小窗口while(sum >= target){len = min(len, right - left + 1); // 更新结果sum -= nums[left++]; // 出窗口}// 一直更新到窗口不符合要求位置,然后right++}return len == INT_MAX ? 0 : len; // 如果没有最终结果就返回0,不然就返回len}
};
3. 无重复字符的最长子串
3. 无重复字符的最长子串 - 力扣(LeetCode)

子串和字数组都是连续的一段
解法一:暴力枚举 + 哈希表(判断字符是否重复出现)
可以借助哈希表来判断是否有重复字符
遍历的时候把字符保存到哈希表里,当遍历到重复元素时,停止这个操作
R
[d, e, a, b, c, a, b, c, a]
L
R
[d, e, a, b, c, a, b, c, a]
L
当a重复时,停止这个操作,然后移动L,
R
[d, e, a, b, c, a, b, c, a]
L
时间复杂度:O(N^2)
解法二:利用规律,使用“滑动窗口”来解决问题
R
[d, e, a, b, c, a, b, c, a]
L
R
[[d, e, a, b, c], a, b, c, a]
L
当a重复时,停止这个操作,然后移动L,
R
[[d, e, a, b, c], a, b, c, a]
L
当发现区间里面有重复字符时,可以让L先跳过这个重复字符
R也不用回到L的位置,让R继续移动即可
此时就可以使用滑动窗口解决问题
1. 先定义L = 0和R = 0
2. 进窗口 -> 让字符进入哈希表
3. 判断
根据判断结果判定是否出窗口(窗口内出现重复字符时才出窗口)
判断和出窗口是一个循环,一直到没有重复字符为止
出窗口就是从哈希表中删除该字符
然后更新结果(更新结果的过程要根据题目决定在哪)
本题中,在整个判断之后,更新结果
为什么要用滑动窗口,因为两个指针都不会回退
时间复杂度:O(N)
空间复杂度:O(1)
因为哈希表只有128位,所以可以忽略不计
代码:C++
class Solution {
public:int lengthOfLongestSubstring(string s) {// 下标表示字符,让里面的数来表示是否重复出现,出现一次为1,两次为2...int hash[128] = {0}; // 使用数组表示哈希表int left = 0, right = 0, n = s.size();int ret = 0;while(right < n){hash[s[right]]++; // 字符对应的下标,进入窗口while(hash[s[right]] > 1) // 判断{hash[s[left++]]--; // 先把哈希表里面的对应的值--,表示它从哈希表删除,然后++完成出窗口的操作}ret = max(ret, right - left + 1); // 更新结果,区间的长度是right - left + 1right++; // 让下一个元素进入窗口}return ret;}
};
1004. 最大连续1的个数 III
1004. 最大连续1的个数 III - 力扣(LeetCode)

最多k个0说明可以翻转0,1,2,...,一直到k个为止
比如下方这个例子中,k最多可以翻转100个0,但其实不需要翻转100次
[1,1,0,0,1,1,0], k = 100
[1,1,1,0,0,0,1,1,1,1,0], K = 2
[ ],最长为6
可以等价处理,在数组中满足0的个数不超过k次即可,只要这个区域的0不超过k,那么这个区域是一定可以翻转成功的
把原始问题转换成:
找出最长的子数组,0的个数不超过k个
解法一:暴力枚举 + zero计数器(int类型变量,统计0出现多少次)
R
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], K = 2
L
zero = 0
R
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], K = 2
L
zero = 1
R
[[1, 1, 1, 0, 0], 0, 1, 1, 1, 1, 0], K = 2 固定第一个位置的最优解
L
zero = 2
然后R继续从数组最开始的位置开始移动
解法二:滑动窗口
所以可以让R越过这段区域,不用重新遍历,可以移动L
R
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], K = 2
L
当在暴力枚举中L和R都只往一个方向移动时,可以使用滑动窗口
1. left = 0, right = 0
2. 进窗口 -> 如果是1,无视;如果是0,计数器+1
当R向后移动时就相当于进窗口了
当进入窗口时无视,当碰到0时,计数器加一
3. 判断 -> 当zero大于k,出窗口
出窗口
让L一直右移,直到窗口合法为止
当判断结束之后,更新结果,当R移动到最后位置就会得到最终结果
时间复杂度:O(N)
空间复杂度:O(1)
代码:C++
class Solution {
public:int longestOnes(vector<int>& nums, int k) {int ret = 0;for(int left = 0, right = 0, zero = 0; right < nums.size(); right++){if(nums[right] == 0) zero++; // 进窗口while(zero > k) // 判断窗口是否合法{if(nums[left++] == 0) zero--; // 出窗口,left向后移动} // 左闭右闭的区间ret = max(ret, right - left + 1); // 更新结果}return ret;}
};相关文章:
Leetcode刷题笔记3
18. 四数之和 18. 四数之和 - 力扣(LeetCode) 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应&…...
初识C语言——第二十九天
数组 本章重点 1.一维数组的创建和初始化 数组的创建 注意事项: 1.一维由低数组在内存中是连续存放的! 2.随着数组下标的增长,地址是由低到高变化的 2.二维数组的创建和初始化 注意事项: 1.二维数组在内存中也是连续存放的&am…...
LeetCode27.移除元素
题目链接: 27. 移除元素 - 力扣(LeetCode) 思路分析:同样属于经典的双指针移动问题,要掌握固定的思路即可。 算法分析:这个题目可以这样处理,我们把所有非val 的元素都向前移动,把…...
DiffMap:首个利用LDM来增强高精地图构建的网络
论文标题: DiffMap: Enhancing Map Segmentation with Map Prior Using Diffusion Model 论文作者: Peijin Jia, Tuopu Wen, Ziang Luo, Mengmeng Yang, Kun Jiang, Zhiquan Lei, Xuewei Tang, Ziyuan Liu, Le Cui, Kehua Sheng, Bo Zhang, Diange Ya…...
ComfyUI简单介绍
🍓什么是ComfyUI ComfyUI是一个为Stable Diffusion专门设计的基于节点的图形用户界面,可以通过各种不同的节点快速搭建自己的绘图工作流程。 软件打开之后是长这个样子: 同时软件本身是github上的一个开源项目,开源地址为&#…...
【内存泄漏Bug】animation未释放
问题描述 一个页面做了动画特效,这个页面有可能跳转到其他页面,并长时间不返回,该页面此时已经不活跃了,该页面的对象为无用对象,存在内存泄漏风险 问题分析 这个activity的特性是 1. 有可能跳转到其他页面 2. 有可…...
《异常检测——从经典算法到深度学习》28 UNRAVEL ANOMALIES:基于周期与趋势分解的时间序列异常检测端到端方法
《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …...
Python正则模块re方法介绍
Python 的 re 模块提供了多种方法来处理正则表达式。以下是一些常用的方法及其功能介绍: 1. re.match() 在字符串的开始位置进行匹配。 import repattern r\d string "123abc456"match re.match(pattern, string) if match:print(f"匹配的字符…...
pdf使用pdfbox切割pdf文件MultipartFile
引入依赖: <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.25</version></dependency>测试代码: import io.choerodon.core.iam.ResourceLevel; impo…...
力扣HOT100 - 31. 下一个排列
解题思路: 数字是逐步增大的 步骤如下: class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…...
设计模式 20 中介者模式 Mediator Pattern
设计模式 20 中介者模式 Mediator Pattern 1.定义 中介者模式(Mediator Pattern)是一种行为型设计模式,它通过封装对象之间的交互,促进对象之间的解耦合。中介者模式的核心思想是引入一个中介者对象,将系统中对象之间…...
在 C++ 中,p->name 和 p.name 的效果并不相同。它们用于不同的情况,取决于你是否通过指针访问结构体成员。
p->name:这是指针访问运算符(箭头运算符)。当 p 是一个指向结构体的指针时,用 p->name 来访问结构体的成员。 student* p &stu; // p 是一个指向 student 类型的指针 cout << p->name << endl; // 通过…...
C++基础:多态
多态相关 多态继承重写父类的虚函数多态的体现,父类的引用指向子类对象的空间虚函数可以实现,也可以不实现,不实现必须要有初始值存在未定义的虚函数的类为抽象类.抽象类不能实例化对象;(animal父类不能实例化对象)如果父类中的函数非虚函数,则会调用父类中的函数//多态的体现…...
移除元素(算法题)
文章目录 移除元素解题思路 移除元素 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。…...
电商场景的视频动效
AtomoVideo:AIGC赋能下的电商视频动效生成本文分享阿里妈妈视频 AIGC(AtomoVideo等) 赋能视频广告创意的探索和实践。通过基于扩散模型的视频生成技术,结合可控生成技术,使静态电商图片能够栩栩如生地“动”起来,实现了在电商领域的视频 AIGC 应用落地。https://mp.weixi…...
Windows操作系统基本知识整理
目录 引言 一、Windows操作系统的发展历史 1.1 Windows 1.0到Windows 3.0 1.2 Windows 95到Windows Me 1.3 Windows NT到Windows 2000 1.4 Windows XP到Windows 7 1.5 Windows 8到Windows 10 二、Windows操作系统的核心组件 2.1 内核 2.2 文件系统 2.3 图形用户界面&…...
Vue 状态管理深入研究:Vuex 和 Pinia 的原理与实践对比
推荐一个AI网站,免费使用豆包AI模型,快去白嫖👉海鲸AI 👋 引言 在 Vue.js 应用程序中,状态管理是一个至关重要的方面。它有助于集中管理应用的状态,使组件之间的数据共享更加高效和可维护。Vuex 和 Pinia …...
【三数之和】python,排序+双指针
暴力搜索3次方的时间复杂度,大抵超时 遇到不会先排序 排序双指针 上题解 照做 class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:res[]nlen(nums)#排序降低复杂度nums.sort()k0#留两个位置给双指针i,jfor k in range(n-2):if nums[k]…...
TCP通信实现(服务端与客户端)
TCP通信实现(服务器端) 案例 // TCP 通信的服务器端#include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h>int main() {// 1.创建socket(用于监听的套接字)int lfd socket(AF_…...
安装appium自动化测试环境,我自己的版本信息
教程来自:Appium原理与安装 - 白月黑羽 我的软件的版本: 安装是选择为自己安装而不是选all user pip install appium-python-client命令在项目根目录下安装appium-python-client sdk的话最简单的安装方式就是去Android官网下一个android studio然后在…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
