目录
一:动态规划
1. 爬楼梯
2.强盗抢劫
3.强盗在环形街区抢劫
4.最短路径的和
5.矩阵的总路径数
6:数组中等差递增子区间的个数
7.分割整数的最大乘积
8. 按平方数来分割整数
9. 最长递增子序列
10.最长数对链
11:最长波动序列个数
12:最长公共子序列
13、最小花费爬楼梯
14、 最长公共子串(连续)
15、 最长公共子串 (不连续)
16、把数字翻译成字符串
17、 兑换零钱
18、连续子数组的最大和
19、最长回文子串
20、编辑距离
二:双指针问题
1、两数之和 II - 输入有序数组
2.平方数之和
3.反转字符串中元音字母
4:回文子串
5:链表是否有环
6、合并区间
7、最长不重复连续子串 (双指针 + set)
8、接雨水问题
三:贪心思想
1、分饼干问题
2.无重叠区间(求删除个数)
编辑
3.飞镖气球
4.买卖股票(一次交易)
5.买卖股票(多次交易)
6.种花问题
7、s是否是t子串
8、分糖果问题
9、主持人调度
四:栈与队列
1.判断括号
2:数组中元素与下一个比它大的元素之间的距离(气温问题)
3.下一个更大元素
4、用两个栈实现队列
5、包含min函数的栈
6、滑动窗口的最大值 (双端队列+单调递减)
7、最小的k个数 (堆)
8、寻找第k大的数 (堆)
9、数据流中位数
五:二叉树
1、树高度 num 104
2、判断是否是avl树 num 110
3、树直径(高度变种)num 543
4 二叉树镜像
5、两棵树对应节点求和 num 617
6、是否存在叶子节点到根节点总和对应输入的数字 num112
7、判断t是否是s的子树
8、判断树是否对称 num101
9、树的最小深度
10、所有左叶子节点的和
11、相同节点值的最大路径长度(待定)
12、间隔求和
13、求第二小的节点
14、层次遍历( 一棵树每层节点的平均数)
15、(层序遍历)得到左下角的节点
16、先序遍历(非递归)
17、中序遍历(非递归)
18、修剪二叉树(节点值全部在(L,R)之间)
19、第k小的元素
20、二叉搜索树转换为累加树
21、最底的公共祖先
22、从有序数组中构造二叉查找树
23、 在二叉查找树中寻找两个节点,使它们的和为一个给定值
24、二叉搜索树的最小绝对差
25、二叉搜索树(众树)
26、前缀树(待定更新)
27、二叉树后续遍历(非递归)
28 按之字形顺序打印二叉树
29、 判断是不是二叉搜索树 (中序遍历的结果是不是顺序)
30、判断是不是完全二叉树
31、序列化和反序列化(前序)
32、重建二叉树
六:二分法
1.求开方
2、大于给定元素的最小元素
3、有序数组只有一个数不出现两次,找出这个数。
4、第一个错误版本
5、旋转数组最小数字
6、查找连续数组
7、有序数组二分查找
8、寻找峰值
9、版本号比较
七:搜索问题
1、最短路径(BFS)
2、岛屿最大面积,连续一的个数(DFS)
3、岛屿数量(DFS)
4、好友关系个数(DFS)
5、填充边界的O
6、手机键盘组合(回溯)
7、IP地址划分
8、单词搜索(回溯)
9、给定一个 没有重复 数字的序列,返回其所有可能的全排列。(回溯)
10、有相同元素全排列
11、组合
12、括号生成
13、矩阵递增序列
八:HASH表专题:
1、数组中两个数的和为给定值(双指针和hash表解决)
2、存在重复元素
3、最长和谐子序列
4、最长连续序列(桶排序和set)
5、三数之和
九:字符串专题:
1、两个字符串包含的字符是否完全相同(排序后判断即可)
2、计算一组字符集合可以组成的回文字符串的最大长度(统计每个字符出现次数)
3、同构字符串
4、判断一个整数是否是回文数(转成字符双指针或者求回文的数)
5、统计二进制字符串中连续 1 和连续 0 数量相同的子字符串个数
6、字符串变形
7、最长公共前缀字符串
8、大数加法
9、验证IP地址
十:数组和矩阵专题
1、移动0
2、改变矩阵维度
3、最长连续的1
4、有序矩阵查找
5、一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
6、(二分)找出数组中重复的数,数组值在 [1, n] 之间(要求不能修改数组,也不能使用额外的空间。)
7、数组的度
8、对角元素相等的矩阵
9、S[i] 表示一个集合,集合的第一个元素是 A[i],第二个元素是 A[A[i]],如此嵌套下去。求最大的 S[i],指导首尾相等
10、分隔数组,使得对每部分排序后数组就为有序。
11、螺旋矩阵
12、 顺时针旋转矩阵
13、旋转数组
十一:排序专题
1、数组中的第K个最大元素(快排或者堆排序)
2、前k个高频元素
3、根据字符出现频率排序
4、三种颜色国旗排列
十二:位运算
1:统计两个数的二进制表示有多少位不同
2:数组中唯一一个不重复的元素
3:找出数组中缺失的那个数
4:数组中不重复的两个元素
5:判断一个数是不是 2 的 n 次方
6:判断一个数是不是 4 的 n 次方
7:判断一个数的位级表示是否不会出现连续的 0 和 1
8:数字的补数
9:字符串数组最大乘积
10: 统计从 0 ~ n 每个数的二进制表示中 1 的个数
十三:链表
1、链表反转(迭代 + 头插)
2、区间内反转
3、 链表中的节点每k个一组翻转
4、合并两个有序链表
5、K个链表合并
6、链表是否有环(快慢指针,见双指针)
7、链表环的入口 (相遇之后,一个指针指向最开头)
8、找出倒数最后k个链表节点
9、删除倒数第n个节点 (先走n步找到该节点)
10、两个链表的第一个公共节点
11、两个链表相加
12、单链表排序
13、 判断链表是否是回文
14、 删除有序链表中重复的元素-I
15、删除有序链表中重复的元素-II
import numpy as np
class Solution:
def climbStairs(self, n: int) -> int:
res=np.zeros(n+1,np.int)
res[0],res[1]=1,1
for i in range(2,n+1):
res[i] = res[i - 1] + res[i - 2]
return int(res[n])
题目描述:抢劫一排住户,但是不能抢邻近的住户,求最大抢劫量。定义 dp 数组用来存储最大的抢劫量,其中 dp[i] 表示抢到第 i 个住户时的最大抢劫量。由于不能抢劫邻近住户,如果抢劫了第 i -1 个住户,那么就不能再抢劫第 i 个住户,所以
编辑
import numpy as np
import math
class Solution:
#初始化比较麻烦 dp[0]=nums[0] dp[1]=max(nums[0],nums[1])
#递推公式 dp[i]=max(dp[i-1],dp[i-2]+nums[i])
def rob(self, nums: List[int]) -> int:
if not nums:
return 0
if(len(nums)==1):
return nums[0]
dp=np.zeros(len(nums)+1,np.int)
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
for index in range(2,len(nums)):
dp[index]=max(dp[index-1],dp[index-2]+nums[index])
return int(dp[len(nums)-1])
这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
import numpy
class Solution:
def rob(self, nums: List[int]) -> int:
#一个是从0到n-1,另一个是从1到n
if not nums:
return 0
if(len(nums)==1):
return nums[0]
if(len(nums)==2):
return max(nums[0],nums[1])
dp1,dp2=numpy.zeros(len(nums),numpy.int),numpy.zeros(len(nums),numpy.int)
dp1[0]=nums[0]
dp1[1]=max(nums[1],nums[0])
for index1 in range(2,len(nums)-1):
dp1[index1]=max(dp1[index1-1],dp1[index1-2]+nums[index1])
nums2=nums[1:]
dp2[0]=nums2[0]
dp2[1]=max(nums2[0],nums2[1])
for index2 in range(2,len(nums)-1):
dp2[index2]=max(dp2[index2-1],dp2[index2-2]+nums2[index2])
return int(max(dp1[len(nums)-2],dp2[len(nums)-2]))
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
import numpy as np
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
#初始化 dp[0][0] = grid[0][0];
#第一行第一列均为之前求和
#dp[row][col]=min(dp[row-1][col],dp[row][col-1])+grid[row][col]
rows=len(grid)
cols=len(grid[0])
dp=np.zeros((rows,cols),dtype=np.int32)
dp[0][0] = grid[0][0];
for row in range(1,rows):
dp[row][0]=dp[row-1][0]+grid[row][0]
for col in range(1,cols):
dp[0][col]=dp[0][col-1]+grid[0][col]
for row in range(1,rows):
for col in range(1,cols):
dp[row][col]=min(dp[row-1][col],dp[row][col-1])+grid[row][col]
return int(dp[rows-1][cols-1])
import numpy as np
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
#初始状态第一行第一列全是1
#dp[i][j]=dp[i-1][j]+dp[i][j-1]
dp=np.zeros((m,n),np.int32)
for i in range(m):
for j in range(n):
if(i==0 or j==0):
dp[i][j]=1
for i in range(1,m):
for j in range(1,n):
dp[i][j]=dp[i-1][j]+dp[i][j-1]
return int(dp[m-1][n-1])
如果一个数列至少有三个元素,并且任意两个相邻元素之差相同,则称该数列为等差数列。例如,以下数列为等差数列:
1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9
以下数列不是等差数列。1, 1, 2, 5, 7
数组 A 包含 N 个数,且索引从0开始。数组 A 的一个子数组划分为数组 (P, Q),P 与 Q 是整数且满足 0<=P函数要返回数组 A 中所有为等差数组的子数组个数。
import numpy as np
class Solution:
def numberOfArithmeticSlices(self, A: List[int]) -> int:
#dp[i] 表示以 A[i] 为结尾的等差递增子区间的个数。
# dp[2] = 1
# [0, 1, 2]
# dp[3] = dp[2] + 1 = 2
# [0, 1, 2, 3], // [0, 1, 2] 之后加一个 3
# [1, 2, 3] // 新的递增子区间
# dp[4] = dp[3] + 1 = 3
# [0, 1, 2, 3, 4], // [0, 1, 2, 3] 之后加一个 4
# [1, 2, 3, 4], // [1, 2, 3] 之后加一个 4
# [2, 3, 4] // 新的递增子区间
if not A or len(A)<=2:
return 0
dp=np.zeros(len(A),np.int)
dp[0],dp[1]=0,0
for i in range(2,len(A)):
if(A[i]-A[i-1]==A[i-1]-A[i-2]):
dp[i]=dp[i-1]+1
return int(sum(dp))
import numpy as np
class Solution:
def integerBreak(self, n: int) -> int:
#dp[i]表示整数i对应的最大乘积,dp[i]的值应是dp[j]*(i-j),j属于[1,i-1]的最大值,
#同时注意dp[i]对应的值是经过拆分了的,所以还应判断两个数拆分的情况,即j*(i-j)的值,取最大即可。像2拆成1+1,积是1
dp=np.zeros(n+1,np.int)
dp[0],dp[1]=0,0
for i in range(2,n+1):
for j in range(0,i):
dp[i]=max(dp[i],dp[j]*(i-j),j*(i-j))
return dp[n]
import numpy as np
import math
class Solution:
def numSquares(self, n: int) -> int:
#dp[i]表示i平方和最小所需要的个数
#dp[i]=min(dp[i],dp[i-j*j]+1)
dp=np.zeros(n+1,np.int)
dp[0],dp[1]=0,1
for i in range(2,n+1):
dp[i]=i
for j in range(1,int(math.sqrt(i))+1):
dp[i]=min(dp[i],dp[i-j*j]+1)
return int(dp[n])
import numpy as np
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
if not nums:
return 0
dp=np.zeros(len(nums),np.int)
dp[0]=1
for i in range(1,len(nums)):
dp[i]=1
for j in range(0,i):
if(nums[i]>nums[j]):
dp[i]=max(dp[i],dp[j]+1)
return int(max(dp))
给出 n 个数对。 在每一个数对中,第一个数字总是比第二个数字小。
现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面。我们用这种形式来构造一个数对链。
给定一个对数集合,找出能够形成的最长数对链的长度。你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。
示例 :
输入: [[1,2], [2,3], [3,4]]
输出: 2
解释: 最长的数对链是 [1,2] -> [3,4]
import numpy as np
class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
#dp[i]表示以第i 个元素结尾最多书对链长度
#dp[i]=max(dp[j]+1,dp[i])
#返回列表中最大的
dp=[0]*len(pairs)
dp[0]=1
pairs.sort(key = lambda x:x[1])
for i in range(1,len(pairs)):
dp[i]=1
for j in range(i):
if(pairs[j][1]
import numpy as np
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
#首先对list进行去重
#dp[i]代表下标i之前的最大,如果是当前元素是摆动dp[i]=dp[i-1]+1,否则dp[i]=dp[i-1]
result=[]
if not nums:
return 0
result.append(nums[0])
for i in range(1,len(nums)):
if(nums[i]!=nums[i-1]):
result.append(nums[i])
if(len(result)<=2):
return len(result)
dp=np.zeros(len(result),np.int)
dp[0],dp[1]=1,2
for i in range(2,len(result)):
if((result[i]-result[i-1])*(result[i-1]-result[i-2])<0):
dp[i]=dp[i-1]+1
else:
dp[i]=dp[i-1]
return dp[len(result)-1]
import numpy as np
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m,n=len(text1),len(text2)
dp=np.zeros((m+1,n+1),np.int)
for i in range(1,m+1):
for j in range(1,n+1):
if(text2[j-1]==text1[i-1]):
dp[i][j]=dp[i-1][j-1]+1
else:
dp[i][j]=max(dp[i-1][j],dp[i][j-1])
return dp[m][n]
class Solution:
def minCostClimbingStairs(self , cost: List[int]) -> int:
# write code here
# 动态规划
# 1、确定状态
# 最后一步前必定是在第i-1级台阶 或 第i-2级台阶
# 原问题:求通过第i级台阶所花费的最少代价
# 子问题:求通过第i-1级台阶和通过第i-2级台阶之间花费的最少代价
# 2、转移方程
# f(i) = min {f(i-1)+cost(i-1), f(i-2)+cost(i-2)}
# 3、初始条件
# 因为可以选择直接从台阶0或台阶1开始爬楼梯,所以: f(0)=0, f(1)=0
# 4、计算顺序
# 从小到大依次计算
# 5、编程实现
n = len(cost) # 有n级台阶
f = [0]*(n+1) # 台阶从0开始,所以索引n为楼梯顶部,即有n+1级台阶
for i in range(2, n+1): # 按从小到大的顺序计算
f[i] = min(f[i-1]+cost[i-1], f[i-2]+cost[i-2])
return f[n]
class Solution:
def LCS(self , str1: str, str2: str) -> str:
# write code here
maxLen = 0
endIndex = 0
f = [[0 for j in range(len(str2)+1)] for i in range(len(str1)+1)]
for i in range(1, len(str1)+1):
for j in range(1, len(str2)+1):
if (str1[i-1] == str2[j-1]):
f[i][j] = f[i-1][j-1] + 1
else:
f[i][j] = 0
if maxLen < f[i][j]:
maxLen = f[i][j]
endIndex = i # end index of the first string
# print(maxLen)
return str1[endIndex-maxLen:endIndex]
class Solution:
def LCS(self , s1: str, s2: str) -> str:
if s1 is None or s2 is None:
return '-1'
len1 = len(s1)
len2 = len(s2)
dp = [[''] * (len2 + 1) for i in range(len1 + 1)]
for i in range(1, len1+1):
for j in range(1, len2+1):
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1] + s1[i -1]
else:
dp[i][j] = dp[i][j-1] if len(dp[i][j-1]) > len(dp[i-1][j]) else dp[i-1][j]
return dp[-1][-1] if dp[-1][-1] != '' else '-1'
class Solution:
def solve(self , nums: str) -> int:
# write code here
n = len(nums)
dp = [0] * (n+1)
dp[0] = 1
dp[1] = 1 if nums[0] != '0' else 0
print(dp)
for i in range(2, n+1):
if nums[i-1] != '0':
dp[i] += dp[i-1]
if '10'<= nums[i-2:i] <= '26':
dp[i] += dp[i-2]
return dp[n]
class Solution:
def minMoney(self , arr: List[int], aim: int) -> int:
# 定义a[i]为组成i的最少货币数
# 状态转移矩阵a[i] = min(a[i-arr[0]], a[i-arr[n]]) + 1
# 输出值a[aim]
# 边界条件: a[i]全部初始化为0即可
a = [0] * (aim + 1)
for i in range(1, aim+1):
min_num = 9999
for coin in arr:
if i >= coin:
min_num = min(min_num, a[i-coin] + 1)
a[i] = min_num
return a[aim] if a[aim] < 9999 else -1
class Solution:
def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
# 定义a[i]为前i个元素的子数组最大和
# 状态转移矩阵为 if a[i-1] <0 then a[i] = arr[i]; if a[i-1]>0 then a[i] = a[i-1] + arr[i]
# 输出max(a[0], a[1], a[m-1])
# a初始化为0即可
m = len(array)
a = [0] * m
a[0] = array[0]
for i in range(1, m):
if a[i-1] < 0:
a[i] = array[i]
else:
a[i] = a[i-1] + array[i]
return max(a)
class Solution:
def getLongestPalindrome(self , A: str) -> int:
# write code here
n = len(A)
dp = [ [0] * n for _ in range(n)]
max_len = 0
for i in range(n - 1, -1, -1):
for j in range(i, n):
if((A[i] == A[j]) and (j - i < 2 or dp[i + 1][j - 1])):
dp[i][j] = 1
max_len = max(max_len, j - i + 1)
return max_len
class Solution:
def editDistance(self , str1: str, str2: str) -> int:
# write code here
m, n = len(str1), len(str2)
dp = [[0] * (n+1) for _ in range(m+1)] # 状态转移方程 (m, n) matrix
# 初始化边界
for i in range(m+1):
dp[i][0] = i
for j in range(n+1):
dp[0][j] = j
for i in range(1, m+1):
for j in range(1, n+1):
if str1[i-1] == str2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])+1
return dp[m][n]
class Solution:
def maximalSquare(self, matrix):
max_side = 0
h,w = len(matrix),len(matrix[0])
dp = [[0 for i in range(w)] for i in range(h)]
print('初始化dp',np.array(dp))
for i in range(h):
dp[i][0] = int(matrix[i][0])
max_side = max(max_side, dp[i][0])
for i in range(w):
dp[0][i] = int(matrix[0][i])
max_side = max(max_side, dp[0][i])
print('初始化边界dp',np.array(dp))
for i in range(1,h):
for j in range(1,w):
if matrix[i][j]=='1':
dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])+1
max_side = max(max_side, dp[i][j])
print('转移好dp',np.array(dp))
return max_side**2
matrix = [["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]]
# matrix = [["0","1"],["1","0"]]
sol = Solution()
res= sol.maximalSquare(matrix)
print(res)
class Solution:
def findTargetSumWays(self, nums: List[int], S: int) -> int:
sumAll = sum(nums)
if S > sumAll or (S + sumAll) % 2:
return 0
target = (S + sumAll) // 2
dp = [0] * (target + 1)
dp[0] = 1
for num in nums:
for j in range(target, num - 1, -1):
dp[j] = dp[j] + dp[j - num]
return dp[-1]
class Solution:
def canPartition(self, nums: List[int]) -> bool:
total = sum(nums)
if total % 2 == 1: # 总和无法等分
return False
target = total // 2
if max(nums) > target: # 最大值大于总和的一半,无法分割
return False
# 初始化
dp = [False] * (target+1)
dp[0] = True
# 状态更新
for num in nums:
for j in range(target, num-1, -1): # 倒序,且j>=num 【j
题目描述:在有序数组中找出两个数,使它们的和为 target。
使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。
- 如果两个指针指向元素的和 sum == target,那么得到要求的结果;
- 如果 sum > target,移动较大的元素,使 sum 变小一些;
- 如果 sum < target,移动较小的元素,使 sum 变大一些。
数组中的元素最多遍历一次,时间复杂度为 O(N)。只使用了两个额外变量,空间复杂度为 O(1)。
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
list=[]
first,latest=0,len(numbers)-1
while(firsttarget):
latest=latest-1
else:
first=first+1
Input: 5 Output: True Explanation: 1 * 1 + 2 * 2 = 5
题目描述:判断一个非负整数是否为两个整数的平方和。
可以看成是在元素为 0~target 的有序数组中查找两个数,使得这两个数的平方和为 target,如果能找到,则返回 true,表示 target 是两个整数的平方和。
本题和 167. Two Sum II - Input array is sorted 类似,只有一个明显区别:一个是和为 target,一个是平方和为 target。本题同样可以使用双指针得到两个数,使其平方和为 target。
本题的关键是右指针的初始化,实现剪枝,从而降低时间复杂度。设右指针为 x,左指针固定为 0,为了使 02 + x2 的值尽可能接近 target,我们可以将 x 取为 sqrt(target)。
因为最多只需要遍历一次 0~sqrt(target),所以时间复杂度为 O(sqrt(target))。又因为只使用了两个额外的变量,因此空间复杂度为 O(1)。
import math
class Solution:
def judgeSquareSum(self, c: int) -> bool:
first,latest=0,int(math.sqrt(c))
while(first<=latest):
sum=first*first+latest*latest
if(sum==c):
return True
elif(sum>c):
latest=latest-1
else:
first=first+1
return False
class Solution:
def reverseVowels(self, s: str) -> str:
first,latest=0,len(s)-1
char_list=['a','o','e','i','u','A','E','I','O','U']
temp_list=[]
#str字符串可以看成数组,但是不能修改
for ele in s:
temp_list.append(ele)
while(first
给定一个非空字符串
s
,最多删除一个字符。判断是否能成为回文字符串。
class Solution:
def validPalindrome(self, s: str) -> bool:
first,late=0,len(s)-1
for i in range(int(len(s)/2)):
if(s[i]==s[late-i]):
continue
else:
return self.judge(s,i+1,late-i) or self.judge(s,i,late-i-1)
return True
def judge(self,s,i,j):
first,late=i,j
count=0
while(first
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
p,q=head,head
if(head==None or head.next==None):
return False
while(q.next!=None and p!=None):
p=p.next
q=q.next.next
if(p==q):
return True
return False
class Solution:
def merge(self , intervals ):
intervals.sort(key=(lambda elme:elme.start))
res = []
for i in range (len(intervals)):
if res == []:
res.append(intervals[i])
else:
if res[-1].end >= intervals[i].start :
res[-1].end = max(intervals[i].end, res[-1].end)
else:
res.append(intervals[i])
return res
class Solution:
def maxLength(self , arr: List[int]) -> int:
# write code here
i, j = 0, 0
val_set = set()
max_len = 0
while i < len(arr) and j < len(arr):
if (arr[j] not in val_set):
val_set.add(arr[j])
max_len = max(max_len, j - i + 1)
j += 1
else:
val_set.remove(arr[i])
i += 1
return max_len
class Solution:
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
left, right = 0, len(height) - 1
left_max, right_max = 0, 0
res = 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
res += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
res += right_max - height[right]
right -= 1
return res
class Solution:
def maxArea(self, height: List[int]) -> int:
maxA = 0
i = 0
j = len(height) - 1
while i < j:
h = min(height[i], height[j]);
maxA = max(maxA, h * (j - i));
if height[i] < height[j]:
i = i + 1
else:
j = j - 1
return int(maxA)
解法一:
使用排序,然后将排序后的数组与排序前对比,找到最开始和最后元素不同的位置
class Solution(object):
def findUnsortedSubarray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, -1
new_nums = sorted(nums)
for i in range(len(nums)):
if nums[i] != new_nums[i]:
left = i
break
for i in range(len(nums)):
if nums[i] != new_nums[i]:
right = i
return right - left + 1
解法二
从网上学习到一个非常牛的解法,使用双指针;
(1)左指针处理,逆向遍历数组,找到最后大于已遍历部分的极小值位置,即为最初需要变动的元素
(2)右指针处理,正向向遍历数组,找到最后小于已遍历部分的极大值位置,即为最后需要变动的元素位置
class Solution(object):
def findUnsortedSubarray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
length = len(nums)
left, right = 0, -1
max, min = nums[0], nums[length - 1]
for i in range(length):
if nums[i] < max:
right = i
else:
max = nums[i]
if nums[length - i - 1] > min:
left = length - i - 1
else:
min = nums[length - i - 1]
return right - left + 1
def change_num():
id1, id2 = -1, -1
max_id = len(nums) - 1
for i in range(len(nums)-1, -1 , -1):
if(nums[i] > nums[max_id]):
max_id = i
elif(nums[i] < nums[max_id]):
id1, id2 = i, max_id
nums[id1],nums[id2] = nums[id2], nums[id1]
if __name__ == '__main__':
nums = [9, 8, 9 , 6, 5]
change_num()
print(nums)
输入: [1,2,3], [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
m,n=len(g),len(s)
g.sort()
s.sort()
i,j,count=0,0,0
while(i
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x:x[1])
count=1
end=intervals[0][1]
for i in range(1,len(intervals)):
if(intervals[i][0]>=end):
count+=1
end=intervals[i][1]
return len(intervals)-count
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
#求不重叠区间个数,就是飞镖个数
if not points:
return 0
points.sort(key=lambda x:x[1])
count=1
end=points[0][1]
for i in range(1,len(points)):
if(points[i][0]>end):
end=points[i][1]
count+=1
return count
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#一次交易
if not prices:
return 0
max_profit=0
min_price=prices[0]
for i in range(1,len(prices)):
min_price=min(prices[i],min_price)
max_profit=max(max_profit,prices[i]-min_price)
return max_profit
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#多次交易
if not prices:
return 0
sum_profit=0
for i in range(1,len(prices)):
if(prices[i]>prices[i-1]):
sum_profit+=prices[i]-prices[i-1]
return sum_profit
题目描述:flowerbed 数组中 1 表示已经种下了花朵。花朵之间至少需要一个单位的间隔,求解是否能种下 n 朵花。
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
#只需要判断前后即可,防止考虑边界问题,在前后加上[0],只要连续出现在三个[0]就可以种花
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
else:
return False
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
index=-1
for ele in s:
index=t.find(ele,index+1)
if index==-1:
return False
return True
class Solution:
def candy(self , arr ):
# write code here
res = [1] * len(arr)
for i in range(1, len(arr)):
if arr[i] > arr[i-1]:
res[i] = res[i-1] + 1
for i in range(len(arr)-2, -1, -1):
if arr[i] > arr[i+1]:
res[i] = max(res[i+1] + 1, res[i])
return sum(res)
class Solution:
def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int:
start = list()
end =list()
#分别得到活动起始时间
for i in range(n):
start.append(startEnd[i][0])
end.append(startEnd[i][1])
#分别对开始和结束时间排序
start.sort()
end.sort()
res = 0
j = 0
for i in range(n):
#新开始的节目大于上一轮结束的时间,主持人不变
if start[i] >= end[j]:
j += 1
else:
#主持人增加
res += 1
return res
class Solution:
def canJump(self, nums: List[int]) -> bool:
farest_idx = 0 # 最远可达位置
for i, jump in enumerate(nums):
if i <= farest_idx and farest_idx < i + jump:
farest_idx = i + jump
return farest_idx >= len(nums) - 1
class Solution:
def isValid(self, s: str) -> bool:
stack=[]
if not s:
return True
stack.append(s[0])
for i in range(1,len(s)):
if(len(stack) and ((s[i]==')' and stack[-1]=='(') or (s[i]=='}' and stack[-1]=='{') or (s[i]==']' and stack[-1]=='['))):
stack.pop()
else:
stack.append(s[i])
if(len(stack)>0):
return False
return True
Input: [73, 74, 75, 71, 69, 72, 76, 73] Output: [1, 1, 4, 2, 1, 1, 0, 0]
import numpy as np
class Solution:
def dailyTemperatures(self, T: List[int]) -> List[int]:
stack=[]
res=np.zeros(len(T),np.int)
stack.append(0)
for cur_index in range(1,len(T)):
while(len(stack)!=0 and T[cur_index]>T[stack[-1]]):#判断条件
pre_index=stack.pop()
res[pre_index]=cur_index-pre_index
stack.append(cur_index)
return res
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
#遍历列表两次,只将第一次的入队列
list_len=len(nums)
res=[-1]*list_len
stack=[]
for index in range(2*list_len):
while(len(stack) and nums[index%list_len]>nums[stack[-1]]):
pre_index=stack.pop()
res[pre_index]=nums[index%list_len]
if(index
# -*- coding:utf-8 -*-
class Solution:
'''
1.当插入时,直接插入 stack1
2.当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,
如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,
再弹出 stack2 栈顶元素
'''
def __init__(self):
self.stack1= []
self.stack2= []
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
# return xx
if len(self.stack2)==0:
while(len(self.stack1)!=0):
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack = [] #初始化原栈
self.stack_min = [] #初始化最小值栈
def push(self, node):
self.stack.append(node) #往原栈中添加 元素
if not self.stack_min: #一开始也往最小值栈中添加元素
self.stack_min.append(node)
elif node < self.stack_min[-1]: #再次添加元素的时候要同最小值栈中元素比较,小于最小值栈中索引-1的对应值,就把node加入;
self.stack_min.append(node)
else:
self.stack_min.append(self.stack_min[-1]) #否则把索引-1的对应值添加到stack_min中
def pop(self):
self.stack.pop() #弹出栈顶元素则分别获取即可
self.stack_min.pop()
def top(self):
return self.stack[-1] #栈顶元素从原栈中获取
def min(self):
return self.stack_min[-1] #最小值就直接从最小值栈中获取
class Solution:
def maxInWindows(self , num: List[int], size: int) -> List[int]:
res=[]
#双端队列
queue=[]#左边做队首,右边做队尾。做成递减队列
for i in range(len(num)):
if len(queue)>0 and i>queue[0]+size-1:#i走到超出原来最大值能覆盖的窗口的位置,那么这个最大值要更新了
queue.pop(0)
while len(queue)>0 and num[i]>num[queue[-1]]:#要进队的数数值大,那就删除所有前面小的数,再把它加进去。
#终止时要加进去的数要么排在第一了,要么就排在比它大的数的后面
#要加len(queue)>0 这个条件,否则当queue被删空了代码就会出现num[-1]这样索引报错的情况
queue.pop()
queue.append(i)
if i>=size-1:
res.append(num[queue[0]])
return res
class Solution:
def GetLeastNumbers_Solution(self, a, k):
import heapq
return heapq.nsmallest(k,a)
import heapq
class Solution:
def findKth(self , a: List[int], n: int, K: int) -> int:
heap = []
for i in range(n):
heapq.heappush(heap, -a[i]) # 小顶堆存进去负数
for i in range(K-1):
heapq.heappop(heap) #出队前K-1个(最大的)
return -heapq.heappop(heap) # 相反数
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.li = []
def Insert(self, num):
for i in range(len(self.li)):
if num < self.li[i]:
self.li.insert(i, num)
break
else:
self.li.append(num)
def GetMedian(self):
length = len(self.li)
if length == 1:
return self.li[0]
return (self.li[length//2] + self.li[(length-1)//2]) / 2
class Solution:
def decodeString(self, s):
stack = [] # (str, int) 记录之前的字符串和括号外的上一个数字
num = 0
res = "" # 实时记录当前可以提取出来的字符串
for c in s:
if c.isdigit():
num = num * 10 + int(c)
elif c == "[":
stack.append((res, num))
res, num = "", 0
elif c == "]":
top = stack.pop()
print('===top:', top)
res = top[0] + res * top[1]
print('==res:', res)
else:
res += c
return res
# s = "3[a]2[bc]"
s = "3[a2[c]]"
sol = Solution()
res = sol.decodeString(s)
print('res:', res)
class Solution:
def LRU(self , operators: List[List[int]], k: int) -> List[int]:
stack = [] #有序
div_kv = {} #无序
res = [] #结果
for op in operators:
if op[0] == 1:#set操作
if len(stack) >= k:
del div_kv[stack.pop(0)]
if op[1] in div_kv:
stack.remove(op[1])
stack.append(op[1])
div_kv[op[1]] = op[2]
elif op[0] == 2:#get操作
if op[1] not in div_kv:
res.append(-1)
else:
stack.remove(op[1])
stack.append(op[1])
res.append(div_kv[op[1]])
return res
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
else:
LD=self.maxDepth(root.left)
RD=self.maxDepth(root.right)
return max(LD,RD)+1
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def get_depth(root):
if not root:
return 0
else:
LD=get_depth(root.left)
RD=get_depth(root.right)
return max(LD,RD)+1
if not root:
return True
LD=get_depth(root.left)
RD=get_depth(root.right)
if(abs(LD-RD)>1):
return False
return self.isBalanced(root.left) and self.isBalanced(root.right)
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.max=0
#最长路径未必经过根节点
def get_depth(root):
if not root:
return 0
else:
LD=get_depth(root.left)
RD=get_depth(root.right)
self.max=max(LD+RD,self.max)
return max(LD,RD)+1
if not root:
return 0
else:
get_depth(root)
return self.max
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if root:
self.invertTree(root.left)
self.invertTree(root.right)
temp=root.left
root.left=root.right
root.right=temp
return root
class Solution:
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
#修改之前的树,先序遍历
if not t1:
return t2
if not t2:
return t1
else:
t1.val+=t2.val
t1.left=self.mergeTrees(t1.left,t2.left)
t1.right=self.mergeTrees(t1.right,t2.right)
return t1
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
#与剑指offer一题目类似
if(not root):
return False
if(not root.left and not root.right and root.val==sum):
return True
sum-=root.val
return self.hasPathSum(root.left,sum) or self.hasPathSum(root.right,sum)
class Solution:
def isSubtree(self, root: [TreeNode], subRoot: [TreeNode]) -> bool:
def is_equal(root, subRoot):
if not root and not subRoot:
return True
if not subRoot or not root:
return False
if (root.val == subRoot.val):
return is_equal(root.left, subRoot.left) and is_equal(root.right, subRoot.right)
if not root:
return False
return is_equal(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
def dfs(p,q):
#判断子树是否相同
if(not p and not q):
return True
if(not p or not q):
return False
if(p.val==q.val):
return dfs(p.left,q.right) and dfs(p.right,q.left)
if not root:
return True
return dfs(root.left,root.right)
class Solution:
def minDepth(self, root: TreeNode) -> int:
#要注意如果根节点的左或右子树为空的话是构不成子树的。而最小深度是要求从根节点到子树的
if not root:
return 0
elif not root.left:
return self.minDepth(root.right)+1
elif not root.right:
return self.minDepth(root.left)+1
else:
left=self.minDepth(root.left)
right=self.minDepth(root.right)
return min(left,right)+1
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
#有点疑惑
if not root:
return 0
sum=0
if root.left and not root.left.left and not root.left.right:
sum=sum+root.left.val+self.sumOfLeftLeaves(root.right)
else:
sum=sum+self.sumOfLeftLeaves(root.right)+self.sumOfLeftLeaves(root.left)
return sum
class Solution:
def rob(self, root: TreeNode) -> int:
#后序遍历,树dp,dp[0]代表不抢该节点可以获取的最大值,dp[1]代表抢该节点
def dfs(root):
if not root:
return [0,0]
left=dfs(root.left)
right=dfs(root.right)
result=[0,0]
result[0]=max(left[0],left[1])+max(right[0],right[1])
result[1]=root.val+left[0]+right[0]
return result
res=dfs(root)
return max(res[0],res[1])
class Solution:
result=[]
def findSecondMinimumValue(self, root: TreeNode) -> int:
def pre_order(root,val_list):
if(root):
pre_order(root.left,val_list)
pre_order(root.right,val_list)
val_list.append(root.val)
val_list=[]
pre_order(root,val_list)
val_list.sort()
val_2 = list(set(val_list))
val_2.sort(key = val_list.index)
if(len(val_2)<2):
return -1
return val_2[1]
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
queue,result=[],[]
queue.append(root)
while(len(queue)):
length,temp_len=len(queue),len(queue)
sum=0
while(length):
length-=1
p=queue.pop(0)
sum+=p.val
if(p.left):
queue.append(p.left)
if(p.right):
queue.append(p.right)
result.append(sum/temp_len)
return result
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
queue=[]
queue.append(root)
while(len(queue)):
#遍历完一层将结果记录下来
length,temp_len=len(queue),len(queue)
level_res=[]
while(length):
length-=1
p=queue.pop(0)
level_res.append(p.val)
if(p.left):
queue.append(p.left)
if(p.right):
queue.append(p.right)
return level_res[0]
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack=[]
stack.append(root)
result=[]
while(len(stack)>0):
temp=stack.pop()
result.append(temp.val)
if(temp.right):
stack.append(temp.right)
if(temp.left):
stack.append(temp.left)
return result
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
stack=[]
p=root
result=[]
while(p or len(stack)):
if(p):
stack.append(p)
p=p.left
else:
p=stack.pop()
result.append(p.val)
p=p.right
return result
class Solution:
def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode:
if not root:
return None
elif(root.val>R):
return self.trimBST(root.left,L,R)
elif(root.val
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
self.count=0
self.res=0
def in_order(root):
if not root:
return
else:
in_order(root.left)
self.count+=1
if(self.count==k):
self.res=root.val
in_order(root.right)
in_order(root)
return self.res
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
self.sum=0
def in_order(root):
if root:
in_order(root.right)
self.sum+=root.val
root.val=self.sum
in_order(root.left)
return root
return in_order(root)
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root:
return None
if(p==root):
return p
if(q==root):
return q
L=self.lowestCommonAncestor(root.left,p,q)
R=self.lowestCommonAncestor(root.right,p,q)
if( L and R):
return root
elif not R:
return L
else:
return R
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
def mid_build(ele_list,l,r):
if(l>r):
return None
mid=(l+r)>>1
root=TreeNode(nums[mid])
root.left=mid_build(ele_list,l,mid-1)
root.right=mid_build(ele_list,mid+1,r)
return root
if not nums:
return
return mid_build(nums,0,len(nums)-1)
class Solution:
def findTarget(self, root: TreeNode, k: int) -> bool:
res_set=set()
visit=[]
def in_order(root,target):
if root:
if(root.val not in res_set):
res_set.add(root.val)
if(k-root.val in res_set and k!=2*root.val):
return True
L=in_order(root.left,target)
R=in_order(root.right,target)
return L or R
return in_order(root,k)
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
min_value=1000
res=[]
stack=[]
p=root
while(p or len(stack)):
if(p):
stack.append(p)
p=p.left
else:
p=stack.pop()
if(len(res)):
min_value=min(min_value,abs(p.val-res[-1]))
res.append(p.val)
p=p.right
return min_value
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
res_dict={}
res=[]
def in_order(root):
if root:
in_order(root.left)
if(root.val not in res_dict):
res_dict[root.val]=1
else:
res_dict[root.val]+=1
in_order(root.right)
in_order(root)
if not root:
return
res_list=sorted(res_dict.items(),key=lambda x:x[1],reverse=True)
num=res_list[0][1]
res.append(res_list[0][0])
for ele in res_list[1:]:
if(ele[1] == num):
res.append(ele[0])
return res
class Solution:
def postorderTraversal(self, root): #迭代法1
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
# 中结点先处理
result.append(node.val)
# 左孩子先入栈
if node.left:
stack.append(node.left)
# 右孩子后入栈
if node.right:
stack.append(node.right)
# 将最终的数组翻转
return result[::-1]
# 层序遍历的时候加个反向的flag。
class Solution:
def Print(self , pRoot: TreeNode) -> List[List[int]]:
# write code here
if not pRoot: return []
quene = []
res = []
quene.append(pRoot)
reverseFlag = True
while quene:
row = []
for i in range(len(quene)):
node = quene.pop(0)
row.append(node.val)
if node.left:
quene.append(node.left)
if node.right:
quene.append(node.right)
reverseFlag = not reverseFlag
if reverseFlag:
res.append(row[::-1])
else:
res.append(row)
return res
class Solution:
def inOrderTraversal(self, root: TreeNode) -> List[int]:
if root is None:
return []
return self.inOrderTraversal(root.left) + [root.val] + self.inOrderTraversal(root.right)
def isValidBST(self , root: TreeNode) -> bool:
res = self.inOrderTraversal(root)
if len(res) <= 1:
return True
for i in range(len(res)-1):
if res[i] >= res[i+1]:
return False
return True
class Solution:
def isCompleteTree(self , root: TreeNode) -> bool:
if root is None:
return True
ret = [root]
while ret:
cur = ret.pop(0)
if cur:
ret.append(cur.left)
ret.append(cur.right)
else:
break
for i in ret:
if i:
return False
return True
class Solution:
str1 = []
def Serialize(self, root):
# write code here
if root == None:
self.str1.append("#")
return self.str1
self.str1.append(str(root.val))
self.Serialize(root.left)
self.Serialize(root.right)
return self.str1
start=-1
def Deserialize(self, s):
# write code here
self.start=self.start+1;
if self.start>=len(s) or s[self.start]=="#" or s==None :return ;
cur=TreeNode(int(s[self.start]))
cur.left=self.Deserialize(s)
cur.right=self.Deserialize(s)
return cur
class Solution:
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
# write code here
if not pre or not vin:
return None
#构造根节点,寻找左右子树的分界线
root = TreeNode(pre[0])
n = vin.index(pre[0])
#构造左右子树,递归调用
root.left = self.reConstructBinaryTree(pre[1:n + 1], vin[:n])
root.right = self.reConstructBinaryTree(pre[n + 1:], vin[n + 1:])
#返回根节点
return root
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = {}
self.word_end = -1
def insert(self, word):
"""
Inserts a word into the trie.
"""
curNode = self.root
for c in word:
if c not in curNode:
curNode[c] = {}
curNode = curNode[c]
curNode[self.word_end] = True
# print('==curNode:', curNode)
def search(self, word):
"""
Retu
rns if the word is in the trie.
"""
curNode = self.root
for c in word:
if c not in curNode:
return False
curNode = curNode[c]
if self.word_end not in curNode:
return False
return True
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
"""
curNode = self.root
for c in prefix:
if c not in curNode:
return False
curNode = curNode[c]
return True
word = 'apple'
prefix = 'ad'
obj = Trie()
obj.insert(word='apple')
obj.insert(word='add')
# obj.insert(word='app')
print('tree:', obj.root)
param_2 = obj.search(word)
print('search res:', param_2)
param_3 = obj.startsWith(prefix)
print('==param_3:', param_3)
lass Solution:
def mySqrt(self, x: int) -> int:
low,high=0,x
if x==0 or x==1:
return x
while(low>1
val=mid*mid
val_1=(mid+1)*(mid+1)
if(val<=x=x):
high=mid
else:
low=mid
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
#不需要等于,返回low
low,high=0,len(letters)-1
while(low>1
if(target
class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
low,high=0,len(nums)-1
while(low>1
if(mid%2):
mid-=1
if(nums[mid+1]==nums[mid]):
low=mid+2
else:
high=mid
return nums[low]
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
low,high=1,n
while(low>1
if(not isBadVersion(mid)):
low=mid+1
else:
high=mid-1
if isBadVersion(low):
return low
return low+1
class Solution:
def findMin(self, nums: List[int]) -> int:
low,high=0,len(nums)-1
if(len(nums)==1):
return nums[0]
while(nums[low]>nums[high]):
mid=(low+high)>>1
if(highnums[low]):
low=mid
else:
high=mid
if(nums[low]
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if(target not in nums):
return [-1,-1]
nums=list(map(float,nums))
def bin_search(nums, target):
low, high = 0, len(nums) - 1
while (low < high):
mid = int((low + high) / 2)
if (target == nums[mid]):
return mid
elif (target > nums[mid]):
low = mid + 1
else:
high = mid - 1
return low
a,b=target-0.5,target+0.5
i,j=bin_search(nums,a),bin_search(nums,b)
if(nums[i]!=target):
i=i+1
if(nums[j]!=target):
j=j-1
return [i,j]
class Solution:
def search(self , nums, target):
# write code here
length = len(nums)
left = 0
right = length
if length < 1:
return -1
while left <= right:
mid = int((left + right) / 2)
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
class Solution:
def findPeakElement(self , nums: List[int]) -> int:
left,right = 0,len(nums)-1
while left
def compare(s1, s2):
s1_val_list, s2_val_list = s1.split('.'), s2.split('.')
len_s1, len_s2 = len(s1_val_list), len(s2_val_list)
max_len = max(len_s1, len_s2)
if (len_s1 < max_len):
s1_val_list += [0] * (max_len - len_s1)
if (len_s2 < max_len):
s2_val_list += [0] * (max_len - len_s2)
for i in range(max_len):
n1 = int(s1_val_list[i])
n2 = int(s2_val_list[i])
if(n1 > n2):
return 1
if(n1 < n2):
return 0
versions = ['4.8', '1.7.1', '4.1.9', '5.0.0.0']
for i in range(len(versions)-1, -1, -1):
for j in range(i):
if(compare(versions[j], versions[j+1])):
versions[j], versions[j+1] = versions[j+1], versions[j]
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
#bfs
queue=[]
rows,cols=len(grid),len(grid[0])
if(rows==1 and cols==1 and grid[0][0]==0):
return 1
if(grid[0][0]==1 or grid[rows-1][cols-1]==1):
return -1
queue.append([0,0])
level=1
grid[0][0]=1
next_step=[[0,1],[1,0],[0,-1],[-1,0],[-1,-1],[1,1],[1,-1],[-1,1]]
while(queue):
length=len(queue)
while(length):
cur=queue.pop(0)
x=cur[0]
y=cur[1]
length-=1
if(x==rows-1 and y==cols-1):
return level
for i in range(len(next_step)):
x+=next_step[i][0]
y+=next_step[i][1]
if(x>=0 and x=0 and y
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def dfs(grid,i,j):
if(i<0 or i>=len(grid) or j<0 or j>=len(grid[0]) or grid[i][j]==0):
return 0
grid[i][j]=0
count=1
count += dfs(grid, i+1, j);
count += dfs(grid, i-1, j);
count += dfs(grid, i, j+1);
count += dfs(grid, i, j-1);
return count
max_count=0
for i in range(len(grid)):
for j in range(len(grid[0])):
if(grid[i][j]==0):
continue
else:
max_count=max(max_count,dfs(grid,i,j))
return max_count
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def dfs(grid,i,j):
if(i<0 or i>=len(grid) or j<0 or j>=len(grid[0]) or grid[i][j]=='0' ):
return
grid[i][j]='0'
dfs(grid,i+1,j)
dfs(grid,i,j+1)
dfs(grid,i-1,j)
dfs(grid,i,j-1)
count=0
for i in range(len(grid)):
for j in range(len(grid[0])):
if(grid[i][j]=='1'):
count+=1
dfs(grid,i,j)
return count
class Solution:
def findCircleNum(self, M: List[List[int]]) -> int:
#最基本的dfs
visited=[0]*len(M)
def dfs(i):
for j in range(len(M)):
if(visited[j]==0 and M[i][j]==1):
visited[j]=1
dfs(j)
count=0
for i in range(len(M)):
if(visited[i]==0):
count+=1
dfs(i)
return count
class Solution:
def solve(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
#对边界的那些‘O’进行dfs改变值,t
def dfs(grad,i,j):
if(i<0 or i>=len(board) or j<0 or j>=len(board[0]) or board[i][j]!='O'):
return
board[i][j]='-'
dfs(board,i-1,j)
dfs(board,i+1,j)
dfs(board,i,j-1)
dfs(board,i,j+1)
for i in range(len(board)):
for j in range(len(board[0])):
if((i==0 or i==len(board)-1 or j==0 or j==len(board[0])-1) and board[i][j]=='O'):
dfs(board,i,j)
for i in range(len(board)):
for j in range(len(board[0])):
if(board[i][j]=='O'):
board[i][j]='X'
if(board[i][j]=='-'):
board[i][j]='O'
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if not digits:
return []
res=[]
hash_table={'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'}
def dfs(index,cur_str):
if(index==len(digits)):
res.append(cur_str)
return
val=hash_table[digits[index]]
for i in range(len(val)):
cur_str=cur_str+val[i]
dfs(index+1,cur_str)
cur_str=cur_str[0:-1]
dfs(0,'')
return res
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
res = []
for i in range(1, 4):
for j in range(i+1, i + 4):
for k in range(j+1, j + 4):
num_1, num_2, num_3, num_4 = s[0:i], s[i:j], s[j:k], s[k:len(s)]
if(len(s)-k>=4):
continue
try:
if((num_1.startswith('0') and len(num_1)!=1) or (num_2.startswith('0') and len(num_2)!=1) or (num_3.startswith('0') and len(num_3)!=1) or (num_4.startswith('0') and len(num_4)!=1)):
continue
if (0 <= int(num_1) <= 255 and 0 <=int(num_2) <= 255 and 0 <= int(num_3) <= 255 and 0 <= int(num_4) <= 255):
res.append(num_1 + '.' + num_2 + '.' + num_3 + '.' + num_4)
except:
continue
return res
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
self.rows,self.cols=len(board),len(board[0])
def search(i,j,index):
if(index>=len(word)):
return True
if(i>=self.rows or j>=self.cols or i<0 or j<0 or board[i][j]!=word[index]):
return False
board[i][j]+='1'#改变之前的,是为了防止同一个单元格的元素多次使用,比如说eae,ea就可以走出eae
res=(search(i,j+1,index+1) or search(i+1,j,index+1) or search(i,j-1,index+1)or search(i-1,j,index+1))
board[i][j]=board[i][j][:-1]#改为原来的值
return res
for i in range(len(board)):
for j in range(len(board[0])):
if(board[i][j]==word[0]):
if(search(i,j,0)):
return True
return False
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
#啊哈算法全排列,浅拷贝和深拷贝
temp_list=[0]*len(nums)
book=[0]*len(nums)
res_list=[]
def dfs(step):
if(step==len(nums)):
res_list.append(temp_list.copy())
return
for i in range(len(nums)):
if(book[i]==0):
temp_list[step]=nums[i]
book[i]=1
dfs(step+1)
book[i]=0
dfs(0)
return res_list
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
#啊哈算法全排列,浅拷贝和深拷贝
temp_list=[0]*len(nums)
book=[0]*len(nums)
res_list=[]
def dfs(step):
if(step==len(nums)):
res_list.append(temp_list.copy())
return
for i in range(len(nums)):
if(book[i]==0):
temp_list[step]=nums[i]
book[i]=1
dfs(step+1)
book[i]=0
dfs(0)
set_list=[]
for ele in res_list:
if ele not in set_list:
set_list.append(ele)
return set_list
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
temp_val = []
res_list = []
def dfs(step):
if (len(temp_val) == k):
res_list.append(temp_val.copy())
return
else:
for index in range(step+1, n+1):
temp_val.append(index)
dfs(index)
temp_val.pop()
dfs(0)
return res_list
class Solution:
def recursion(self, string, res, length):
tmp = "".join(string)
if len(string) == length:
res.add(tmp)
return res
for i in range(len(string)):
string.insert(i, ')')
string.insert(i, '(')
self.recursion(string, res, length)
string.pop(i)
string.pop(i)
def generateParenthesis(self , n):
# write code here
length = 2*n
string = ['(',')']
res = set()
self.recursion(string, res, length)
res = list(res)
return res
class Solution:
global dirs
#记录四个方向
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
global n, m
#深度优先搜索,返回最大单元格数
def dfs(self, matrix:List[List[int]], dp: List[List[int]], i:int, j:int) :
if dp[i][j] != 0:
return dp[i][j]
dp[i][j] += 1
for k in range(4):
nexti = i + dirs[k][0]
nextj = j + dirs[k][1]
#判断条件
if nexti >= 0 and nexti < n and nextj >= 0 and nextj < m and matrix[nexti][nextj] > matrix[i][j]:
dp[i][j] = max(dp[i][j], self.dfs(matrix, dp, nexti, nextj) + 1)
return dp[i][j]
def solve(self , matrix: List[List[int]]) -> int:
global n,m
#矩阵不为空
if len(matrix) == 0 or len(matrix[0]) == 0:
return 0
res = 0
n = len(matrix)
m = len(matrix[0])
#i,j处的单元格拥有的最长递增路径
dp = [[0 for col in range(m)] for row in range(n)]
for i in range(n):
for j in range(m):
#更新最大值
res = max(res, self.dfs(matrix, dp, i, j))
return res
class Solution:
def canFinish(self, numCourses, prerequisites):
indegrees = [0] * numCourses # 入度列表
print('==indegrees:', indegrees)
adjacency = [[] for i in range(numCourses)] # 邻接列表 存储节点的下一个节点
print('=adjacency:', adjacency)
#得到入度和每个课程的邻接列表
for cur, pre in prerequisites:
indegrees[cur] += 1
adjacency[pre].append(cur)
print('====indegrees:', indegrees)
print('====adjacency:', adjacency)
quene = []
# 如果度为0 就进入队列
for i in range(len(indegrees)):
if indegrees[i] == 0:
quene.append(i)
print('==quene:', quene)
num_nodes = 0
while quene:
node = quene.pop(0)
num_nodes += 1
for next_node in adjacency[node]:
indegrees[next_node] -= 1 # 找出下一个点相应的度-1
if indegrees[next_node] == 0: # 入度为0
quene.append(next_node)
print('==num_nodes:', num_nodes)
return num_nodes == numCourses
numCourses, prerequisites = 6, [[3, 0], [3, 1], [4, 1], [4, 2], [5, 3], [5, 4]]
sol = Solution()
res = sol.canFinish(numCourses, prerequisites)
print('res:', res)
class Solution:
def canFinish(self, numCourses, prerequisites):
indegrees = [0] * numCourses # 入度列表
print('==indegrees:', indegrees)
adjacency = [[] for i in range(numCourses)] # 邻接列表
print('=adjacency:', adjacency)
#得到入度和每个课程的邻接列表
for cur, pre in prerequisites:
indegrees[cur] += 1
adjacency[pre].append(cur)
print('====indegrees:', indegrees)
print('====adjacency:', adjacency)
quene = []
# 如果度为0 就进入队列
for i in range(len(indegrees)):
if indegrees[i] == 0:
quene.append(i)
print('==quene:', quene)
num_nodes = 0
learn_node = []
while quene:
node = quene.pop(0)
print('=======node', node)
learn_node.append(node)
num_nodes += 1
for next_node in adjacency[node]:
indegrees[next_node] -= 1 # 找出下一个点相应的度-1
if indegrees[next_node] == 0: # 入度为0
quene.append(next_node)
print('==num_nodes:', num_nodes)
return learn_node if num_nodes == numCourses else []
# numCourses, prerequisites = 2, [[1, 0]]
# numCourses, prerequisites = 2, [[1, 0], [0, 1]]
numCourses, prerequisites = 6, [[3, 0], [3, 1], [4, 1], [4, 2], [5, 3], [5, 4]]
sol = Solution()
res = sol.canFinish(numCourses, prerequisites)
print('res:', res)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
res=[]
return_list=[]
for i in range(len(nums)):
if((target-nums[i]) in nums and nums.index(target-nums[i])!=i):
return [i,nums.index(target-nums[i])]
return []
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
res_set=set()
for i in range(len(nums)):
if(nums[i] not in res_set):
res_set.add(nums[i])
else:
return True
return False
class Solution:
def findLHS(self, nums: List[int]) -> int:
if not nums:
return 0
res_dict={}
max_res=0
for i in range(len(nums)):
if(nums[i] not in res_dict):
res_dict[nums[i]]=1
else:
res_dict[nums[i]]+=1
for i in range(1,len(nums)):
if( (nums[i]-1) in res_dict):
max_res=max(max_res,res_dict[nums[i]]+res_dict[nums[i]-1])
return max_res
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
#用set存储然后遍历查找,只往后查找
ele_set = set()
max_len = 0
for ele in nums:
if (ele not in ele_set):
ele_set.add(ele)
for ele in nums:
if ((ele - 1) not in ele_set):
cur_num = ele
temp_len = 0
while (cur_num in ele_set):
temp_len += 1
cur_num += 1
max_len = max(max_len, temp_len)
return max_len
class Solution:
def threeSum(self , num: List[int]) -> List[List[int]]:
# write code here
if len(num) < 3:
return []
help = {}
res = []
num = sorted(num)
for i in range(len(num)-2):
target = -num[i]
l = i + 1
r = len(num) - 1
while l < r:
if num[l] + num[r] == target:
res.append((num[i], num[l], num[r]))
res = list(set(res))
l += 1
elif num[l] + num[r] < target:
l += 1
else:
r -= 1
return res
思路 – hashtable
通过前缀和求解,令P[i] = A[0] + A[1] + … + A[i-1], 令P[j] = A[0] + … + A[j-1],
满足题目条件为 S = P[j] - P[i],目标是计算有多少个S。
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
pre_sum = {0:1}
cur_sum = 0
res = 0
for i in nums:
cur_sum += i
if cur_sum - k in pre_sum:
res += pre_sum[cur_sum - k]
pre_sum[cur_sum] = pre_sum[cur_sum] + 1 if cur_sum in pre_sum else 1
return res
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
s="".join((lambda x:(x.sort(),x)[1])(list(s)))
t="".join((lambda x:(x.sort(),x)[1])(list(t)))
if(len(s)!=len(t)):
return False
for i in range(len(s)):
if(s[i]!=t[i]):
return False
return True
class Solution:
def longestPalindrome(self, s: str) -> int:
count = collections.Counter(s)
length=0
for ele in count.values():
length+=int(ele/2)*2
if(length%2==0 and ele%2==1):
length+=1
return length
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
class Solution:
def isIsomorphic(self, s: str, t: str) -> bool:
for i in range(len(s)):
if(s.find(s[i])==t.find(t[i])):
continue
else:
return False
return True
class Solution:
def isPalindrome(self, x: int) -> bool:
if(x<0):
return False
if -1
class Solution:
def countBinarySubstrings(self, s: str) -> int:
#从前往后统计每个连续区间相同数字个数
if(len(s)<2):
return 0
count=1
count_list=[]
for i in range(1,len(s)):
if(s[i]==s[i-1]):
count+=1
else:
count_list.append(count)
count=1
count_list.append(count)
if(len(count_list)<2):
return 0
sum=0
for j in range(1,len(count_list)):
sum+=min(count_list[j],count_list[j-1])
return sum
class Solution:
def trans(self , s: str, n: int) -> str:
# write code here
s0=[]
for i in s:
if i!=' ':
if i.islower():
s0.append(i.upper())
else:
s0.append(i.lower())
else:
s0.append(' ')
s0=''.join(s0).split(' ')
return ' '.join(s0[::-1])
class Solution:
def longestCommonPrefix(self , strs: List[str]) -> str:
# write code here
if len(strs) == 0:
return ''
pre_str = strs[0]
for string in strs[1:]:
if pre_str in string:
continue
elif string in pre_str:
pre_str = string
else:
while pre_str not in string:
pre_str = pre_str[:-1]
return pre_str
class Solution:
def solve(self , s: str, t: str) -> str:
# write code here
if not s: return t
if not t: return s
res = ''
carry = 0
i = len(s) - 1
j = len(t) - 1
while i >= 0 or j >= 0:
n1 = s[i] if i >= 0 else 0
n2 = t[j] if j >= 0 else 0
tmp = int(n1) + int(n2) + carry
carry = tmp // 10
res = str(tmp % 10) + res
i -= 1
j -= 1
if carry:
return '1'+res
else:
return res
class Solution:
def ipv4(self, ip: str) -> str:
flag = True
for x in ip.split("."):
if len(x) > 3:
flag = False
break
for xi in x:
if not "0" <= xi <= "9":
flag = False
break
if not flag:
break
if x[0] == "0" or int(x) < 0 or int(x) > 255:
flag = False
break
return "IPv4" if flag else "Neither"
def ipv6(self, ip: str) -> str:
def check(digit):
try:
res = int(digit, 16)
return True
except Exception:
return False
flag = True
for x in ip.split(":"):
if not x or len(x) > 4 or not check(x.upper()) or int(x.upper(), 16) < 0 or int(x.upper(), 16) > 65536:
flag = False
break
return "IPv6" if flag else "Neither"
def solve(self , IP: str) -> str:
# write code here
if ":" in IP:
# ip6
if len(IP.split(":")) != 8: return "Neither"
return self.ipv6(IP)
elif "." in IP:
if len(IP.split(".")) != 4: return "Neither"
return self.ipv4(IP)
else:
return "Neither"
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
count=0
for ele in nums:
if(ele!=0):
count+=1
k=0
for i in range(len(nums)):
if(nums[i]!=0):
nums[k]=nums[i]
k+=1
for i in range(count,len(nums)):
nums[i]=0
class Solution:
def matrixReshape(self, nums: List[List[int]], r: int, c: int) -> List[List[int]]:
if(len(nums)*len(nums[0])
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
if not nums:
return 0
count=0
if(nums[0]==0):
count=0
else:
count=1
max_count=count
for i in range(1,len(nums)):
if(nums[i]==nums[i-1] and nums[i]==1):
count+=1
max_count=max(max_count,count)
elif(nums[i]==1):
count=1
max_count=max(max_count,count)
return max_count
class Solution:
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if not matrix:
return False
row_index,col_index=0,len(matrix[0])-1
while(row_index=0 ):
if(matrix[row_index][col_index]==target):
return True
elif(target
集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复,找出重复的数和缺失的数。
class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
#其实就是找第一个
for index in range(len(nums)):
while(nums[index]!= index+1):
#这里终止一定要注意
if(nums[index]==nums[nums[index]-1]):
break
temp=nums[nums[index]-1]
nums[nums[index]-1]=nums[index]
nums[index]=temp
for index in range(len(nums)):
if(nums[index]!= index+1):
return [nums[index],index+1]
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
low,high=1,len(nums)-1
mid=-1
while(low>1
count=0
for ele in nums:
if(ele <= mid):
count+=1
if(count<=mid):
low=mid+1
else:
high=mid
return low
class Solution:
def findShortestSubArray(self, nums: List[int]) -> int:
freq,left,right={},{},{}
for index,ele in enumerate(nums):
if(ele not in freq):
freq[ele]=1
left[ele]=index
else:
freq[ele]+=1
right[ele]=index
degree=max(freq.values())
return min(right[i]-left[i]+1 for i,v in freq.items() if v==degree)
class Solution:
def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
#只需要判断当前行除了最后一个元素和后一行除了第一个元素是否相等
rows,cols=len(matrix),len(matrix[0])
if(rows==1 or cols==1):
return True
for index in range(rows-1):
if(matrix[index][:-1]!=matrix[index+1][1:]):
return False
return True
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
#寻找最大长度的环
max_len=1
for index in range(len(nums)):
if(max_len>len(nums)/2):
return max_len
start_num=nums[index]
temp_num=nums[start_num]
temp_len=1
while(temp_num!=start_num):
temp_len+=1
temp_num=nums[temp_num]
max_len=max(max_len,temp_len)
return max_len
class Solution:
def maxChunksToSorted(self, arr: List[int]) -> int:
#当遍历到第i个位置时,如果可以切分为块,那前i个位置的最大值一定等于i。
#否则,一定有比i小的数划分到后面的块,那块排序后,一定不满足升序。
max_value,count=-100,0
for i in range(len(arr)):
max_value=max(max_value,arr[i])
if(max_value==i):
count+=1
return count
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param matrix int整型二维数组
# @return int整型一维数组
#
class Solution:
def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
# write code here
if matrix == []:
return []
m,n = len(matrix),len(matrix[0])
up,down = 0,m-1
left,right = 0,n-1
res = []
while left<=right and up<=down:
for i in range(left,right+1):
res.append(matrix[up][i])
up += 1
if up > down:
break
for i in range(up,down+1):
res.append(matrix[i][right])
right -= 1
if right < left:
break
for i in range(right,left-1,-1):
res.append(matrix[down][i])
down -= 1
if up > down:
break
for i in range(down,up-1,-1):
res.append(matrix[i][left])
left += 1
if left > right:
break
return res
class Solution:
def rotateMatrix(self , mat: List[List[int]], n: int) -> List[List[int]]:
for i in range(n):
for j in range(i):
temp = mat[i][j]
mat[i][j] = mat[j][i]
mat[j][i] = temp
for i in range(n):
mat[i].reverse()
return mat
class Solution:
def solve(self , n: int, m: int, a: List[int]) -> List[int]:
m = m % n
return a[n-m:] + a[:n-m]
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def quick_sort(nums, l, r, k):
if (l <=r):
temp = nums[l]
i, j = l, r
while (i != j):
while (i < j and temp < nums[j]):
j -= 1
if (i < j):
nums[i] = nums[j]
i += 1
while (i < j and temp >= nums[i]):
i += 1
if (i < j):
nums[j] = nums[i]
j -= 1
nums[i] = temp
if (i == k - 1):
return temp
elif (i > k-1):
return quick_sort(nums, l, i - 1, k)
else:
return quick_sort(nums, i + 1, r, k)
if(k>len(nums)):
return -1
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
res_dict={}
res_list=[]
for ele in nums:
if(ele not in res_dict):
res_dict[ele]=1
else:
res_dict[ele]+=1
res=sorted(res_dict.items(),key=lambda x: x[1], reverse=True)
if(k>len(res)):
return []
for index,ele in enumerate(res):
if(index
import collections
class Solution:
def frequencySort(self, s: str) -> str:
m=collections.Counter(s)
tmp=[[k,v] for k,v in m.items()]
tmp.sort(key=lambda x:x[1],reverse=True)
res=''
for ele in tmp:
res=res+ele[0]*ele[1]
return res
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
low,high=0,len(nums)-1
index=0
while(index<=high):
if(nums[index]==0):
nums[index],nums[low]=nums[low],nums[index]
low+=1
index+=1
elif(nums[index]==1):
index+=1
else:
nums[index],nums[high]=nums[high],nums[index]
high-=1
class Solution(object):
def hammingDistance(self, x, y):
"""
:type x: int
:type y: int
:rtype: int
"""
#所有int型整数都是相同位数
count=0
while(x or y):
if((x & 1) != (y & 1)):
count+=1
x=x>>1
y=y>>1
return count
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
#交换律:a ^ b ^ c <=> a ^ c ^ b
#任何数于0异或为任何数 0 ^ n => n
#相同的数异或为0: n ^ n => 0
count=0
for ele in nums:
count = count ^ ele
return count
题目描述:数组元素在 0-n 之间,但是有一个数是缺失的,要求找到这个缺失的数。
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res=0
for ele in range(len(nums)+1):
res^=ele
for ele in nums:
res^=ele
return res
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
#将数组所有元素进行异或操作
#找出结果的最高位1,两个数中一个最高位是1,一个是0
bit_mask=0
for ele in nums:
bit_mask ^=ele
#找到最高位是1的index
n=len(bin(bit_mask))-3
i,j=0,0
for ele in nums:
if((ele>>n)&1):
i^=ele
else:
j^=ele
return [i,j]
class Solution(object):
def isPowerOfTwo(self, n):
"""
:type n: int
:rtype: bool
"""
#n与n-1,如果为0,则是2的幂次方
if(n<=0):
return False
return (n&(n-1))==0
class Solution(object):
def isPowerOfFour(self, num):
"""
:type num: int
:rtype: bool
"""
return num >0 and (num & (num-1)==0) and (num & 0xaaaaaaaa)==0
class Solution(object):
def hasAlternatingBits(self, n):
"""
:type n: int
:rtype: bool
"""
n=(n ^ (n>>1))
n=(n&(n+1))
return n==0
给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。
class Solution(object):
def findComplement(self, num):
"""
:type num: int
:rtype: int
"""
#转换为求掩码过程
#100000000...作为mask与num相与,找出最高位1
mask=1<<30
while((mask & num ==0)):
mask = mask>>1
mask=(mask <<1 )-1
return mask^num
题目描述:字符串数组的字符串只含有小写字符。求解字符串数组中两个字符串长度的最大乘积,要求这两个字符串不能含有相同字符。
class Solution(object):
def maxProduct(self, words):
"""
:type words: List[str]
:rtype: int
"""
# 或|=:两个二进制对应位只要1个为1,结果就是1,否则是0;
# 与 &=:两个二进制的对应位都为1时,结果为1,否则结果等于0;
# 异或 ^=:两个二进制的对应位不同,结果为1,否则结果为0。
value_list=[0]*len(words)
for i in range(len(words)):
for char_val in words[i]:
#向左移动1
value_list[i] |= 1 << (ord(char_val)-97)
#只要有一个位置相同,&就不必为0
return max([len(words[i])*len(words[j]) for i in range(len(words)) for j in range(i+1,len(words)) if not (value_list[i] & value_list[j])] or [0])
class Solution(object):
def countBits(self, num):
"""
:type num: int
:rtype: List[int]
"""
#动态规划找规律
#如果是偶数,等于其一半的数中1的数目
#如果是基数,等于其减去一的数中1的数目
res=[0]
for ele in range(1,num+1):
if(ele %2==0):
res.append(res[ele/2])
else:
res.append(res[ele-1]+1)
return res
class Solution:
def ReverseList(self , head: ListNode) -> ListNode:
# write code here
# 空链表处理
if head == None:
return head
# 非空链表处理
pre = None
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
class Solution:
def reverseBetween(self , head: ListNode, m: int, n: int) -> ListNode:
# write code here
p = ListNode(0)
p.next = head # 保证p.next存在
new_head = p
cur = None
i = 1
while i < n:
if i < m:
p = head
head = head.next
elif i >= m:
cur = head.next
head.next = cur.next # 保证第n个节点之后的节点不丢失
cur.next = p.next
p.next = cur
i += 1
return new_head.next
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
class Solution:
def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
# write code here
new_head = ListNode(0)
new_head.next=head
c=0
last=new_head
cur = new_head
while cur:
if c==k:
cur=self.reverse(last,k)
last=cur
c=0
c+=1
cur=cur.next
return new_head.next
def reverse(self, last, k):
queue_head=last.next
for i in range(1, k):
next=queue_head.next
queue_head.next=next.next
next.next=last.next
last.next=next
return queue_head
class Solution:
def Merge(self , pHead1: ListNode, pHead2: ListNode) -> ListNode:
# write code here
h = ListNode(0)
new = h
# 为什么要用new?因为h接下来不断在动,new记住了表头!
while pHead1 and pHead2:
if pHead1.val <= pHead2.val:
h.next = pHead1
pHead1 = pHead1.next
else:
h.next = pHead2
pHead2 = pHead2.next
h = h.next
else:
if pHead1:
h.next = pHead1
elif pHead2:
h.next = pHead2
return new.next
import heapq
class Solution:
def mergeKLists(self , lists: List[ListNode]) -> ListNode:
vhead = ListNode(-1)
p = vhead
heads = [i for i in lists]
heap = [(n.val,idx) for idx, n in enumerate(lists) if n is not None]
heapq.heapify(heap)
while heap:
idx = heapq.heappop(heap)[1] #
tmp = heads[idx]
p.next = tmp
heads[idx] = heads[idx].next
p = p.next
if heads[idx]: heapq.heappush(heap,(heads[idx].val, idx))
return vhead.next
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if pHead == None:
return None
fast =pHead
slow = pHead
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
if fast == None&nbs***bsp;fast.next == None:
return None
slow = pHead
while slow != fast:
slow=slow.next
fast = fast.next
return slow
class Solution:
def FindKthToTail(self , pHead: ListNode, k: int):
pre = pHead
suc = pHead
for i in range(k):
if suc:
suc = suc.next
else:
return None
while suc:
pre = pre.next
suc = suc.next
else:
return pre
class Solution:
def removeNthFromEnd(self , head, n):
pre = head
suc = head
for i in range(n):
if suc.next:
suc = suc.next
else:
head = head.next
return head
while suc.next:
pre = pre.next
suc = suc.next
else:
pre.next = pre.next.next
return head
class Solution:
def FindFirstCommonNode(self , pHead1 , pHead2 ):
# 计算链表长度的函数
def lenth(pHead: ListNode):
i = 0
while pHead:
i += 1
pHead = pHead.next
return i
# 走差值
l1 = lenth(pHead1)
l2 = lenth(pHead2)
if l1 >= l2:
n = l1-l2
while n:
pHead1 = pHead1.next
n -= 1
else:
n = l2-l1
while n:
pHead2 = pHead2.next
n -= 1
# 一起走
while pHead1:
if pHead1 == pHead2:
return pHead1
else:
pHead1 = pHead1.next
pHead2 = pHead2.next
# 没有交点返回空
return None
class Solution:
# 反转链表,按照个十百位数顺序相加,carry保存进位数据
# 时间复杂度:O(n) 空间复杂度:O(1)
def reverse_list(self, head):
if not head:
return None
cur = head
pre = None
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre
def addInList(self , head1: ListNode, head2: ListNode) -> ListNode:
if not head1:
return head2
if not head2:
return head1
head1 = self.reverse_list(head1)
head2 = self.reverse_list(head2)
res = ListNode(2022)
head = res
carry = 0
while head1 or head2 or carry != 0:
val1 = 0 if not head1 else head1.val
val2 = 0 if not head2 else head2.val
sum_ = val1 + val2 + carry
carry = sum_ // 10
temp = sum_ % 10
head.next = ListNode(temp)
head = head.next
if head1:
head1 = head1.next
if head2:
head2 = head2.next
return self.reverse_list(res.next)
class Solution:
def sortInList(self , head ):
# write code here
list1 = []
while(head):
list1.append(head.val)
head = head.next
list1.sort()
temp = ListNode(0)
pHead = temp
for i in list1:
pHead.next = ListNode(i)
pHead = pHead.next
return temp.next
class Solution:
def isPail(self , head):
res = []
cur = head
while cur:
res.append(cur.val)
cur = cur.next
return res == res[::-1]
class Solution:
def deleteDuplicates(self , head):
# write code here
cur = head
while cur:
while cur.next and cur.val == cur.next.val:
cur.next = cur.next.next
cur = cur.next
return head
class Solution:
def deleteDuplicates(self , head: ListNode) -> ListNode:
# write code here
dummy = pre = ListNode(-1)
while head and head.next:
if head.val == head.next.val:
temp = head.val
while head and head.val == temp:
head = head.next
continue
else:
pre.next = head
pre = pre.next
head = head.next
pre.next = head
return dummy.next