747.至少是其他数字两倍的最大数
一次遍历,记录好最大值和次大值以及最大值的下标即可。
class Solution:
def dominantIndex(self, nums: List[int]) -> int:
max1,max2 = float('-inf'), float('-inf')
index = -1
for i in range(len(nums)):
if nums[i] > max1:
max1,max2 = nums[i],max1
if max1 >= max2*2:
index = i
else: index = -1
elif nums[i] > max2:
max2 = nums[i]
if max1 < max2 *2:
index = -1
return index
643.子数组最大平均数
滑动窗口分别记录好当前的总和,然后做差即可(最开始我想的用哈希表,但是超时了)
class Solution:
def findMaxAverage(self, nums: List[int], k: int) -> float:
if k == 1:
return max(nums)
for i in range(1,len(nums)):
nums[i] += nums[i-1]
if i == k-1:
ans = nums[i]/k
elif i > k-1:
ans = max(ans,(nums[i]-nums[i-k])/k)
return ans
219.存在重复元素2
题目有点不太好懂,读作存在两个差值小于等于k的i,j。就好理解了。
class Solution:
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
Hash = {}
for i in range(len(nums)):
if (nums[i] not in Hash) or (i-Hash[nums[i]]>k):
Hash[nums[i]] = i
else:
ans = i - Hash[nums[i]]
if ans <= k:
return True
return False
742.寻找数组的中心索引
简单题,看清题意即可
class Solution:
def pivotIndex(self, nums: List[int]) -> int:
total_num = sum(nums)
left_num = 0
for i in range(len(nums)):
if left_num == total_num - left_num - nums[i]:
return i
left_num += nums[i]
return -1
941.有效的山脉数组
思路很简单,但是写起来很麻烦。
class Solution:
def validMountainArray(self, A: List[int]) -> bool:
n = len(A)
if n < 3:
return False
left = 0
for i in range(n-1):
if A[i] > A[i+1]:
left = i
break
if A[i] == A[i+1]:
return False
if left == 0:
return False
for j in range(left,n-1):
if A[j] <= A[j+1]:
return False
return True
414.第三大的数
一般思路的题目
class Solution:
def thirdMax(self, nums: List[int]) -> int:
max1,max2,max3 = float('-inf'),float('-inf'),float('-inf')
for num in nums:
if num == max1 or num == max2 or num == max3:
continue
if num > max1:
max1,max2,max3 = num,max1,max2
elif num > max2:
max2,max3 = num,max2
elif num > max3:
max3 = num
if max3 != float('-inf'):
return max3
return max1
581.最短无序连续子数组
本题有点类似于最长上坡路,稍微有点点不一样
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
n = len(nums)
min_num = float('inf')
for i in range(1,n):
if nums[i] < nums[i-1]:
min_num = min(min_num,nums[i])
max_num = float('-inf')
for i in range(n-1,0,-1):
if nums[i-1] > nums[i]:
max_num = max(max_num,nums[i-1])
left,right = 0,0
for i in range(n):
if nums[i] > min_num:
left = i-1
break
for j in range(n-1,-1,-1):
if nums[j] < max_num:
right = j
break
return right - left
532.数组中的K-diff数对
非常秀的解法,高赞带佬的答案就是强(可重复欣赏的题目)
class Solution:
def findPairs(self, nums: List[int], k: int) -> int:
if k < 0:
return 0
diff,ans = set(),set()
for num in nums:
if num + k in diff:
ans.add(num+k)
if num - k in diff:
ans.add(num)
diff.add(num)
return len(ans)
840.矩阵中的幻方
垃圾题目,建议跳过
class Solution:
def numMagicSquaresInside(self, grid: List[List[int]]) -> int:
d1=len(grid)
d2=len(grid[0])
ans = 0
for i in range(d1):
for j in range(d2):
if i+2>=d1 or j+2>=d2:
continue
if grid[i+1][j+1]!=5:
continue
pool = set()
mark = 0
for m in range(i,i+3):
for n in range(j,j+3):
if grid[m][n]>=1 and grid[m][n]<=9 and grid[m][n] not in pool:
pool.add(grid[m][n])
else:
mark=1
if mark==1:
continue
if grid[i][j]+grid[i][j+1]+grid[i][j+2]!=15:
continue
if grid[i+1][j]+grid[i+1][j+1]+grid[i+1][j+2]!=15:
continue
if grid[i+2][j]+grid[i+2][j+1]+grid[i+2][j+2]!=15:
continue
if grid[i][j]+grid[i+1][j]+grid[i+2][j]!=15:
continue
if grid[i][j+1]+grid[i+1][j+1]+grid[i+2][j+1]!=15:
continue
if grid[i][j+2]+grid[i+1][j+2]+grid[i+2][j+2]!=15:
continue
if grid[i][j]+grid[i+1][j+1]+grid[i+2][j+2]!=15:
continue
if grid[i][j+2]+grid[i+1][j+1]+grid[i+2][j]!=15:
continue
ans+=1
return ans
914.卡牌分组
本题本质即求数组n个元素的最大公约数,用集合set来做会比较方便
class Solution:
def hasGroupsSizeX(self, deck: List[int]) -> bool:
Deck = sorted(deck)
ans = set()
cur_num = 1
for i in range(1,len(Deck)):
if Deck[i] == Deck[i-1]:
cur_num += 1
else:
ans.add(cur_num)
cur_num = 1
ans.add(cur_num)
ans = list(ans)
min_num = min(ans)
for i in range(2,min_num+1):
for num in ans:
if num % i != 0:
break
if num == ans[-1]:
return True
return False
605.种花问题看解二
解法一:
数学转换:有点熟悉的题目,判断好两端和全为零的特殊情况就好。
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
if 1 not in flowerbed:
length = len(flowerbed)
if (length+1)//2 >= n:
return True
return False
left,right = 0,0
for num in flowerbed:
if num == 1:
break
left += 1
for num in flowerbed[::-1]:
if num == 1:
break
right += 1
left_flo,right_flo = left//2,right//2
n -= left_flo + right_flo
cur_0 = 0
for i in range(left,len(flowerbed)-right):
if flowerbed[i] == 0:
cur_0 += 1
else:
if cur_0 > 2:
n -= (cur_0-1)//2
cur_0 = 0
if n <= 0:
return True
return False
解法二:
两侧添0+贪心算法
因为两侧的判断条件与中间不同会使得代码变得冗长。所以我们两侧各加一个0使得所有的判断条件相同,之后只需要遍历数组,使用贪心算法,若元素0左右也为0,则可以种一棵树。
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
flowerbed = [0] + flowerbed +[0]
count = 0
for i in range(1,len(flowerbed)-1):
if flowerbed[i-1] == 0 and flowerbed[i]==0 and flowerbed[i+1] == 0:
flowerbed[i] = 1
count += 1
if count >= n:
return True
return False
665.非递减数列
class Solution:
def checkPossibility(self, nums: List[int]) -> bool:
for i in range(len(nums)-1):
if nums[i] > nums[i+1]:
if i==0:
nums[0]=nums[1]
elif nums[i-1]>nums[i+1]:
nums[i+1]=nums[i]
elif nums[i-1]<nums[i+1]:
nums[i]=nums[i-1]
break
for i in range(len(nums)-1):
if nums[i] > nums[i+1]:
return False
return True
59.螺旋矩阵2
洋葱遍历法:设置四个变量就好了。分别标记上下左右处理到哪儿了。
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
left,right,top,buttle = 0,n-1,0,n-1
array = [[0]*n for _ in range(n)]
num ,end = 1,n*n
while num <= n*n:
for c in range(left,right+1):
array[top][c] = num
num += 1
top +=1
for r in range(top,buttle+1):
array[r][right] = num
num += 1
right -= 1
for c in range(right,left-1,-1):
array[buttle][c] = num
num += 1
buttle -= 1
for r in range(buttle,top-1,-1):
array[r][left] = num
num += 1
left += 1
return array
950.按递增顺序显示卡牌
用单独一个数组来模拟抽取卡牌过程,存储摸取卡牌的顺序即可。
class Solution:
def deckRevealedIncreasing(self, deck: List[int]) -> List[int]:
if len(deck) < 2:
return deck
List = [i for i in range(len(deck))]
ans = []
while len(List) > 2:
ans.append(List[0])
List = List[2:] + [List[1]]
ans.append(List[0])
ans.append(List[1]) # 存储位置
deck.sort()
res = [None for _ in range(len(deck))]
for index in range(len(deck)):
res[ans[index]] = deck[index]
return res
216.数组总和3
第一次不看题解写出回溯法
class Solution:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
def backtrace(first=0,curr = []):
if sum(curr) == n and len(curr) == k:
ans.append(curr[:])
return
if sum(curr) > n or len(curr) >= k:
return
for num in range(first+1,10):
curr.append(num)
backtrace(num,curr)
curr.pop()
ans = []
curr = []
backtrace(0,[])
return ans
289.生命游戏
搞清楚深复制和浅复制的区别
class Solution:
def gameOfLife(self, board: List[List[int]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
row,col = len(board),len(board[0])
curr = [[None]*col for _ in range(row)]
for r in range(row):
for c in range(col):
curr[r][c] = board[r][c]
for r in range(row):
for c in range(col):
alive_num = 0
for nr in [r-1,r,r+1]:
for nc in [c-1,c,c+1]:
if 0 <= nr < row and 0 <= nc < col and curr[nr][nc] == 1:
alive_num += 1
if board[r][c] == 0 and alive_num == 3:
board[r][c] = 1
if board[r][c] == 1:
if alive_num > 4 or alive_num < 3:
board[r][c] = 0