- 菜 35. 搜索插入位置(D-)
- 中 31. 下一个排列(B+)33. 搜索旋转排序数组(B-)34. 在排序数组中查找元素的第一个和最后一个位置(C)39. 组合总和(A-中二) 40. 组合总和 II(A-)
- 危 40. 组合总和 II(A-)
总结:本来以为数组题很简单,结果碰到好多问题。引出回溯法,和堆排序。做个专题练习一下。任重道远啊,差的太多了。
31. 下一个排列(B+)
分析:一道数组题竟然卡了好久。为什么没有思路呢。关键在于,题意理解,还有细化问题。倒叙从小到大,比较。找到前一个大于后一个,这时交换。再从后往前遍历,确保交换的是最小一个大于i-1的数。然后将i-1之后的所有数从小到大排序。也就是倒序。
转换思维一时间没有转换过来。感觉又误入歧途了。
1 | class Solution: |
第二种。
1 | class Solution: |
33. 搜索旋转排序数组(B-)
分析:注意要求!你的算法时间复杂度必须是 O(log n) 级别。想到二分法。
先膜拜一下大神的代码
在用
for..in..
迭代对象时,如果对象没有实现__iter__
__next__
迭代器协议,Python的解释器就会去寻找__getitem__
来迭代对象,如果连__getitem__
都没有定义,这解释器就会报对象不是迭代器的错误.实例调用__class__属性时会指向该实例对应的类,然后可以再去调用其它类属性,毕竟类属性还是由类调用会比较好
bisect 其目的在于查找该数值将会插入的位置并返回,而不会插入。
bisect_left 和 bisect_right 函数,该函数用入处理将会插入重复数值的情况,返回将会插入的位置:
1 | class Solution: |
第二种
一看到题目要求时间复杂度O(log n) 级别,就应该想到应该是用二分法了。但这题难就难在它并不是一个严格意义上的递增序列,而是两段递增序列组成的。那第一步就应该先用二分法找出分界点。然后对两段用二分法查找出index。相当于用了两次二分法
1 | class Solution: |
第三种。直接对target位置进行细分比较。
1 | class Solution: |
34. 在排序数组中查找元素的第一个和最后一个位置(C)
分析:你的算法时间复杂度必须是 O(log n) 级别。
经过上一题的洗礼,这道题就显得简单很多了。先二分,找到元素。然后,往前往后循环找到第一个,和最后一个位置。
1 | class Solution: |
35. 搜索插入位置(D-)
分析:很简单的一道题。二分法并没有快反而变慢了,大概是用例问题。
1 | class Solution: |
二分法
1 | class Solution: |
39. 组合总和(A-)中二
分析:想用dp做但是感觉不太对。看了别人的答案,觉得步骤很巧妙。这种自迭代加上过滤,匿名函数综合运用。有点厉害。
1 | class Solution: |
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
第二种。
分支界限法,使用递归函数做到自然剪枝
1 | class Solution: |
第三种
1 | class Solution: |
40. 组合总和 II(A-)
分析:和上一题差不多的方法。
回溯法。不是很清楚。明天开个专题。训练一下。答案贴出来,暂且不表。
1 | class Solution: |
第二种。用时短了不少。
1 | class Solution: |
41. 缺失的第一个正数(B+)
分析:
注意:你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
(1)首先把数组内,范围在 ( 0, n ] 元素x,放到nums[x - 1],类似桶排序中的找位置。
(2)放好之后,进行遍历,找第一个 i + 1 != nums[i],返回 i + 1,就是结果,如果没有就返回 n + 1。
(3)所以,最小的正整数很重要,如果是第一个没出现的数,就不能这样做了。
桶排序~
1 | class Solution: |
第二种。取巧,不过是不是不满足常数空间。
1 | class Solution: |
第三种 ~~ 二。plus
1 |