
剑指offer
咕噜咕噜day
day day up!
展开
-
剑指offer【66】:构建乘数数组
题目:思路+代码: 思路: 构建矩阵BXA,利用上三角和下三角乘积,得出B 时间复杂度:O(n) 空间复杂度:O(1)class Solution: def constructArr(self, a: List[int]) -> List[int]: # 思路: # 构建矩阵BXA,利用上三角和下三角乘积,得出B # 时间复杂度:O(n) # 空间复杂度:O(1)原创 2020-07-30 08:19:39 · 186 阅读 · 0 评论 -
剑指offer【62】:约瑟夫环问题,例子+递推
题目:思路+代码:举例:序号递推关系:思路:约瑟夫环,首先理解,最终留下的数字在每轮删掉一个数剩下数组中都存在,只是索引不同;然后知道只剩一个数时索引一定为0,比如 F(8,3) 可以由 F(7,3)推出;f(n,m) = (f(n-1, m) + m) % nclass Solution: # 思路: # 约瑟夫环,首先理解,最终留下的数字在每轮删掉一个数剩下数组中都存在,只是索引不同; # 然后知道只剩一个数时索引一定为0,比如 F(8,3) 可原创 2020-07-29 14:12:05 · 788 阅读 · 0 评论 -
剑指offer【61】:扑克牌的顺子
题目:思路+代码:思路:首先可以知道,边界情况带有2个0时,max-min < 5; 所以只要这5个数除0之外不重复,且max-min <5,那么就一定是连续的;不需要具体的根据0的个数去判断;时间复杂度:O(n)空间复杂度:O(n); 一个数set()判重是O(1)class Solution: def isStraight(self, nums: List[int]) -> bool: # 思路: # 首先可以知道,边界情况带有原创 2020-07-29 11:20:42 · 178 阅读 · 0 评论 -
剑指offer【60】:n个骰子得点数取值
题目:思路+代码:思路:动态规划,总可能出现情况6n初始状态:n=1, 1,2,3,4,5,6;六种情况转移方程:第n次掷色子后的s值,F(n,s) = F(n-1,s-1)+F(n-1,s-2)+F(n-1,s-3)+F(n-1,s-4)+F(n-1,s-5)+F(n-1,s-6);返回:第n次后,出现各值得情况次数 * 1/(6n)时间复杂度:O(n2)空间复杂度:O(n2); 初始化一个n*(6n)的0数组class Solution: def twoSum(self, n原创 2020-07-29 10:43:13 · 216 阅读 · 0 评论 -
剑指offer【65】:不用加减乘除做加法(位运算+python存储负数)
题目:思路+代码:思路:a + b == (a ^ b) + ((a & b ) << 1)1.两个数 异或操作结果 == 两个数二进制无进位和 ; a ^ b2.两个数 与操作结果 == 两个数的进位结果 ; a & b ) << 13.两个结果相加即为两个数的和;4.return a; 是因为当无进位时,说明上一轮计算的无进位和(a),已经是最终结果时间复杂度:最差情况下(例如 a= 0x7fffffff , b=1 时),需循环 31 次,使用原创 2020-07-22 12:17:13 · 428 阅读 · 0 评论 -
剑指offer【64】:求1+...+n
题目:思路+代码:思路:python and操作如果为真,返回最后表达式的值; or 操作如果为真,返回第一个表达式的值时间复杂度:O(n), 递归n个数空间复杂度:O(n),递归n次,需要n个辅助空间class Solution: def sumNums(self, n: int) -> int: # python and操作如果为真,返回最后表达式的值; or 操作如果为真,返回第一个表达式的值 return n and (n + self.s原创 2020-07-22 10:00:54 · 161 阅读 · 0 评论 -
剑指offer【57-2】:和为tar的连续正整数序列
题目:思路+代码:思路:python双指针,只不过这里不是对撞双指针;初始化l=1, r=2,因为题目明确说了结果至少含有两个正整数;如果 sum(l~r) >target; 则l+=1; sum(l~r) < target,则r += 1; 相等则加入到res,并且从l开始没有了其他结果,所以l,r都右移;(疑问:也没说是一定输出两个不想等正整数,如测试案例:tar=2, 应该输出[1,1];但是测试案例没有)时间复杂度:O(target):由于两个指针都是移动单调不减,最多移原创 2020-07-22 09:35:59 · 165 阅读 · 0 评论 -
剑指offer【57】:和为s的两个数字—双指针
题目:思路+代码:思路:由于是有序序列,所以查找两个数可以用首尾对撞指针,进行求和判定;时间复杂度:O(n)空间复杂度:O(1)class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: if not List: return # 思路: # 由于是有序序列,所以查找两个数可以用首尾对撞指针,进行求和判定; i, j原创 2020-07-22 08:40:07 · 188 阅读 · 0 评论 -
剑指offer【53】:0~n-1数组缺失值
题目:思路+代码:法一:暴力法,首尾指针思路:初始化首尾指针,i=0,j=len(nums); 每次移动一个数,判断nums[i] ?= i or nums[j-1] ?= j时间复杂度:O(n)空间复杂度:O(1)class Solution: def missingNumber(self, nums: List[int]) -> int: # 思路:初始化首尾指针,i=0,j=len(nums); 每次移动一个数,判断nums[i] ?= i or nums原创 2020-07-21 10:03:42 · 142 阅读 · 0 评论 -
剑指offer【14-1】:剪绳子
题目:思路+代码:思路:数学推理可以证明,当长度大于3时,划分为每段长度为3时乘积最大;然后考虑:取余后的0,1,2;时间复杂度:O(1)空间复杂度:O(1)import mathclass Solution: def cuttingRope(self, n: int) -> int: # 思路:数学推理可以证明,当长度大于3时,划分为每段长度为3时乘积最大; # 然后考虑:取余后的0,1,2; if n <= 3: #原创 2020-07-20 10:53:05 · 226 阅读 · 0 评论 -
剑指offer【16】:数值的整数次方;(快速幂)
题目:思路+代码:思路: n & 1 等价于 n % 2n >>= 1 等价于 n //= 2利用二分法;每次和自己相乘;因为n//2最终都会==1,所以res *=1 能取最终结果时间复杂度:O(logn)空间复杂度:O(1)class Solution: def myPow(self, x: float, n: int) -> float: # 思路:n & 1 ==1 等价于 n % 2 ==1; #原创 2020-07-20 09:39:41 · 121 阅读 · 0 评论 -
剑指offer【29】:顺时针打印矩阵
题目:代码+思路:思路:设立好上下左右四个边界;每走过一行或一列,边界值发生变化;循环结束条件是左>右;上>下;时间复杂度:O(MxN)空间复杂度:O(1)class Solution: def spiralOrder(self, matrix:[[int]]) -> [int]: # 思路:设立好上下左右四个边界;每走过一行或一列,边界值发生变化; # 循环结束条件是左>右;上>下; if not ma原创 2020-07-20 08:32:34 · 219 阅读 · 0 评论 -
剑指offer【15】:二进制中1的个数
题目:思路:与运算:x & 1 == 1, 则x二进制最后一位是1x & 1 == 0, 则x二进制最后一位是0判断最后一位是否为1,进行count计数,然后进行指针右移;代码:class Solution: def hammingWeight(self, n: int) -> int: # 与运算: # x & 1 == 1, 则x二进制最后一位是1 # x & 1 == 0, 则x二进制原创 2020-07-19 09:38:19 · 227 阅读 · 0 评论 -
剑指offer【43】:1-n中出现1的次数
题目:思路+代码:法一:暴力法。遍历求和(超时)class Solution: def countDigitOne(self, n: int) -> int: # 暴力法超时 if not n: return 0 count = 0 for k in range(1, n+1): while k: temp = k % 10 .原创 2020-07-16 10:13:22 · 115 阅读 · 0 评论 -
剑指offer【39】:数组中次数超过一半的数字
题目:代码:法一:hash 记数法,时间复杂度和空间复杂度都是O(n)class Solution: def majorityElement(self, nums: List[int]) -> int: # hash 记数法,时间复杂度和空间复杂度都是O(n) count_nums = dict() i = 0 for num in nums: if nums[i] in count_nums原创 2020-07-16 09:19:31 · 160 阅读 · 0 评论 -
剑指offer【38】:字符串的排列
题目:代码:法一:全排列模板,把字符串排序后进行全排列class Solution: def permutation(self, s: str) -> List[str]: if not s: return s=list(sorted(s)) res=[] def helper(s,tmp): if not s: res.append(''.join(tmp))原创 2020-07-14 11:41:19 · 199 阅读 · 0 评论 -
剑指offer【21】:调整数组使得奇数在偶数前面
题目:代码:class Solution: def exchange(self, nums: List[int]) -> List[int]: # 思路:i,j分别从左右两边查找,如果i遇到奇数跳过,j遇到偶数也跳过; 每一轮交换nums[i]和nums[j]; # 时间复杂度:O(n) # 空间复杂度:O(1) if not nums: return [] i, j = 0, len(nums) -原创 2020-07-13 11:43:17 · 125 阅读 · 0 评论 -
剑指offer【42】:连续子数组最大和
题目:代码:思路:数组中连续子数组的最大值;可以转化为求以第i个元素结尾的连续子数组的最大和; dp状态:dp[i]表示以当前第i个元素结尾的最大连续子数组和 转移方程:dp[i] = dp[i-1] + nums[i]; 判断dp[i-1]是否大于0即可 初始值:dp[0] = nums[0]class Solution: def maxSubArray(self, nums: List[int]) -> int: ...原创 2020-07-13 10:19:54 · 266 阅读 · 0 评论 -
剑指 Offer 【10- II】. 青蛙跳台阶问题
题目:代码:# 思路:跳上第n个台阶,可以是从n-1跳上也可以从n-2跳上,所以f(n) = f(n-1) + f(n-2); 符合斐波拉契数列公式;只是当f(0)=1,因为一级台阶也有一种跳法class Solution: def numWays(self, n: int) -> int: # 思路:跳上第n个台阶,可以是从n-1跳上也可以从n-2跳上,所以f(n) = f(n-1) + f(n-2); 符合斐波拉契数列公式;只是当f(0)=1,因为一级台阶也原创 2020-07-12 14:45:22 · 185 阅读 · 0 评论 -
剑指 Offer 【10- I】. 斐波那契数列
题目:代码:class Solution: def fib(self, n: int) -> int: # 思路:动态规划求解 # a, b 初始为0,1 a, b = 0, 1 for _ in range(n): a, b = b, a+b return a % 1000000007原创 2020-07-12 10:07:33 · 252 阅读 · 0 评论 -
剑指offer【13】:机器人运动范围;迭代和递归dfs
题目:思路:法一:思路:两个条件,1.机器人可达,说明机器人也只能从目前已知区域边界往外走一步;2.数位求和小于k的区域;迭代对(m,n)中每一个进行判断,def digitsum(n): res = 0 while n: res += n % 10 n //= 10 return resclass Solution: def movingCount(self, m: int, n: int, k: int) ->原创 2020-07-12 09:29:48 · 180 阅读 · 0 评论 -
剑指offer【12】:矩阵中的路径
题目:思路+代码:class Solution: def exist(self, board: List[List[str]], word: str) -> bool: # 暴力用dfs递归暴力查找: # 递归终止条件: # False: 数组越界 or 当前索引和目标字符不匹配 # True:传进来目标字符的索引=len(word)-1 # 当前层递推:在上下左右四个方向进行递归;为了防止原创 2020-07-07 17:09:41 · 145 阅读 · 0 评论 -
剑指offer【50】:第一次只出现的字符
题目:思路+代码:class Solution: def firstUniqChar(self, s: str) -> str: # 第一遍遍历字符串,if not c 则 true; 第二遍遍历dict;输出第一个v=true的k if not s: return ' ' temp = {} for c in s: temp[c] = not c in temp.原创 2020-07-07 15:54:15 · 162 阅读 · 0 评论 -
剑指offer【35】:复杂链表的复制
题目:思路+代码:# 思路:递归dfs, 初始化dict:{node: copy_node}; # 递归结束条件:当前节点none或者节点已经存在则return dict# 当前层递归:根据head值,建立节点; node.next和node.random递归建立;# 返回值:return 当前层节点(此时节点已经建成class Solution: def copyRandomList(self, head: 'Node') -&原创 2020-07-07 15:29:18 · 201 阅读 · 0 评论 -
剑指offer【59-1】:滑动窗口的最大值
题目:思路+代码:思路1. 类似拿到栈中最小值时维持一个非严格递增辅助栈,这里也是维护一个单调队列(用的list)滑块移动,对滑块最左边i,最右边j判值大小,因为每次滑块进来值索引是j+1, 出去值索引i-1;然后保证当前滑块的最大值出现在单调队列的队首;所以每次进来新的值,都需要从队尾比较进(维持一个单调队列),因为如果只和队首最大比较,如果队首元素pop后,后续队列为空了;class Solution: def maxSlidingWindow(self, nums: L原创 2020-07-01 11:16:48 · 224 阅读 · 0 评论 -
剑指offer【68】:二叉树最近祖先节点
题目:思路+代码:思路:找就近的祖先节点,采用递归方法,考虑3种边界情况,边界情况:1. p,q在左右两边2. p,q都在左子树或右子树3. p或q有一个是根节点递归结束:如果not root, 找到节点为p或q,return root当前层递归:返回值:在左子树和右子树进行递归,并判断如果左子树返回值为空,则说明左子树不存在,则返回右子树,同理右子树; 如果左右子树同时存在值则返回 root为最近祖先节点class Solution: def lowestComm.原创 2020-07-01 09:37:01 · 197 阅读 · 0 评论 -
剑指offer【68】:二叉搜索树的最近祖先节点
题目:思路+代码:思路一:非递归迭代 二叉树节点值唯一,且为二叉搜索树 非递归写法: 所以根据值大小不断从根节点,往下一层判断;直到p,q分布在 子树根节点的左右 时间复杂度:O(n),当二叉树为链表时,root为某一个节点的直接根节点 空间复杂度:O(1)思路二:递归写法 递归写法 时间复杂度:O(n),...原创 2020-06-30 12:22:19 · 234 阅读 · 0 评论 -
剑指offer【40】:topk数,小顶堆,快排实现
题目:思路+代码:思路:法一:调用python sorted 方法 时间复杂度:因为sorted也是使用饿快速排序实现饿,O(nlogn) 空间复杂度:额外需要空间O(logn)法二:python 小顶堆实现 时间复杂度:n-k个数,维护小顶堆时间复杂度是O(logn), O(nlogk) 空间复杂度:小顶堆只有k个数,O(logk)法三:使用***,第一次确定的数看跟k比较;因为***每一次能确定基准...原创 2020-06-30 10:12:59 · 582 阅读 · 0 评论 -
剑指offer【36】:二叉搜索树与双向链表
题目:思路+代码:class Solution: # 思路:二叉搜索树中序遍历才是递增,又因为要求是双向链表,cur.left= self.pre; self.pre.right=cur # 特例:如果root不存在,return # 初始化self.pre=None # 递归调用中序遍历,构建除首尾两个节点之外的双向链表; # 中序遍历递归结束后,设置head.left = pre; pre.right=head,构成循环链表原创 2020-06-29 21:04:53 · 317 阅读 · 0 评论 -
剑指 Offer 【37】. 序列化二叉树
题目:思路+代码:思路:1.序列化,采用层序遍历;这里添加null节点操作,是判断节点是否为空添加,所以res确实有多添加null2.反序列化:先构建根节点,遍历有效的节点val,每次pop一个节点就添加它的左右节点;class Codec: def serialize(self, root): """Encodes a tree to a single string. :type root: TreeNode原创 2020-06-29 10:13:55 · 174 阅读 · 0 评论 -
剑指offer【34】:二叉树和为某一值的路径
二叉树和为某个值的路径原创 2020-06-28 19:39:58 · 174 阅读 · 0 评论 -
剑指offer【26】:判读B是否是A的子结构
题目:思路+代码:class Solution: # 思路:逆推法,要判断B是否是A子结构就是判断,拿B分别和A, A.left, A.right 开始比较; # 递归思路: # 1.递归结束判断:B越过叶子节时True, B越过叶子节点时,False, A.val != B.val 时False # 2.返回值:当A,B都存在时,递归判断A.left,A.right def isSubStructure(self, A: TreeNode,原创 2020-06-26 15:03:02 · 183 阅读 · 0 评论 -
剑指offer【7】:重构二叉树,递归思路
思路:最终是要重构二叉树;1. 确定子树的根节点:递归(当前子树根在前序中的索引,left,right)每层传入根节点在前序遍历的索引;在中序遍历中拿到根节点的索引,建立 当前子树的根节点2. 确定当前子树的左节点:递归(左子树的根节点在前序索引, left, 当前根在中序索引-1)3. 确定当前子树的右节点:递归(右子树的根节点在前序索引, 当前根在中序索引+1, right)其他:为了方便查询中序中节点的索引,建立map(节点:idx)建立递归思路:递归结束:子树的左边界idx >原创 2020-06-26 11:00:48 · 209 阅读 · 0 评论 -
剑指offer【54】:返回二叉搜索树的第K大节点
题目:思路+代码:思路一:pythonic写法:三行代码,中序遍历二叉树返回遍历listclass Solution: def kthLargest(self, root: TreeNode, k: int) -> int: # pythonic写法 def dfs(root): return dfs(root.left) + [root.val] + dfs(root.right) if root else []原创 2020-06-25 00:47:51 · 191 阅读 · 0 评论 -
剑指offer【55】层序遍历 后序遍历返回二叉树深度
题目:思路+代码:层序遍历:层序遍历计算二叉树层数,时间复杂度O(n),空间复杂度O(n)class Solution: def maxDepth(self, root: TreeNode) -> int: # # 层序遍历计算二叉树层数,时间复杂度O(n),空间复杂度O(n) if not root: return 0 depth = 0 node_list = [] node_原创 2020-06-19 11:45:38 · 323 阅读 · 0 评论 -
剑指offer【28】:判断对称二叉树
题目:思路+代码:思路:递归判断,left.val?=right.val递归终止条件:1.如果是叶子节点,那么returntrue;2.如果单个子树不存在左或右节点,或者值不相等returnFalse;递推:L.value?=right.val返回值:分布返回左右子树判断class Solution: def isSymmetric(self, root: TreeNode) -> b...原创 2020-06-19 10:29:17 · 142 阅读 · 0 评论 -
剑指offer【56-2】:列表中一个不重复的数和其他数每个数重复三次
题目:思路+代码:class Solution: def singleNumber(self, nums: List[int]) -> int: # 遍历求和每个数字32位,然后对每一位对3进行取余留下了的数字便只留下出现一次的数 if not nums: return count = [0] * 32 for num in nums: for i in range(原创 2020-06-19 09:39:32 · 193 阅读 · 0 评论 -
剑指offer【11】 旋转数组的最小数字
题目:思路+代码:class Solution: def minArray(self, numbers: List[int]) -> int: # # 时间复杂度:O(n); 空间复杂度:O(1), 遍历数组 if not numbers: return min_num = numbers[0] for i in range(len(numbers)): print原创 2020-06-19 00:31:28 · 242 阅读 · 0 评论 -
剑指offer【56-1】:找到列表中不重复的两个数字
题目:思路+代码:class Solution: def singleNumbers(self, nums: List[int]) -> List[int]: if not nums: return [] # 思路: # 1. 首先当a,b不相等时,全员异或的结果 == a ^ b,先得到全员异或结果 # 2. 选取全员异或结果的二进制的某一位1,则代表在这一位,a和b的异或结果不同原创 2020-06-18 22:15:00 · 313 阅读 · 0 评论 -
剑指offer【4】.二维数组的遍历查找
题目:代码+思路:class Solution: def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool: # 从左下角开始搜索,如果比tar大则,往右,如果小则往上 if not matrix: return False n, m = len(matrix), len(matrix[0]) ro原创 2020-06-18 12:10:51 · 241 阅读 · 0 评论