方法:五张牌排序,把大小王先当作零,然后统计零的个数,挨个求相邻两个数的间隔,若果间隔有0,表明有重复牌,则不可能是顺子,如果0的个数大于所有数间隔的和,则是顺子
class Solution:
def isStraight(self, nums: List[int]) -> bool:
joker = 0
nums.sort() # 数组排序
for i in range(4):
if nums[i] == 0: joker += 1 # 统计大小王数量
elif nums[i] == nums[i + 1]: return False # 若有重复,提前返回 false
return nums[4] - nums[joker] < 5 # 最大牌 - 最小牌 < 5 则可构成顺子
方法一:约瑟夫环,环形链表模拟圆圈,用list,k = (start + m - 1) % n ,k为每次要删除的数
class Solution:
def LastRemaining_Solution(self, n, m):
# write code here
if n==0:
return -1
temp = []
num = 0
for i in range(n):
temp.append(i)
while len(temp)!=1:
num = (m+num-1) % n
temp.pop(num)
n =n-1
return temp[0]
方法二:找到每次被删除数字的规律直接计算,
方法:从前往后遍历,记录当索引之前的数的最小值,然后用当前数减去最小值,每次循环需要更新最小值和差值的最大值
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if len(prices)==0:
return 0
tempmin = prices[0]
tempdiff = 0
for i in range(len(prices)):
if prices[i]tempdiff:
tempdiff = prices[i]-tempmin
return tempdiff
方法一:利用条件与的短路特性,即and前面的条件如果不满足,不会执行后面的表达式,利用这点实现递归的if返回判断
class Solution:
def __init__(self):
self.res = 0
def sumNums(self, n: int) -> int:
n > 1 and self.sumNums(n - 1)
self.res += n
return self.res
方法二:利用构造函数、函数指针、虚函数、模板等来实现
方法:利用位运算,每次把两个数相抑或,得到没有计算进位的结果,然后两个数相与并<<1,得到只计算进位的结果,然后把得到的两个数作为新的加数,重复以上运算,直到表示进位的数为0
class Solution:
def Add(self, num1, num2):
# write code here
while(num2!=0):
temp = num1^num2;
num2= (num1&num2)<<1;
num1 = temp;
return num1
'''
return sum([num1,num2])
'''
方法1:直接暴力连乘,时间复杂度n*2
方法2:通过i来划分左右两个部分,左面的a(n) = a(n-1)*A(n),右边的b(n-1) = b(n)*A(n),然后B(n)=a(n)*b(len(A)-n-1)
class Solution:
def multiply(self, A):
zuo=1
you=1
left=[]
right=[]
result=[]
for i in range(len(A)):
left.append(zuo)
zuo=zuo*A[i]
for j in range(len(A)-1,-1,-1):
right.append(you)
you=you*A[j]
for n in range(len(A)):
result.append(left[n]*right[len(A)-1-n])
return result
方法一:直接用int()函数,可以用try 和except来捕获异常
方法二:按部就班的写,注意开头是‘+’或者‘-’号的情况
class Solution:
def StrToInt(self, s):
# write code here
if(s==''):
return 0
flag = 0
temp = 0
for i in range(len(s)):
if i==0:
if s[i]=='-':
flag = 1
elif s[i]>='0' and s[i]<='9' :
temp = temp*10+(ord(s[i])-ord('0'))
elif s[i]>='0' and s[i]<='9':
temp = temp*10+(ord(s[i])-ord('0'))
else:
return 0
if flag==1:
temp =-temp
return temp
'''
try:
return int(s)
except Exception as e:
return 0
'''
情况一:是二叉搜索树,所以跟节点比左节点大比右节点小,中序遍历即为排序的队列,从根节点开始,如果比两个节点都大,则最低公共祖先在左子树,反之在右子树
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val < p.val and root.val < q.val: # p,q 都在 root 的右子树中
root = root.right # 遍历至右子节点
elif root.val > p.val and root.val > q.val: # p,q 都在 root 的左子树中
root = root.left # 遍历至左子节点
else: break
return root
情况二:不是搜索树,但有指向父节点的指针,可以把此问题转化成求两个链表相交的第一个节点的题
情况三:不是搜索树,没有指向父节点的指针,需要先分别将两条路径保存,然后从头开始比较两个list,第一个不想等的即为结果
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
stack_1 = []
stack_2 = []
def dfs(root, node, stack):
if not root:
return False
stack.append(root)
if root.val == node.val:
return True
if (dfs(root.left, node, stack) or dfs(root.right, node, stack)):
return True
stack.pop()
dfs(root, p, stack_1)
dfs(root, q, stack_2)
i = 0
while i < len(stack_1) and i
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or root == p or root == q: return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left and not right: return # 1.
if not left: return right # 3.
if not right: return left # 4.
return root # 2. if left and right: