今天是练习第二天,三道题目分别运用了三种方法,接下来分别介绍心得
这道题可以运用双指针来求解,运用双指针的第一个也是最重要的理由就是:求平方的数字最大的数肯定是由两边产生的,想清楚这一点以后,双指针的思路可以呼之欲出。而且题目中数组是按顺序排列的,输出的结果也是按顺序排列的,运用双指针可以省略一次for循环,使得时间复杂度为O(n)。代码如下:
class Solution(object):
def sortedSquares(self, nums):
result = []
i, j = 0, len(nums)-1
while i <= j :
if nums[i]**2 > nums[j]**2:
result.insert(0,nums[i]**2)
i += 1
else:
result.insert(0, nums[j]**2)
j -= 1
return result
这道题运用滑动窗口来解,滑动窗口可以只用于一个for循环来解题,并且滑动窗口也是双指针的延伸(可以将两个指针的范围内看做一个窗口),因此,这种寻找子串中的类似题目可以用滑动窗口来解题。
滑动窗口题目的难点在于调整起始位置与终止位置的设定。这个我也是看题解视频了解到的。这道题如果用起始位置来遍历的话,效果和暴力求解是一样的。所以用终止位置来遍历,可以通过调整起始位置来调整窗口大小。
子串求和大于目标值时,开始一点一点缩小起始位置,直到窗口中的子串小于目标值。这样能保证不漏掉符合条件的情况
所以我第一次的代码是这样写的(有问题):
# class Solution(object):
# def minSubArrayLen(self, target, nums):
# i, j = 0, 0
# result = len(nums)
# subL = len(nums)
# sum = 0
# while j < len(nums):
# sum += nums[j]
# while sum >= target:
# subL = j - i + 1
# result = min(result, subL)
# sum -= nums[i]
# i += 1
# j += 1
# if result == len(nums):
# return 0
# else:
# return result
直接导致测试用例nums = [1,2,3,4,5],target =15的测试用例结果为0.
这和我写代码熟练度有关,没有考虑到更充分的情况。这种思路没错但是输出有问题的事情经常犯错,因此参考了题解的写法,改变了返回值的写法,将默认的最小子串长度设为无穷大。这样在后面的最小值处理时也比较方便。代码如下:
class Solution(object):
def minSubArrayLen(self, target, nums):
i, j = 0, 0
subL = float('inf')
sum = 0
while j < len(nums):
sum += nums[j]
while sum >= target:
subL = min(j - i + 1, subL)
sum -= nums[i]
i += 1
j += 1
return subL if subL != float('inf') else 0
这样的问题还得靠经验积累来解决呀
这道题没有用到特殊的算法,只不过考察的是代码的控制,要想明白下面几件事:
1. 搞清楚循小循环(每一条边)的循环不变量,这道题循环不变量是左闭右开的区间
2.搞清楚大循环(每一圈)要怎么循环,循环几次。这道题中需要设置一个offset,offset的作用除了作为大循环的次数,还可以作为一圈的偏移量,因为没过一圈,起始位置startx和starty要往斜下方缩一下,offset代表每个小循环终点的偏移量,每循环一大圈,也要缩一格。至于循环几圈这个问题。n为偶数的时候,大圈走n的一半就能全部走完,n为奇数的时候,大圈走n的一半,最后还剩中间一格,所以n为奇数的时候,中间那个格子直接赋值就行。
3.python的二维数组的题练得还是少,要多练。
代码如下:
class Solution(object):
def generateMatrix(self, n):
nums = [[0]*n for _ in range(n)]
startx, starty = 0, 0
loop, mid = n // 2, n // 2
count = 1
for offset in range(1, loop + 1):
for j in range(starty, n - offset):
nums[startx][j] = count
count += 1
for i in range(startx, n - offset):
nums[i][n - offset] = count
count += 1
for j in range(n - offset, starty, -1):
nums[n - offset][j] = count
count += 1
for i in range(n - offset, startx, -1):
nums[i][starty] = count
count += 1
startx += 1
starty += 1
if n % 2 == 1:
nums[mid][mid] = count
return nums