2024.8.30 Python 最大连续1的个数,滑动窗口,排列组合,三数之和

1.最大连续1的个数

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
示例 1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例 2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。

分析:这个题在27号的文章中写道过,但是我的掌握还是很差,包括之后的二叉树染色题,所以这两道题我会重新再写一遍,这个题的关键在于去找连续1的个数很难与k对应起来,所以不如翻转列表,直接找0的个数,把0变成1,数1,然后这时候就是,窗口中不超过k个1,最大的窗口就是最大连续1的个数。
***方法一:***下面是我自己写的双指针的方法

class Solution:def longestOnes(self,nums:List[int],k:int)->int:n=len(nums)for i in range(n):nums[i]=nums[i]^1num_1,left=0,0res=0for right in range(n):if nums[right]==1:num_1+=1while num_1>k:if nums[left]==1:num_1-=1left+=1res=max(res,right-left+1)return res

代码逻辑:
1.循环遍历翻转
2.右边遇见一个1就计数,当计数超过k的时候就移左边的,直到计数降下来,则继续循环,算每次的最大res
3.其实我如果使用双指针计算的话我完全没有必要去做翻转,没有必要。
方法二:二分查找
这个方法非常的巧妙,有点动态规划的思路,他是通过前n项和来进行计算的,首先是生成这个数列的前n项和的列表,然后此时的P就是一个单调递增的列表,那么就有right所在位置的n项和减left-1所在位置的n项和,就为这中间的1的数量,注意是left-1,因为left自己是要加上的,所以你减的时候应该减去left-1的n项和,left到right中间包括两边的所有列表元素就能包含进去了。

class Solution:def longestOnes(self, nums: List[int], k: int) -> int:n=len(nums)P=[0]for num in nums:P.append(P[-1]+(1-num))  #注意这里的1-num,等价于num^1ans=0for right in range(n):left=bisect.bisect_left(P,P[right+1]-k)ans=max(ans,right-left+1)return ans

注意,因为P[0]=0,也就是说,关于数列的前n项和在P中应该是n+1,比如到0项和,应该是P[1],所以本来要找的是,right的前n项和,减去left-1要等于k,现在就变成了P[right+1]-P[left]==k,这里的加一减一确实不好想,那不如在实际操作的时候看和结果差多少,通过debug来找这个问题。
关于这个bisect.bisect_left这个是二分查找,代码实现如下:

def find(self,nums:List[int],k:int)->int:n=len(nums)left=0right=n-1while left<right:mid=(left+right)//2if nums[mid]<k:left=mid+1else:right=midreturn left 

2.执行所有后缀指令

现有一个 n x n 大小的网格,左上角单元格坐标 (0, 0) ,右下角单元格坐标 (n - 1, n - 1) 。给你整数 n 和一个整数数组 startPos ,其中 startPos = [startrow, startcol] 表示机器人最开始在坐标为 (startrow, startcol) 的单元格上。
另给你一个长度为 m 、下标从 0 开始的字符串 s ,其中 s[i] 是对机器人的第 i 条指令:‘L’(向左移动),‘R’(向右移动),‘U’(向上移动)和 ‘D’(向下移动)。
机器人可以从 s 中的任一第 i 条指令开始执行。它将会逐条执行指令直到 s 的末尾,但在满足下述条件之一时,机器人将会停止:
下一条指令将会导致机器人移动到网格外。
没有指令可以执行。
返回一个长度为 m 的数组 answer ,其中 answer[i] 是机器人从第 i 条指令 开始 ,可以执行的 指令数目 。

分析:这个题没啥好说的,挺简单的,按照题目说法一个一个写就好了,问题是在我写的时候出现了问题:

#以下代码是错误的
class Solution:def executeInstructions(self, n: int, startPos: List[int], s: str) -> List[int]:res=[]for start in range(len(s)):step=0Pos=startPos #应该改为Pos=startPos[:]for i in range(start,len(s)):if s[i]=='L':Pos[1]-=1elif s[i]=='U':Pos[0]-=1elif s[i]=='R':Pos[1]+=1elif s[i]=='D':Pos[0]+=1if 0<=Pos[0]<n and 0<=Pos[1]<n:step+=1else:breakres.append(step)return res

这个代码在执行的过程中,我开始忘记把startPos单独拉出来了,直接在startPos上面进行操作了,但是你想,在第二轮的时候,startPos应该归位重新计算,但是我没记录的情况下,startPos最开始的记录已经没了,所以我就定义了个pos来复制startPos,这样每轮都会能回去读startPos,然后编译之后结果没有任何变化。去debug才发现,startPos竟然都赋值给Pos了,Pos变他竟然还在变,我当时就懵了,chat的解释如下:
在 Python 中,Pos = startPos[:] 和 Pos = startPos 的区别在于如何处理列表的引用。当你写 Pos = startPos 时,Pos 和 startPos 都指向同一个列表对象,这意味着对 Pos 的任何修改都会直接影响到 startPos,因为它们引用的是同一个内存地址。在这种情况下,Pos 和 startPos 是同一个对象的两个引用。任何对 Pos 的修改都会影响到 startPos,反之亦然。所以改成startPos[:]即可。

3.最长优雅子数组

提示
给你一个由 正 整数组成的数组 nums 。
如果 nums 的子数组中位于 不同 位置的每对元素按位 与(AND)运算的结果等于 0 ,则称该子数组为 优雅 子数组。
返回 最长 的优雅子数组的长度。
子数组 是数组中的一个 连续 部分。
注意:长度为 1 的子数组始终视作优雅子数组。
方法一:暴力法

class Solution:def longestNiceSubarray(self, nums: List[int]) -> int:n=len(nums)res=1left=0right=1while 1<=right<len(nums):if right!=left:if self.check(nums[left:right+1]):res=max((right-left+1),res)right+=1                    else:left+=1else:right+=1return resdef check(self,nums:List[int])->bool:n=len(nums)i=0j=0for i in range(len(nums)-1):for j in range(i+1,len(nums)):if nums[j]&nums[i]!=0:breakif nums[j]&nums[i]!=0:breakif nums[j]&nums[i]!=0:return Falseelse:return True

开始写的时候循环套循环,给哥们逻辑套懵了,后来想了下不如把函数调出来。
方法二:滑动窗口
其实这个滑动窗口和我写的没啥太大区别,代码量少了好多的原因是因为,他在判断的时候,用了一个很神奇的东西,判断新加入的这个的办法是直接和按位或进行按位和操作,如果错了就用异或弹出左边的,如果成了就按位或加入,代码如下:

class Solution:def longestNiceSubarray(self, nums: List[int]) -> int:ans=left=or_list=0while right<len(nums):while or_list & nums[right]:or_list^=nums[left]left+=1or_list|=nums[right]ans=max(ans,right-left+1)right+1return ans

题没啥难得,但是很巧就是了。

4.排列和组合

我先手写排列的代码

def A(self,nums:List[int])->List[List[int]]:res=[]def backtrack(path,remaining):if not remaining:res.append(path)returnfor i in range(len(remaining)):backtrack(path+[remaining[i]],remaining[:i]+remaining[i+1:])backtrack([],nums)return res

那么组合的代码如下:

class Solution:def combine(self, nums: List[int], k: int) -> List[List[int]]:res = []def backtrack(path, remaining):if len(path) == k:  # 当当前组合长度达到k时,加入结果集res.append(path)return            for i in range(len(remaining)):# 选择当前元素,递归求剩余部分的组合backtrack(path + [remaining[i]], remaining[i+1:])        backtrack([], nums)return res

可以看到,排列的时候的remaining是剔除了当前值以后的remain,组合的时候,直接i前的全剃了。

5.三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums_long=self.combine(nums,3)n=len(nums_long)res=[]for i in range (n):if nums_long[i][0]+ nums_long[i][1]+ nums_long[i][2]==0:#res.append(nums_long[i])res.append(tuple(sorted(nums_long[i])))res = list(set(res))res = [list(t) for t in res]return resdef combine(self, nums: List[int], k: int) -> List[List[int]]:res = []def backtrack(path, remaining):if len(path) == k:  # 当当前组合长度达到k时,加入结果集res.append(path)returnfor i in range(len(remaining)):# 选择当前元素,递归求剩余部分的组合backtrack(path + [remaining[i]], remaining[i+1:])backtrack([], nums)return res

代码逻辑:
这个是我写的,我先组合,然后判断,其中比较重要的是这个地方res.append(tuple(sorted(nums_long[i])))然后res = list(set(res))再转回列表res = [list(t) for t in res],这步操作用来降重。

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

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

相关文章

《教育科学》

《教育科学》期刊简介 《教育科学》&#xff08;EDUCATION SCIENCE&#xff09;1985年创刊&#xff0c;是由辽宁省教育厅主管、辽宁师范大学主办的教育理论刊物&#xff0c;所属学科为教育学&#xff08;侧重社会科学&#xff09;&#xff0c;在国内外公开发行&#xff08;刊号…

私人诊所|基于SprinBoot+vue的私人诊所管理系统(源码+数据库+文档)

私人诊所管理系统 基于SprinBootvue的私人诊所管理系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员功能实现 患者功能实现 医生功能实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&am…

企业级Mysql 集群技术部署

目录 1.1部署mysql 1.1.1 安装依赖性&#xff1a; 1.1.2 下载并解压源码包 1.1.3 源码编译安装mysql 1.1.4 部署mysql 2.mysql的主从复制 2.1 配置masters 2.2配置slave 2.3 延迟复制 2.4 慢查询日志 2.5并行复制 2.6 原理刨析 2. 7架构缺陷 3.半同步模式 3.1半同…

Charles苹果手机https抓包

1、电脑设置Charles代理端口 1)设置代理端口 Proxy-》Proxying Settings-》HTTP Proxy 设置端口 2)设置监控的代理地址 Proxy-》SSL Proxying Settings 添加Add允许所有地址*.* 2、电脑导入Charles的ssl证书 3、电脑查看Charles的IP地址和端口 4、手机无线wifi配置代理 5、手…

QUIC(Quick UDP Internet Connections)协议

QUIC&#xff08;Quick UDP Internet Connections&#xff09;是一种基于UDP&#xff08;用户数据报协议&#xff09;的多路复用传输协议&#xff0c;由Google开发并在2013年公开。QUIC旨在解决TCP协议在现代网络应用中面临的一些性能瓶颈&#xff0c;特别是减少网络通信的延迟…

如何实现OpenHarmony的OTA升级

OTA简介 随着设备系统日新月异&#xff0c;用户如何及时获取系统的更新&#xff0c;体验新版本带来的新的体验&#xff0c;以及提升系统的稳定性和安全性成为了每个厂商都面临的严峻问题。OTA&#xff08;Over the Air&#xff09;提供对设备远程升级的能力。升级子系统对用户…

工商业光伏的三大新模式

模式一&#xff1a;垫资代建&#xff08;适合第三方投资&#xff09; 合作流程:注册项目公司&#xff0c;备案接入批复&#xff0c;项目公司质押&#xff0c;签订代建合同&#xff0c;进场施工&#xff0c;完成施工进行并网&#xff0c;融资放款&#xff0c;融资款支付代建费用…

归因分析(Attribution)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 归因1.归因是什么广告归因 2.常见的归因模型3.归因依据3.1 安卓方式3.2 IOS方式 归因 在当今纷繁复杂的数字营销环境中&#xff0c;企业面临着如何准确衡量和提升营…

1.7 离散频率

1.7 离散频率 离散时间和采样率 模拟到数字转换器 (ADC) 对连续时间信号进行采样以生成离散时间样本。对于数字信号处理器来说&#xff0c;该信号仅存储在内存中作为一系列数字。因此&#xff0c;采样率 F S F_S FS​ 的知识是数字域中信号处理的关键。 对于时间而言&#…

Java 面试题:TCP重传机制与拥塞控制 --xunznux

文章目录 TCP重传机制1. 超时重传&#xff08;Timeout Retransmission&#xff09;2. 快速重传&#xff08;Fast Retransmission&#xff09;3. 选择性确认&#xff08;Selective Acknowledgment, SACK&#xff09;4. D-SACK(Duplicate sAcK)5. 总结 TCP的拥塞控制机制1. **慢启…

iPhone备忘录不小心删除了怎么办?

在日常使用iPhone的过程中&#xff0c;备忘录作为我们记录重要信息、灵感闪现和日常琐事的小帮手&#xff0c;其重要性不言而喻。然而&#xff0c;有时候因为操作失误或是不小心点击&#xff0c;我们可能会将珍贵的备忘录内容删除&#xff0c;这无疑会让人感到焦虑与不安。但请…

APP长文本内容编辑器功能实现方案

背景 CSDN APP 中原有编辑器页面为纯H5适配&#xff0c;整体用户交互体验差&#xff0c;如何优化APP端编辑器用户体验是我们团队需要思考的问题。下面我们以iOS为例展开讨论。 一、方案调研 我们分析了几款国内内容发布的APP&#xff0c;如知乎、今日头条、简书&#xff0c;…

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题——(共九套)(每套四十题)

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题-题目分享——共九套&#xff08;每套四十题&#xff09; 岗位——芯片与器件设计工程师 岗位意向——数字芯片 真题题目分享&#xff0c;完整版带答案(有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&am…

不再畏惧猫咪浮毛,希喂、安德迈、美的宠物空气净化器性能PK

夏天来了&#xff0c;宠物换毛季加上天气闷热&#xff0c;难消的异味和漫天乱飞的猫毛双重夹击&#xff0c;家里的空气质量直线下降。还是鼻炎患者的我感到非常不适&#xff0c;有股想把家里两只毛孩子逐出家门的冲动。每天不是梳毛就是在吸毛的路上&#xff0c;猫咪们还爱到处…

Redis的内存淘汰策略-noeviction

noeviction 策略简介 noeviction 是 Redis 的默认内存淘汰策略。当 Redis 的内存使用达到配置的最大限制&#xff08;maxmemory&#xff09;时&#xff0c;该策略不会删除任何现有键&#xff0c;而是直接返回错误。这意味着 Redis 将拒绝写操作&#xff08;如 SET、LPUSH 等&a…

若依 Vue3的前后端分离系统管理 创建

RuoYi 若依官方网站 |后台管理系统|权限管理系统|快速开发框架|企业管理系统|开源框架|微服务框架|前后端分离框架|开源后台系统|RuoYi|RuoYi-Vue|RuoYi-Cloud|RuoYi框架|RuoYi开源|RuoYi视频|若依视频|RuoYi开发文档|若依开发文档|Java开源框架|Java|SpringBoot|SrpingBoot2.0…

uniapp 封装uni.login 实现全局调用

封装utils app.vue中 使用globalData 注册 utils 页面中使用方法 定义app 调用方法

win10/11环境变量path误删了如何恢复?

首先&#xff0c;我们可以尝试使用 set 命令来临时设置 PATH&#xff1a; set PATH%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\ 这会在当前的 CMD 会话中设置 PATH。 如果你想永久设置 PATH&#xff0c;我…

【Docker】个人笔记

文章目录 Docker三个基本概念镜像(Image)容器(Container)仓库(Repository) Docker命令基础命令查看版本信息显示详细信息从仓库拉取镜像列出本地存储的镜像删除一个或多个镜像列出所有运行中的容器运行一个新的容器停止一个运行中的容器启动一个已停止的容器重启一个容器删除一…

零知识证明-非对称加解密算法(三)

前言 非对称加解密算法 &#xff0c;就有对称加解密算法 1:对称算法 定义 对称算法&#xff0c;加解密双方使用一个密钥。即加密秘钥和解密秘钥相同。 对称加密又分为&#xff1a;分组加密和流加密 分组加密 分组加密是每次只能处理特定长度的一块数据的一类密码算法&#xff0…