图解算法数据结构部分题目
1.分开奇偶数,使得数组中前面部分为奇数后面为偶数。使用类似与快速排序的思想,用两个指针分别从前面找偶数和后面找奇数,找到则对换。
class Solution(object):
def trainingPlan(self, actions):
"""
:type actions: List[int]
:rtype: List[int]
"""
a = 0
b = len(actions)-1
while a < b:
# 从前往后找偶数
# x & 1 == 1 等价于 x % 2 == 1,没见过学一下
while a < b and actions[a] & 1 == 1:
a += 1
while a < b and actions[b] & 1 == 0:
b -= 1
# 对换数字。用以下形式可以不用暂存
actions[a], actions[b] = actions[b],actions[a]
return actions
2.找一组连续的数相加得目标数。我用的暴力,,学一下滑动窗口做法,结合图理解:
def fileCombination(self, target):
"""
:type target: int
:rtype: List[List[int]]
"""
i, j ,sums, ans = 1, 2, 3, []
while i < j:
if sums == target:
ans.append([i for i in range(i,j+1)])
if sums < target:
j += 1 # 小了,右边指针右移
sums += j
else:
sums -= i
i += 1 # 左边指针右移
return ans
3. 求除了i之外的乘积。我用除法算,先求全部的乘积,然后每位除array[i],遇到0时先把0替换为1然后累乘,耗时。不如答案来的聪明,学答案:
注意体会累乘的表示
class Solution(object):
def statisticalResult(self, arrayA):
"""
:type arrayA: List[int]
:rtype: List[int]
"""
arrayB, tmp = [1]*len(arrayA), 1
for i in range(1, len(arrayA)): # 下三角累乘
arrayB[i] = arrayB[i-1] * arrayA[i-1]
for i in range(len(arrayA)-2, -1, -1): # 上三角累乘
tmp *= arrayA[i+1]
arrayB[i] *= tmp
return arrayB
4.返回任意一个重复值。最先想到用数组存,耗时。可以用哈希表(set())来缩短时间复杂度:
class Solution:
def findRepeatDocument(self, documents: List[int]) -> int:
hmap = set() # 使用集合
for doc in documents:
if doc in hmap: return doc # 找到一样的返回
hmap.add(doc)
return -1
5.螺旋遍历二维数组,规定上下左右边界来循环,每遍历完一行/列缩减范围。特别注意循环边界
class Solution:
def sprialArray(self,array):
if not array: # 数组为空则返回[]
return []
l, r, t, b, res = 0, len(array[0])-1, 0, len(array)-1, []
while True:
for i in range(l, r+1): # 从左到右遍历
res.append(array[t][i])
t += 1 # top增加,下降界限
if t > b: # 越界则退出循环
break
for i in range(t, b+1): # 从上到下遍历
res.append(array[i][r])
r -= 1
if r < l:
break
for i in range(r, l-1, -1): # 从右到左遍历,注意循环边界设置
res.append(array[b][i])
b -= 1
if t > b:break
for i in range(b, t-1, -1): # 从下到上遍历
res.append(array[i][l])
l += 1
if l > r:break
return res