LeetCode上知识卡片之 初级算法的刷题记录
数组
删除排序数组中的重复项
难点在于原地删除的同时不想时间复杂度太高的话,可以考虑双指针。一个指针遍历数组判断是否为重复元素,一个指针用来搜集不重复元素并把他们安排到数组前列。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if not nums:
return 0
#index为接下来不重复元素的插入位置
index = 0
for i in range(1,len(nums)):
if nums[i] != nums[i-1]:
index += 1
nums[index] = nums[i]
return index + 1
买卖股票的最佳时机 II
1.分析题目要求,最大的利润是在每一次价格的波峰波谷完成买卖。所以统计每一段价格上升的幅度就是答案。
2.利用dp思想,dp[i][0]和dp[i][1]分别记录第i天不持有股票和持有股票的最大收益,则dp[len-1][0]就是要求的输出,又因为每天状态和前一天有关,可以把dp数组压缩为2个变量。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
dp0 = 0
dp1 = -prices[0]
for i in range(1,len(prices)):
dp0,dp1 = max(dp0,dp1+prices[i]),max(dp1,dp0-prices[i])
return dp0
旋转数组
1.环状替代
2.利用3次反转
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= n
nums[:] = nums[::-1]
nums[:k],nums[k:]= nums[:k][::-1],nums[k:][::-1]
存在重复元素
利用hash表达到最优时间效率,python中set类型即可
只出现1次的数字
异或操作可以把出现2次的数字归零,让一个变量等于0然后异或数组中每个数字,剩下的结果就是答案。
两个数组的交集2
1.把一个数组元素存成hash表记录出现次数;遍历另外一个数组元素,如果在hash表出现且次数大于0则加入结果。
2.把两个数组排好序,双指针遍历过去,相等就加入结果,否则根据移动较小元素的指针。
加一
在用数组保存的数字上执行加一操作,用变量carry标志是否进位,从数组尾到头遍历更新数组元素和carry即可。若最后carry为1,说明在数组最右扩招一位。
移动零
双指针,一个用来遍历数组,一个用来记录非0元素应该放入的位置/
两数之和
经典题目,利用hash表即可。
有效的数独
设置9*3个hash表,记录横,竖以及子数独各个数字出现情况。
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
rows = [{
} for i in range(9)]
columns = [{
} for i in range(9)]
boxes = [{
} for i in range(9)]
for i in range(9):
for j in range(9):
num = board[i][j]
if num != '.':
num = int(num)
box_index = (i // 3 ) * 3 + j // 3
rows[i][num] = rows[i].get(num, 0) + 1
columns[j][num] = columns[j].get(num, 0) + 1
boxes[box_index][num] = boxes[box_index].get(num, 0) + 1
if rows[i][num] > 1 or columns[j][num] > 1 or boxes[box_index][num] > 1:
return False
return True
旋转图像
矩阵旋转问题
1.矩阵转置以后,每行反转。
2.分成4个矩形块处理,遍历一个矩形块中每个元素时同时考虑其他3块内对应位置元素互换。
字符串
反转字符串
原地反转字符串,s[i]与s[n-1-i]交换即可
整数反转
整数反转可利用如下代码,但是需要主要python中负数整除往下约等,-123//10 = -13,所以为了方便处理,对x输入取绝对值。
while x:
res = 10*res+ x%10
x //= 10
字符串中的第一个唯一字符
遍历字符串,用hash表存储出现状况即可。但是因为要求是第一次字符:
1.可以再遍历一遍字符串,先出现的hash值为1的就是要求。
2.python的字典是有序字典,直接遍历dict.keys()也可
有效的字母异位词
遍历两个字符串,一个再hash表对应字母数量+1,一个-1,最后如果hash有元素值不为0就是false
验证回文字符串
头尾双指针,往中间遍历,遇到数字字母就检查判断。
字符串转换整数 (atoi)
边界细节比较多,最大最小值判断,符号以及符号位过滤,非法字符。
class Solution:
def myAtoi(self, str: str) -> int:
str = str.strip() # 删除首尾空格
if not str:
return 0 # 字符串为空则直接返回
int_max, int_min = 2 ** 31 - 1, -2 ** 31
boudry = 2 ** 31 // 10
res, i, sign = 0, 1, 1
if str[0] == '-': sign = -1 # 保存负号
elif str[0] != '+': i = 0 # 若无符号位,则需从 i = 0 开始数字拼接
for c in str[i:]:
if not '0' <= c <= '9' :
break
if res > boudry or(res == boudry and c > '7'):
return int_max if sign == 1 else int_min
res = 10 * res + ord