栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Leetcode刷题总结——数组

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Leetcode刷题总结——数组

数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

数组的元素是不能删的,只能覆盖。

一、二分查找

这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件。

二分法逻辑比较简单,但容易写乱,比如是while(left

写二分法,区间的定义一般可以分为两种,左闭右闭[left,right],或者左闭右开[left,right)。

(以下解答均基于题目704)

二分法第一种写法

第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] 。

区间的定义这就决定了二分法的应该如何写,因为定义target在[left, right]区间,所以有如下两点:

1)while(left<=right)要使用<=,因为left==right是有意义的,所以使用<=;

2)if(nums[mid]>target) right要赋值为mid-1,因为当前这个nums[mid]一定不是target,那么接下来要查找的左区间结束下标位置就是mid-1。

二分法第二种写法

如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。

有如下两点:

1)while(left

2)if(nums[mid]>target) right更新为mid,因为当前这个nums[mid]不等于target,去左区间继续寻找,而寻找的左区间是左闭右开区间,所以right更新为mid,即下一个查询区间不会去比较nums[mid]。

1、

法一:

法二:

 

2、

 3、

寻找target在数组里的左右边界,有如下三种情况:

  • 情况一:target 在数组范围的右边或者左边,例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}
  • 情况二:target 在数组范围中,且数组中不存在target,例如数组{3,6,7},target为5,此时应该返回{-1, -1}
  • 情况三:target 在数组范围中,且数组中存在target,例如数组{3,6,7},target为6,此时应该返回{1, 1}

所以可以写两个二分去分别寻找左右边界。

寻找右边界:

 寻找左边界:

最终代码:

4、 

 二、移/除元素

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

1、

双指针法(快慢指针法)

2、 

 

 

3、

 

4、

方法一:(使用栈的思路)栈适用于做匹配问题

 方法二:双指针

 

 5、

方法一:(sort排序 时间复杂度为 O(nlogn))

方法二:(归并排序后双指针)

负数部分,平方以后单调递减,大于等于0的部分,平方以后单调递增

首先找到负数结束的位置记为 neg,使用两个指针分别指向位置 neg 和 neg+1,每次比较两个指针对应的数,选择较小的那个放入答案并移动指针。当某一指针移至边界时,将另一指针还未遍历到的数依次放入答案。

方法三:直接双指针

使用两个指针分别指向位置 00 和 n-1n−1,每次比较两个指针对应的数,选择较大的那个逆序放入答案并移动指针。这种方法无需处理某一指针移动至边界的情况。

 三、关于数组中的连续问题(滑动窗口)

1、

方法一:暴力法

方法二:滑动窗口

2、

题目可以理解为求只包含两种元素的最长连续子序列

 

 3、

解题思路:

1)用一个哈希表mpt先存放字符串t中的字符

2)定义两个指针 start和end,start指针用于收缩窗口,end指针用于延伸窗口,区间[start,end]表示当前滑动窗口。首先让start,end指针都指向字符串s开头,然后枚举整个字符串s,在枚举过程中,不断增加end,使滑动窗口增大。在窗口变大的同时,需要记录加入的字符数,即mps[s[end]]++

3)对于新加入的字符s[start],如果mps[s[start]]<=mpt[s[start]],说明当前新加入的字符s[start]是必须的,而且未达到字符串t所要求的数量。其次我们还需要事先定义一个cnt变量,cnt维护的是s字符串[start,end]区间中满足t字符串的元素的个数,记录相对字符的总数。如果新加入的字符s[start]必需,则cnt++

4)向右扩展滑动窗口的同时还需要收缩窗口,当mps[s[start]]>mpt[s[start]]时,说明mps哈希表中s[start]的数量多于mpt哈希表中s[start]的数量,此时我们就需要向右收缩滑动窗口,mps[s[start]]--并使,start++

5)当cnt==t.size()时,说明此时滑动窗口包含字符串t的全部字符。重复上述过程找到最小窗口即可

四、螺旋矩阵问题

主要遵循 循环不变量问题

1、

 2、

方法一:

初始位置为矩阵的左上角,初始方向是向右,当路径超出界限或者进入之前已经访问过的位置时,顺时针旋转,进入下一个方向。

因此需要引入一个与输入矩阵大小相同的辅助矩阵visited,记录每个位置是否被访问过。

由于矩阵中的每个元素都被访问一次,因此路径的长度即为矩阵中的元素数量,当路径的长度达到矩阵中的元素数量时即为完整路径,将该路径返回。

 方法二:

一层一层向内圈遍历

 

(第二种更清晰)

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/858219.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号