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然后在…...
如何快速提升游戏效率:英雄联盟智能工具完整指南
如何快速提升游戏效率:英雄联盟智能工具完整指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟游戏中的繁琐操作和…...
如何解决多显示器壁纸管理的三大痛点:Superpaper跨平台解决方案实战指南
如何解决多显示器壁纸管理的三大痛点:Superpaper跨平台解决方案实战指南 【免费下载链接】superpaper A cross-platform multi monitor wallpaper manager. 项目地址: https://gitcode.com/gh_mirrors/su/superpaper 在多显示器工作环境中,你是否…...
Go Context 生命周期与控制流分析
Go Context 生命周期与控制流分析 在Go语言中,Context是控制并发任务生命周期和传递请求范围数据的重要机制。它广泛应用于超时控制、取消信号传递以及跨API边界的数据共享。理解Context的生命周期及其对控制流的影响,对于编写高效、健壮的并发程序至关…...
用快马AI将数据库理论变现实:三分钟搭建学生信息管理原型
用快马AI将数据库理论变现实:三分钟搭建学生信息管理原型 数据库系统概论这门课我学了很久,但总觉得理论和实践之间隔着一道鸿沟。直到最近尝试用InsCode(快马)平台快速搭建了一个学生信息管理系统原型,才发现原来抽象的概念可以这么直观地呈…...
YOLOv10实战:用官方镜像5分钟搭建智能监控原型系统
YOLOv10实战:用官方镜像5分钟搭建智能监控原型系统 想快速验证一个智能监控的想法,却卡在繁琐的环境配置和模型部署上?从安装CUDA、配置Python环境,到调试各种依赖库,可能半天时间就过去了,真正的业务逻辑…...
基于RexUniNLU的Matlab科研助手开发全攻略
基于RexUniNLU的Matlab科研助手开发全攻略 科研工作繁琐耗时?让AI帮你自动解析论文、理解公式、生成报告! 1. 引言:科研工作的智能革命 作为一名科研工作者,你是否经常被这些场景困扰:面对堆积如山的论文不知从何读起…...
在github上部署个人的vitepress文档网站
我开发的BMapViewer组件正式上线了,文档使用了vitepress搭建编写,使用github Pages进行部署,现在可以正常访问了,接下来我会完整的写一遍网站部署过程。 我的文档网站:https://banyan666.github.io/BMapViewer-docs/ …...
NanoHttpd POST 请求中文乱码问题解决方案
解决方案 推荐做法:服务器端修正 在请求处理的 serve() 方法中,在调用 parseBody() 之前,显式确保 Content-Type 包含 charsetUTF-8: Override public Response serve(IHTTPSession session) {Map<String, String> files n…...
LeetCode:726. Number of Atoms - Python
问题描述: 给定一个化学式formula(作为字符串),返回每种原子的数量。 原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字。 如果数量大于 1,原子后会跟着数字表示原子的…...
SolidWorks插件发布踩坑实录:从RegAsm报错到安装包权限,我的C#二次开发交付心得
SolidWorks插件发布全流程避坑指南:从代码签名到权限管理的实战经验 第一次看到自己开发的SolidWorks插件在同事电脑上成功加载时,那种成就感难以言喻。但在此之前,我经历了无数次"为什么在我机器上能运行,到他那里就报错&qu…...
