剑指offer 65 至 剑指offer 68 - II 题解
Posted 风去幽墨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer 65 至 剑指offer 68 - II 题解相关的知识,希望对你有一定的参考价值。
剑指 Offer 65. 不用加减乘除做加法
题意:
写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。
题解:
先思考两个正数相加。
a+b 在二进制下一共只有四种情况 + 进位情况。
- 0 + 0 = 0
- 0 +1 = 1 + 0 = 1
- 1+ 1 = 0 进位1
很容易得出,加法后本位结果就是异或的结果,而是否进位的结果是相与的结果。
所以a+b = (a^b)+(a&b)<<1.
很容易就能够写出递归表达式。
while b !=0
a, b = (a ^ b), (a & b) << 1
接下来就是注意python里的负数以及变量无位数限制的情况。
整型中0xffffffff是32位二进制全为1的情况,其中若是最高位为1则表示负数。
在处理时加上判断即可。
代码:
class Solution:
def add(self, a: int, b: int) -> int:
x = 0xffffffff
a, b = a & x, b & x
while b != 0:
a, b = (a ^ b), (a & b) << 1 & x
return a if a <= 0x7fffffff else ~(a ^ x)
剑指 Offer 66. 构建乘积数组
题意:
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
题解:
预处理一下前缀积和后缀积
代码:
class Solution:
def constructArr(self, a: List[int]) -> List[int]:
sum,rsum= [1]*(len(a)+1),[1]*(len(a)+2)
for i in range(1,len(a)+1):
sum[i] =sum[i-1]*a[i-1]
for i in range(len(a),0,-1):
rsum[i]=rsum[i+1]*a[i-1]
ret = []
for i in range(1,len(a)+1):
ret.append(sum[i-1]*rsum[i+1])
return ret
剑指 Offer 67. 把字符串转换成整数
题意:
字符串转换成整数
题解:
字符串处理问题,注意各种非法值即可。
代码:
class Solution:
def strToInt(self, str: str) -> int:
s,st,ans = str.strip(),0,0
INT_MAX,INT_MIN = (1<<31)-1,-(1<<31)
if len(s)== 0:return 0
if s[0]=='+' or s[0]=='-':
st+=1
if len(s)==1 and st == 1:
return 0
for i in range(st,len(s)):
if '0'<=s[i]<='9':
ans=ans*10+int(s[i])
else:
break
if st == 1 and s[0]=='-':
ans = -ans
ans = min(ans,INT_MAX)
ans = max(ans,INT_MIN)
return ans
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
题意:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先
题解:
因为是二叉搜索树,所以满足左子树<根节点<右子树。
所以两个节点的最小公共祖先,一定满足 :
min(q.val,p.val)<=root.val<=max(q.val,p.val)
且满足此要求的节点为最近公共祖先。
反证:若是节点A满足此要求但不是最近公共祖先,那么节点p与节点q应该分布在其左右子树上且不在同一子树上,或者有一节点为根节点A本身。此时最近公共祖先B应该在A的左右子树之一中,那么根据有序性B无法满足上述要求,故节点A为最近公共祖先。
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root: return None
def dfs(root:'TreeNode'):
if min(q.val,p.val)<=root.val<=max(q.val,p.val):
return root
elif root.val>=max(q.val,p.val):
return dfs(root.left)
else :
return dfs(root.right)
return dfs(root)
剑指 Offer 68 - II. 二叉树的最近公共祖先
题意:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
题解:
递归寻找,记录左右子树是否含有p或者q节点。
当前节点为最近公共祖先的成立条件是:
- 左右子树包含pq节点
- 左右子树之一包含pq节点之一,该节点本身为pq节点之一
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
ans=None
def dfs(root:TreeNode)->bool:
nonlocal ans
if not root:return False
fl = dfs(root.left)
fr = dfs(root.right)
if (fl and fr) or ((root == p or root == q) and(fl or fr)):
ans =root
if root == p or root == q :
return True
return fl or fr
dfs(root)
return ans
以上是关于剑指offer 65 至 剑指offer 68 - II 题解的主要内容,如果未能解决你的问题,请参考以下文章
剑指offer 65 至 剑指offer 68 - II 题解