数组
二分查找(双指针)
闭区间比较好分析
开区间就是low一定小于high
更新策略也不同 注意右边是开是取不到的
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
low, high = 0, len(nums)-1
while low <= high: #<=
mid = (high - low)//2 + low
if (nums[mid] == target):
return mid
else:
if target > nums[mid]:
low = mid + 1 # 忘记+1
else:
high = mid - 1 #忘记-1
return -1
Solution().search(nums=[-1,0,3,5,9,12], target=9) #要self 说明要实例化 不要忘记Solution后面的()
还有特殊情况没有考虑!
这不是特殊情况 这是你下表多减了一个1
移除元素 (双指针)
如果对参数重新赋值则不会对原来参数有影响
这个问题很奇怪
不奇怪,因为没有指向那个列表的地址去引用,而是等于一个新的列表
python 不支持a++. 要用a+=1
代码
优化双指针
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
length = len(nums)
p1, p2 = 0, length-1
while p2 >= p1:
if nums[p1] == val:
nums[p1] = nums[p2]
p2-=1
else:
p1+=1
return p1
有序数组的平方
likou
要记得[]毕竟叫做列表解析式
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
length = len(nums)
new_nums = [0]*length #要记得创建存储空间. 如何创建指定长度
i, j = 0, length-1
count = 1
while i<=j:
if abs(nums[i]) > abs(nums[j]):
new_nums[length - count] = nums[i]**2
i+=1
count+=1
else:
new_nums[length - count] = nums[j]**2
j-=1
count+=1
return new_nums
长度最小子数组
涉及连续子数组,元素非负的问题,我们通常有两种思路:一是滑动窗口、二是前缀和。
元素非负 元素非负所以有前缀和思想 元素非负所以有滑动窗口思想,即窗口缩小则和变小 窗口伸长则和变大
lk
暴力解法
python 会超出时间
我这个方法也不够好
1.
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
length = len(nums)
new_num = [0] * length
for i in range(length):
result = 0
j = 1
while result < target:
if (i + j - 1) <= (length-1):
result += nums[i + j - 1]
if result >= target:#>= 并且之前没有加这个判断
break
else:
j += 1
else:
j = length+10
break
new_num[i] = j
if min(new_num) == length+10:
return 0
else:
return min(new_num)
bisect.bisect_left函数返回这样的位置:位置左侧值都小于x, 位置右侧大于等于x
bisect.bisect_left函数返回这样的位置:位置左侧值都小于等于x, 位置右侧大于x
总结 有相等的话 相等的在左边或者右边
没有相等的就都是一个位置
前缀和记住了就是比原来数组多一个 因为第一个元素的前缀和是0!
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
""" 最小子序列长度就是数组长度"""
length = len(nums)
""" sum是前缀和多一个!"""
sums = [0]
ans = length + 1
for i in range(length):
sums.append(sums[-1] + nums[i]) #前缀和比原数组多一位
"""表示第几个数字 1开始的到长度len结束"""
for i in range(1, length + 1):
# 第i个数字前缀和加上s 目的是找到从它本身开始到sums结束中的某一位
s = target + sums[i - 1]
# 在整个sums查找位置 数据范围是下表i 到len
bound = bisect.bisect_left(sums, s)
if bound != len(sums): #len +1
ans = min(ans, bound - (i - 1))
if ans == length + 1:
return 0
else:
return ans
滑动窗口
可以直接记录窗口内的数字 千万不要每次都重复计算总和 很傻
遇到问题
j会越界
sum -= num[i]
会导致count多一个
错误代码如下
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
length = len(nums)
i, j = -1, -1 #这里错了
sum = 0
count = 0
ans = length + 1
while j < length:
sum += nums[j]
count += 1
if sum < target:
j += 1
else:
while sum > target:
sum -= nums[i]
i += 1
count -= 1 #这里sum其实已经小于target怎么办 增加一个判断
if count < ans:
ans = count
if ans == length + 1:
return 0
else:
return ans
上面是错误代码 还有越界错误
count可以用双指针来算
双指针更新代码:
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
length = len(nums)
i, j = 0, 0 #初始条件不清晰
sum = 0
ans = length + 1
while j < length:
sum += nums[j]
if sum < target:
j += 1
else:
while sum >= target:
ans = min(ans, j-i+1) #先后顺序不清晰
sum -= nums[i]
i += 1
j += 1 #这里忘记了
if ans == length + 1:
return 0
else:
return ans
。。。。。。。。。。。。。。。。
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
if not nums: #这里不要忘记了
return 0
n = len(nums)
ans = n + 1
i, j = 0, 0
sums = 0 # 多给初始值
# for i in range(n) 要用while 不然i 会被重制
while j < n:
sums += nums[j]
while sums >= target:# 判断条件一定要清晰 >跟>=完全不一样
ans = min(ans, j - i + 1)
sums -= nums[i]
i += 1
j += 1 # 用while来做判断条件
# print(ans)
if ans == n+1:
return 0
else:
return ans
Solution().minSubArrayLen(7,[2,3,1,2,4,3])
python创建二维列表 深拷贝创建
```python
a = [1, 2, 3, 4, 5]
b = [a.copy() for _ in range(5)]#跟copy毫无关系!
b[1][2] = 1000000
print(b)
输出
[[1, 2, 3, 4, 5], [1, 2, 1000000, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
b = [2] * 3
b[1] = 19000
print(b)
shuchu
[2, 19000, 2]
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
matrix = [[0] * n for _ in range(n)]
rol, col, dirIdx = 0, 0, 0
for i in range(1, n**2+1):
matrix[rol][col] = i
dx, dy = dirs[dirIdx]
r, c = rol + dx, col + dy
if r < 0 or r == n or c < 0 or c == n or matrix[r][c] > 0:
"""转向"""
dirIdx = (dirIdx + 1) % 4
dx, dy = dirs[dirIdx]
rol, col = rol + dx, col + dy
return matrix # 最后一个不会出现转很多方向,因为i只能等于n