【Leetcode】top 100 双指针

283 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

分析:双指针初始为0;left指针找零值,right指针找非零值;由于需要保持非零元素的相对顺序,right只能在left的右边寻找(这里不要将right=left+1,会造成right的回退)结束循环条件 right < len(nums);

class Solution(object):
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        i, j, m = 0, 0, len(nums)
        while j < m:   
            if nums[i] == 0:
                while j < m: 
                    if nums[j] != 0:  #j指向i后第一个非零值
                        nums[i], nums[j] = nums[j], nums[i]
                        break                  
                    j+=1    
            i, j = i+1, j+1
        return nums
11 盛最多的水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。

分析:双指针指向一头一尾,使宽度最大;

在移动指针时,宽度减小,只能通过用更大的高度值替换现有较小的高度值来增加水量;

当height[left] < height[right]时,移动left指针,若找到比height[left]更大的元素时,更新水量和left指针;

                                                                         若找不到比height[left]更大的元素时,当前水量为最大;

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        out = min(height[0], height[-1]) * (len(height) - 1)
        left, right = 0, len(height) - 1
        while left < right:
            if height[left] < height[right]:           #移动左侧
                idx = left+1
                while idx < right:
                    if height[idx] > height[left]:     #可能需要更新
                        out = max(out, min(height[idx],height[right]) * (right-idx))
                        break
                    idx+=1
                left = idx
            else:
                idx = right-1
                while idx > left:
                    if height[idx] > height[right]:     #可能需要更新
                        out = max(out, min(height[idx],height[left]) * (idx-left))   
                        break
                    idx-=1
                right = idx
        return out

官方思路:不在乎height[idx] 和 height[left] 的大小,反正left指针需要更新到height[left] > height[right]

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        left, right, out = 0, len(height) - 1, 0
        while left < right:
            if height[left] < height[right]:           
                out = max(out, height[left] * (right-left))
                left += 1
            else:
                out = max(out, height[right] * (right-left))   
                right -= 1
        return out
  • 相当于用增加的idx内存换out更新次数的减少;

  • 还有一个提前结束的条件: out >= max(height) * (right - left)   因为再更新也无法找到更大的高度值;
15 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

分析:当固定nums[i]时,该问题转为在nums[i:]中找到两数之和为-nums[i],可以搭配hashmap;

          去重处理...本来想用set的自动去重,但list不满足可哈希条件,无法实现set(list),这里list为二维或更高维列表...还是选择用hashmap:键用tuple,这里需要搭配排序使三元组中元素的相对位置一致;

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        out = {}
        for i in range(len(nums)-1):
            hashmap = {}
            for j, num in enumerate(nums[i+1:]):
                if -nums[i]-num in hashmap:
                    outt = [nums[i], num, -nums[i]-num]
                    outt.sort()
                    out[tuple(outt)] = j
                else:
                    hashmap[num] = j 
        
        return list(out)

#改变排序位置
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        out = {}
        nums.sort()
        for i in range(len(nums)-1):
            hashmap = {}
            for j, num in enumerate(nums[i+1:]):
                if -nums[i]-num in hashmap:
                    out[tuple([nums[i], num, -nums[i]-num])] = j
                else:
                    hashmap[num] = j 
        
        return list(out)

#时间复杂度过高O(nlogn)+O(n^2)+O(n)?

官方思路:同样先进行排序,再用一层循环固定一个值,将其转换为两数之和,这里要求固定的值不出现重复;在两数之和问题上使用一头一尾双指针,因为b+c=-a,随着b的增大c必然要减小,这里要求b的值不出现重复,自然c的值就不会出现重复

优化点:提前结束条件:最小三个值的和大于0或最大三个值的和小于零

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        if sum(nums[0:3])>0 or sum(nums[-3:])<0: return []

        out = []
        for i in range(len(nums)):
            if i>0 and nums[i] == nums[i-1]:continue               #nums[i]不重复
            left, right = i+1, len(nums)-1
            while left<right:
                if left>i+1 and nums[left]==nums[left-1]:          #nums[j]不重复
                    left+=1
                    continue
                if nums[left]+nums[right]<-nums[i]:left+=1
                elif nums[left]+nums[right]>-nums[i]:right-=1
                else:
                    out.append([nums[i],nums[left],nums[right]])   
                    left, right = left+1, right-1         

        return out
 42 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

分析:用减法更方便计算

          以 [a,b,c,d,e]为例:固定a时,要在[b,c,d,e]中找到>=a的第一个值(假设是c),故a-c蓄水ax1-b—ac宽度好计算,但需要用变量储存ac中间的体积;

                                         固定c时,要在[d,e]中找到>=c的第一个值(假设不存在),故c无法作为较小的壁蓄水;改判断c作为较大的壁蓄水:在向右遍历时添加一个指向[d,e]第一个最大值的指针mid,同时也需要用变量储存c-mid中间的体积;

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        left, mid, right = 0, [1,0], [1,0]
        out = 0
        while left < len(height)-1:
            flag = 1
            while right[0] < len(height):
                if height[right[0]] >= height[left]:     #找到>=height[left]的值
                    out += height[left]*(right[0]-left-1)-right[1]
                    flag = 0
                    break
                else:
                    if height[right[0]] > height[mid[0]]:mid = right[:]           #mid更新
                    right[0], right[1] = right[0]+1, right[1]+height[right[0]]
                
            if flag:                                    #遍历找不到>=height[left]的值
                out += height[mid[0]]*(mid[0]-left-1)-mid[1]
                left = mid[0]
                mid, right = [left+1, 0], [left+1, 0]
            else:
                left = right[0]
                mid, right = [left+1, 0], [left+1, 0]

        return out

#时间复杂度太大,巨长的案例会超出时间限制

官方思路

思路一:动态规划:对于下标 i 能接住的雨水为左侧最大值和右侧最大值的最小值减去 height[i]

用leftmax[i]代表[:i]的最大值,用rightmax[i]代表[i:]的最大值,

递推式:leftmax[i] = max( leftmax[i-1], height[i] )  

              rightmax[i] = max( rightmax[i+1], height[i] )     这里发现rightmax适合倒序遍历

边界条件:leftmax[0] = height[0]

                  rightmax[-1] = height[-1] 

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        leftmax, rightmax = [height[0]], [height[-1]]
        for i in range(1,len(height)):
            leftmax.append(max(leftmax[i-1], height[i]))
            rightmax.insert(0, max(rightmax[-i], height[-i-1]))
        #左右遍历合并

        out = 0
        for i in range(len(height)):
            out += min(leftmax[i], rightmax[i]) - height[i]

        return out
#return sum(min(leftmax[i], rightmax[i])-height[i] for i in range(n))

思路二:双指针:使用双指针来缩减动态规划中的空间开销;

因为对于下标 i 能接住的雨水为左侧最大值和右侧最大值的最小值减去 height[i],所以已知左侧最大值和右侧最大值的大小关系时,该式可简化,对应更新left/right指针的下标即可;

class Solution:
    def trap(self, height):
        out = 0
        left, right = 0, len(height) - 1
        leftmax = rightmax = 0

        while left < right:
            leftmax = max(leftmax, height[left])
            rightmax = max(rightmax, height[right])
            if leftmax < rightmax:                  
                out += leftmax - height[left]
                left += 1
            else:
                out += rightmax - height[right]
                right -= 1
        
        return out

思路三:两个方向计算当前最高值围成的有效面积,该面积=矩形面积+柱子面积+积水面积

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        # 同时从左往右和从右往左计算有效面积
        s1, s2 = 0, 0
        max1, max2 = 0, 0
        for i in range(len(height)):
            if height[i] > max1:
                max1 = height[i]
            if height[-i-1] > max2:
                max2 = height[-i-1]
            s1 += max1
            s2 += max2
        # 积水面积 = S1 + S2 - 矩形面积 - 柱子面积
        res = s1 + s2 - max1 * len(height) - sum(height)
        return res

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

02-组件化编程与Vu额 Click脚手架

1.Vue组件化编程(只有1个数字是一级标题) 1.1 模块与组件、模块化与组件化(两个数字组成是二级标题) 1.1.1模块(三个数字是三级标题 依次类推) 理解&#xff1a;向外提供特定功能的 js 程序&#xff0c;一般就是一个 js 文件为什么&#xff1a;js 文件很多很复杂作用&#xf…

【性能测试】性能测试各知识第1篇:性能测试大纲【附代码文档】

性能测试完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;性能测试大纲。。。。。。。。。。。。。。 全套笔记资料代码移步&#xff1a; 前往gitee仓库查看 感兴趣的小伙伴可以自取哦&#xff0c;欢迎大家点赞转发~ 性能测试大纲 |序号|阶段|概述| |--…

【C++】三大特性之继承

1 继承的概念及定义 1.1 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展、增加功能&#xff0c;这样产生新的类&#xff0c;称派生类&#xff08;或子类&#xff09;。而被继承的…

【NR 定位】3GPP NR Positioning 5G定位标准解读(九)-增强的小区ID定位

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

云服务器python版本冲突解决(awd平台搭建)

文章目录 yum和apt-getdockerpython环境问题 大家在使用python时&#xff0c;难免会使用他人的代码&#xff0c;自己是python3&#xff0c;而别人的是python2.我们直接运行会报错(比如print函数括号的问题)。但是去修改代码又很麻烦。这里给大家推荐conda。我以我搭建awd平台为…

toB开发范式

前言 B端开发&#xff0c;也被称为后台开发或者企业级开发&#xff0c;是针对企业或者组织的业务需求进行的软件开发。在 B 端开发中&#xff0c;我们通常关注的是系统的功能性、稳定性、可扩展性以及安全性&#xff0c;从面向过程编程 -> 面向对象编程 组合式编程 以下是…

【谈一谈】并发_Synchronized

Synchronized 又到周末了,最近的话(有点子小日子不好过,哈哈哈!~)但是,我还是报之以歌哈哈哈 本次写关于并发_Synchronized的优化以及底层实现原理 说说心里话~其实是非常的累,原因应该怎么说呢?我发现自己在如今的这家公司,我处于一种活多钱少以及关键现在给的或自己不想干,因…

新版Android Studio火烈鸟 在新建项目工程时 无法选java的语言模板解决方法

前言 最近下载最新版androidstudio时 发现不能勾选java语言模板了 如果快速点击下一步 新建项目 默认是kotlin语言模板 这可能和google主推kt语言有关 勾选1 如图所示 如果勾选 No Activity 这个模板 是可以选java语言模板的 但是里面没有默认的Activity 勾选2 和以前的用法…

关于安卓ZXing条码识别(一)引入源码

背景 从0-1引入安卓zxing&#xff0c;实现条码识别 环境 win10 as4 jdk8 引入 首先&#xff0c;官方网站&#xff0c;就是源码。链接 选择你要引入的分支&#xff0c;这里博主选择的是最近更新的分支&#xff0c;如下图&#xff1a; 上图中&#xff0c;1和2都需要引入&am…

车载诊断协议DoIP系列 —— 诊断报文和诊断报文应答传输层安全(TLS)

车载诊断协议DoIP系列 —— 诊断报文和诊断报文应答&传输层安全(TLS) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎…

2021年江苏省职业院校技能大赛高职组 “信息安全管理与评估”赛项任务书

2021年江苏省职业院校技能大赛高职组 “信息安全管理与评估”赛项任务书 一、赛项时间&#xff1a;二、赛项信息三、竞赛内容&#xff1a;第一阶段任务书&#xff08;300分&#xff09;任务1&#xff1a;网络平台搭建&#xff08;60分&#xff09;任务2&#xff1a;网络安全设备…

23 经典卷积神经网络 LeNet【李沐动手学深度学习v2课程笔记】 (备注:提到如何把代码从CPU改到在GPU上使用)

目录 1. LeNet 2. 实现代码 3. 模型训练 4. 小结 本节将介绍LeNet&#xff0c;它是最早发布的卷积神经网络之一&#xff0c;因其在计算机视觉任务中的高效性能而受到广泛关注。 这个模型是由AT&T贝尔实验室的研究员Yann LeCun在1989年提出的&#xff08;并以其命名&…

第十九天-分布式爬虫scrapy-redis

1.scrapy-redis介绍 1.scrapy框架程 2.分布式爬虫将多个主机组合起乱来&#xff0c;完成一个爬虫任务&#xff0c;快速高效的提高爬虫效率 3.scrapy-redis框架&#xff0c; 优点&#xff1a;1.加快项目的运行速度2.单节点不稳定不影响整个系统的稳定性 3.断点续爬 缺点&…

基于C++和Qt Creator实现的仿制网易云音乐播放器

目录 总体介绍开发环境技术介绍项目目录项目介绍特殊说明Gitee地址 总体介绍 仿照网易云播放器界面实现&#xff0c;目的在于锻炼C编程能力&#xff0c;熟练掌握Qt Creator各种组件的使用及样式设置、界面布局、QtPlugin技术、QXml读写XML文件方法、Qss文件的编写及使用等。 …

【笔记】全国大学生GIS应用技能大赛练习总结

该总结笔记为小组成员在练习完毕了历届题目后自我总结的结果&#xff0c;如有不足之处可以在评论区提出&#xff0c;排版较乱往谅解 绘制带空洞的面要素&#xff1a; 法一&#xff1a; 1、矢量化整个区域。2、矢量化空洞区域。3、将矢量化空洞区域进行合并&#xff08;编辑器…

【MySql学习之路】window环境下MySql安装和安装过程中出现的问题

environment:windows software:mysql 本文主要分享mysql关系型数据库在干净的环境下,第一次安装以及在安装过程中出现的常见问题和解决方法。目前官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的。很多人下了zip格式的解压发现没有setup.exe,面对一堆文件无从…

HTTPS如何保证数据传输的安全性 以及CA签发证书验签

暴力输出&#xff1a; 越看会越深入&#xff0c;睡前难以想通&#xff0c;后深入研究。得之。 有问题 请留言。 ----------追求内心的富足与平和。日行一善。 亓苏姑娘

面试经典150题【61-70】

文章目录 面试经典150题【61-70】61.旋转链表86.分隔链表104. 二叉树的最大深度100.相同的树226.翻转二叉树101.对称二叉树105.从前序与中序遍历序列构造二叉树106.从后序和中序遍历序列构造二叉树117.填充每个节点的下一个右侧节点指针II114.二叉树展开为链表 面试经典150题【…

【软考】图的遍历

目录 1. 概念2. 深度优先搜索2.1 说明2.2 步骤 3. 深度优先搜索例子3.1 无向图3.2 代码示例3.3 结果示例3.4 过程 4. 广度优先搜索4.1 说明4.2 步骤 5. 广度优先搜索例子5.1 无向图5.2 代码示例5.3 结果示例5.4 过程5.5 例题5.5.1 题目1 1. 概念 1.图的遍历是指从某个顶点出发…

Day32-计算机基础2

Day32-计算机基础2 1. 什么是网络拓扑(Network Topology)&#xff1f;2. 网络拓扑3种经典模型2.1 网络拓扑结构-总线型2.2 网络拓扑结构-环形2.3 星型&#xff1a;2.4 网络拓扑结构总结 3.OSI网络模型概念*****3.1 OSI的概念&#xff1a;open system interconnect 开放系统互连…