LeetCode刷题--数组

之前按照顺序来做题,总是一天一道还卡死了,后来求教了师兄

才知道由简到难,按照这样的顺序做

推荐了我代码随想录,跟着那个顺序刷题。

这两天将这里的数组做完了,对其进行一个总结梳理:

题目1:二分查找(704)
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

思路:

        每一次都对数组的中位数进行选取比较,可能会遇到一下的情况:

  1. 大于目标值,即目标值会出现在中位数的左侧,就将此时的区间右边界变为中位数的上一位
  2. 小于目标值,即目标值会出现在中位数的右侧,就将此时区间的左边界变为中位数的下一位
  3. 等于目标值,直接返回此时的下标

当区间满足,在此区间内有值,即合法的时候,我们按照这个顺序一直执行即可。 

题目2:搜索插入位置(35)

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

思路:

        出现对时间复杂度要求是log,首先想到二分法

   本题查找部分可以参照题目1

   当无法找到的时候,此时的区间边界左边界是大于右边界的,此时可以发现我们所要插入的数值位于此时右边界的下一位,返回该位即可。

题目3:在排序数组中查找元素的第一个和最后一个位置(34)

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

思路:

        一般查找思路可以按照上面的来

        我这里想着,查找到一个符合的值之后,定义两个临时变量,i--和j++,直到找到和目标值不一样的下标,最后的边界就是此时的i+1和j-1(因为最后一次的判断不满足条件的时候执行了一次i--和j++),但我不知道这样会不会时间复杂度变为O(n)

   可以按照左右边界分开查找

   左边界,找到>=目标值的最右边的元素

   右边界,找到<=目标值的的最左边元素

题目4:移除元素(27)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路:

        因为额外空间只可以使用一个,将其定位数组变化后的长度

        起始时,该值位数组原长。

        利用for遍历每一位数值元素,当出现某一位的值和目标值相等,此元素后面的元素一次前移一位

        这里需要注意,找到i时,移动使用for语句,要使得j=i+1,因为用j=i的话,每一次移动的最后一位是无法填补元素的,会报错

        每删减一次元素,此时的长度就会减去1

        并且删减掉第i个位置,移动之后第i个位置补上了元素,在此时也需要i--

题目5:有序数组的平方(977)

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

思路:

        一开始想着找0,但无法保证每一个数组都有零

        面对这样的数组,我们无法从中间取值来定界,只能从两边入手

        可以求边界平方最高的,将其存入数组

        若取的是左边界,存了该数之后,左边界加一

        若取的是右边界,存了该数之后,右边界减一

        此时存入数组的是递减的排序,可以使用reverse(v.begin(),v.end())进行翻转

题目5:长度最小的子数组(209)

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

思路一:

可以做哈希表,两个都是int类型,哈希表的关键字是每个元素的下标,对应的键值是该下标所满足的最小长度,若是没有满足条件的,该下标为0

将哈希表做好之后,若是键值都是0,则返回0

若有不为0的元素,进行大小比较,返回最小值键值对应的关键字和关键字+键值

思路二:

用一个动态窗口,来储存满足条件的最小数组,定义长度是一个INT32_MAX

第一次,从下标为0开始取长度最小的数组,记录长度,取此时长度和定义长度的最小值

第二次,下标变为1取长度最小的数组,记录长度,取此时长度和定义长度的最小值

.............

因为我们只需要返回长度,每一次取最小的长度即可,没有要求返回该位置,所以可以使用一个for语句,在for中求和,当求得的和大于等于目标值之后,记录长度

减去此时存储的第一项,for中再加上满足条件的值,每一次都只记录长度

有点类似二分法的左右边界,只是右边界是通过for定义,左边界是满足条件之后+1

题目6:螺旋矩阵 II(59)

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

思路:
将其进行问题拆分

为了规律,每一次的插入元素,不论是行还是列,其所属的最后一个元素都不进行插入,留给下一个部分

比如:

112
452
433

3*3的矩阵中,按照1-2-3-4-5的插入数据,我们可以得到规律操作

若是按照

111
442
332

这种计算方法的话,需要根据具体情况具体确定行规律和列规律,对于较小的数字还好操作,数字一旦大了,就很难操作了

每一次操作,都相当于是外包围了一圈,操作了两行和两列,那么操作的循环次数就是n/2

第二次操作的时候,行和列的起始都各加一,他们在此次循环中所需要操作行/列就是1----n-1

...........

n是奇数的时候,最中间的一项自定义即可

题目7:螺旋矩阵(54)

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

思路:

参照构造螺旋矩阵的方法,逆推

m行n列

1111111112
5562
499102
812111162
8772
4333333333

m和n中最小值,若最小值是偶数,则循环圈数为最小值除以2,若是奇数,除以2之后的值加一

最后再单独处理m=n且m为奇数的元素存入最后一个

最后:
在数组这些题中,我逐渐发现

首先掌握方法:二分查找和快慢指针的方法

面对不一样的题,具体先分析思路,有了想法,可以套这两个思路进行求解

面对难题,可以自己先试着取简单的例子,看有没有什么方法,最后总结技巧

其实算法就是前人精炼处理的经验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值