对于数组的处理,是leetcode中一种非常常见的题型。针对数组结构的处理,我自己整理了一些常用的解题思路,便于在面对问题时,迅速思索解题方法。

1.滑窗法
2.双指针
3.构建左右侧双列表
4.利用数据结构

1.滑窗法

滑窗法一般用于处理数组中多个数字之间关系。 一般的结构是,一个for循环嵌套一个while循环,并结合max或者min方法进行判断。 相关的题目见上述链接。

2.双指针

双指针方法一般有两种应用场景:

  • 一种是左右指针,即开始时定义左右指针索引。
    左右指针中又包含两种方式:
    一种是先定义边界后,左加右减。
    这种方式广泛应用于二分排序等操作常见用法:二分法常见应用
l,r = 0,len(list)-1

另一种左右指针是以出现的每各index为中轴,左减右加。这种方式运用比较少,可以用于判定字符串中的回文字符串,见密码截取

  • 另一种是快慢指针,执行逻辑后,两指针一先一后遍历数组,判断是否满足条件。
    常见用法:快慢指针法题目汇总
3.构建左右侧双列表

构建左右列表问题,一般需要考虑数组中三个值的关系,例如比较是否递增,中间值是否最小等等。
因此,我们一般会构建两个和原数组等长的数组,按照数组中的每个元素,分别统计其左侧情况与右侧情况,维护其左侧结果和右侧结果。
典型的题目有:
334. 递增的三元子序列
给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。
思路:
对于一个长度为3的递增序列,我们只需要考虑数组中的每一个数字左侧是否有数字比其小,右侧是否有数字比其大即可。
这样,我们需要维护两个数组,分别记录原数组中每个数字左侧最小值和右侧最大值。随后,分别对比相同索引位置,是否有:左侧<当前<右侧
相应代码如下:

class Solution:def increasingTriplet(self, nums: List[int]) -> bool:if len(nums) < 3:return Falsesmall = [nums[0]]*len(nums)large = [nums[-1]]*len(nums)for i in range(1,len(nums)):small[i] = min(nums[i],small[i-1])for j in range(len(nums)-2,-1,-1):large[j] = max(large[j+1],nums[j])for i in range(len(nums)):if small[i] < nums[i] < large[i]:return Truereturn False

238. 除自身以外数组的乘积
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
思路:
计算除自身外所有元素的乘积,但是题目要求不可以使用除法。因此我们考虑构建两个list分别计算每个元素左侧的乘积和右侧的乘积,随后将相同索引位置的左右list中的元素相乘即可。
进一步,题目要求不使用除了结果之外的额外空间,所以先在结果list上计算所有元素左侧的值,进一步在此基础上乘计算所有元素右侧的值,即为结果。

class Solution:def productExceptSelf(self, nums: List[int]) -> List[int]:res = [1]*len(nums)n = len(nums)r = 1for i in range(1,n):res[i] = res[i-1]*nums[i-1]for j in range(n-1,-1,-1):res[j] = res[j]*rr = r*nums[j]return res

42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
思路:
一种比较直观的逻辑是:只有柱子左右两侧存在更高柱子的位置才能够储水。这样我们需要维护两个list计算每个柱子左侧和右侧最大值。
当然此问题存在不构建list的简便方式,但思路不具备一般性,不容易想到。故这里不多涉及。

class Solution:def trap(self, height: List[int]) -> int:#分别计算左侧和右侧最大值l = [0]r = []for i in range(1,len(height)):tmp1 = max(height[0:i])if tmp1 < height[i]: l.append(0) else: l.append(tmp1)for j in range(len(height)-1):tmp2 = max(height[j+1:])if tmp2 < height[j]: r.append(0) else: r.append(tmp2)r.append(0)print("l is",l)print("r is",r)#累计计算可以的积雨量res = 0for idx in range(len(height)-1):res += max((min(l[idx],r[idx]) - height[idx]),0)return res
4.利用数据结构

一般可以运用的数据结构及方式通常有:

  • 通过字典可以记录每个元素的次数,并结和for循环进行加减计算执行逻辑;
  • 通过enumerate获得数组的索引值;
  • 通过集合去除重复的数字。

常见的题目有:
350. 两个数组的交集 II
给定两个数组,编写一个函数来计算它们的交集。
思路:
通过一个字典记录数组1中每个元素的出现次数,遍历数组2,如果2中的元素出现在1中,则字典相应的计数减1.

class Solution:def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:if len(nums1) == 0 or len(nums2) == 0:return []map1 = {}res = []for i in nums1:map1[i] = map1.setdefault(i,0) + 1for j in nums2:if j in map1.keys() and map1[j] > 0:map1[j] -= 1res.append(j)return res

leetcode中数组问题常用的处理方式相关推荐

  1. java定义数组_java中数组的三种定义方式_java中数组的定义及使用方法(推荐)...

    java中数组的三种定义方式 java中,数组是一种很常用的工具,今天我们来说说数组怎么定义 [java] view plain copy /** * 数组的三种定义方法 * 1.数组类型[] 数组名 ...

  2. js中数组的几种循环方式

    js中数组的几种循环方式 for循环最基本的循环方式,不多说.这种最基本的循环才是速度最快的,效率最高的. for(var i = 0;i<5;i++){console.log(i) } for ...

  3. java类初始数组_java中数组初始化的三种方式是什么

    java中数组初始化的三种方式是:1.静态初始化,如[int a[] = {2, 0, 1, 9, 2020}]:2.动态初始化,如[int[] c = new int[4]]:3.默认初始化,如[i ...

  4. lodash中数组删除常用的api

    lodash 中数组删除常用的 api 1.pull 说明: 移除数组 array 中所有和给定值相等的元素,使用 SameValueZero 进行全等比. 注意: 和 without 方法不同,这个 ...

  5. java中数组遍历的三种方式

    使用显示数组 for,for-each,和toString 题目描述 1.for循环遍历 程序: 运行结果: 2.foreach语句遍历 语法格式: 注: 运行结果: 程序: 运行结果: 3.Arra ...

  6. php中数组遍历的四种方式

    首先要讲一点的是:PHP中的数组与C/C++中的数组不同. 它是基于键值对结构的hash表来实现的(存在key/value的概念).有点类似于python和lua中的dictionary. 在没有显示 ...

  7. ruby中数组的常用函数

    在程序中定义一个数组 在程序中定义一个数组,因为我们在下面说明. fruits = ["apple", "orange", "lemon"] ...

  8. c语言long型数组怎么初始化,C语言中数组初始化的三种方式是什么?

    C语言中,数组初始化的方式主要有三种: 1.声明时,使用 {0} 初始化: 2.使用memset: 3.用for循环赋值. 那么,这三种方法的原理以及效率如何呢? 请看下面的测试代码:#define ...

  9. html中数组的定义,javascript中数组定义的几种方式是什么?

    javascript中怎么定义数组?下面本篇文章给大家介绍一下javascript数组定义的几种方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 1.什么是数组 数组就是一组数据 ...

最新文章

  1. css3 3d变换和动画——回顾
  2. 重启jboss出现问题:端口被占用
  3. 全排列—leetcode46
  4. Caffe阅读代码并修改
  5. NIPS2018 Workshop一览
  6. [jQuery基础] jQuery对象 -- CSS相关
  7. linux重启后mysql无法启动_Linux重启后MySQL数据库文件全部丢失MySQL无法启动
  8. POJ 1050 To the Max (最大子矩阵和)
  9. 如何通过SCJP考试(含真题分析和考点)
  10. Android 硬件加速
  11. 声明圆锥体类,实现Area和Volume接口,计算表面积和体积,按体积比较大小。
  12. Typora图片上传失败问题
  13. 微商铺php,帮助中心-微商铺的功能详解
  14. 《游戏学习》| 射击类小游戏 html5 打野鸭子
  15. linux设备驱动读书笔记
  16. Android工具类blankj
  17. 软考系统设计架构师经验与教训分享
  18. python 解码js escape,encodeURI
  19. 吉林大学计算机科学杨凤杰,吉林大学计算机科学与技术学院 [2005-04] 总第36期...
  20. WIFI6模块 802.11ac/ax AP6275S

热门文章

  1. 使用javascript制作 滚动字幕及时钟
  2. 请写代码校验第二代身份证号码有效性。程序接收一个18位的身份证号码和性别,根据以下规则输出号码是有效还是无效。
  3. Prometheus原理详解
  4. word/ppt中如何插入11以上带圆圈的数字序号
  5. 【平面解析几何】直线方程的表示形式
  6. Hive 外部表的练习(多表关联查询,以及分组,子查询)
  7. c语言Int16_t 什么意思,__IO uint16_t 是什么意思,在定义参数时为什么不直接写成 uint16...
  8. VC 6.0在链接Link时经常卡死问题
  9. 人民币大写与数字互转
  10. 阿里云 Java发布SpringBoot项目,使用邮件服务发送失败原因整理