目录

一、剑指 Offer 14- I. 剪绳子

1.1 题求

1.2 求解

1.3 解答

二、剑指 Offer II. 剪绳子 II

2.1 题求

2.2 求解

三、剑指 Offer 39. 数组中出现次数超过一半的数字

3.1 题求

3.2 求解

3.3 解答

四、剑指 Offer 43. 1~n 整数中 1 出现的次数

4.1 题求

4.2 求解

4.3 解答

五、剑指 Offer 44. 数字序列中某一位的数字

5.1 题求

5.2 求解

5.3 解答

六、剑指 Offer - II. 和为 s 的连续正数序列

6.1 题求

6.2 求解

6.3 解答

七、剑指 Offer 62. 圆圈中最后剩下的数字 ☆

7.1 题求

7.2 求解

7.3 解答

八、剑指 Offer 66. 构建乘积数组

8.1 题求

8.2 求解

8.3 解答


一、剑指 Offer 14- I. 剪绳子

1.1 题求

1.2 求解

法一:3 的幂次

# 24ms - 98.38%
class Solution:def cuttingRope(self, n: int) -> int:if n == 3:return 2elif n == 4:return 4max_product = 1# 遍历所有 3 的幂组合for i in range(1, n//3+1):cur_product = int(math.pow(3, i))  ### math.pow 比 ** 快非常多!!y = n - 3 * iif y > 0:cur_product *= y if cur_product > max_product:max_product = cur_productreturn max_product

官方说明

# 24ms - 98.38%
class Solution:def cuttingRope(self, n: int) -> int:if n <= 3: return n - 1# 商 与 余数a, b = n // 3, n % 3# 余数为 0if b == 0: return int(math.pow(3, a))# 余数为 1if b == 1: return int(math.pow(3, a - 1) * 4)  # 即 × 2×2, 因为 2×2 > 3×1# 余数为 2return int(math.pow(3, a) * 2)  # 即 × 2

1.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5v1026/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5vyva2/


二、剑指 Offer II. 剪绳子 II

2.1 题求

2.2 求解

官方说明

# 20ms - 99.76%
class Solution:def cuttingRope(self, n: int) -> int:if n <= 3: return n - 1a, b, p, x, rem = n // 3 - 1, n % 3, 1000000007, 3 , 1while a > 0:if a % 2: rem = (rem * x) % px = x ** 2 % pa //= 2if b == 0: return (rem * 3) % p # = 3^(a+1) % pif b == 1: return (rem * 4) % p # = 3^a * 4 % preturn (rem * 6) % p # = 3^(a+1) * 2  % p
# 28ms - 96.05%
# 由于语言特性,Python 可以不考虑大数越界问题
class Solution:def cuttingRope(self, n: int) -> int:if n <= 3: return n - 1a, b, p = n // 3, n % 3, 1000000007if b == 0: return 3 ** a % pif b == 1: return 3 ** (a - 1) * 4 % preturn 3 ** a * 2 % p

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5vcapc/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5vbrri/


三、剑指 Offer 39. 数组中出现次数超过一半的数字

3.1 题求

3.2 求解

法一:哈希表

# 40ms - 82.66%
class Solution:def majorityElement(self, nums: List[int]) -> int:half_len = len(nums) // 2hashmap = {}for n in nums:if hashmap.get(n) is None:hashmap[n] = 0hashmap[n] += 1if hashmap[n] > half_len:return nreturn -1

官方说明

# 40ms - 82.66%
class Solution:def majorityElement(self, nums: List[int]) -> int:### 摩尔投票法 ###votes = 0for num in nums:# 当票数 votes = 0 时, 假设当前数字 num 是众数if votes == 0: x = num# 当 num = x 时, 票数 votes +1; 当 num != x 时, 票数 votes -1votes += 1 if num == x else -1return x'''例子:[1,  2,  3,  2,  2,  2,  5,  4,  2]众数: 1,  1,  3,  3,  2,  2,  2,  2,  2票数:+1, -1, +1, -1, +1, +1, -1, -1, +1'''

class Solution:def majorityElement(self, nums: List[int]) -> int:votes, count = 0, 0for num in nums:if votes == 0: x = numvotes += 1 if num == x else -1# 验证 x 是否为众数for num in nums:if num == x: count += 1return x if count > len(nums) // 2 else 0  # 当无众数时返回 0

3.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/99iy4g/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/99ussv/


四、剑指 Offer 43. 1~n 整数中 1 出现的次数

4.1 题求

4.2 求解

官方说明 (困难)

# 24ms - 97.87%
class Solution:def countDigitOne(self, n: int) -> int:digit, res = 1, 0high, cur, low = n // 10, n % 10, 0while high != 0 or cur != 0:# 当 cur = 0 时, 当前位 cur 的 1 的出现次数只由高位 high 决定if cur == 0: res += high * digit# 当 cur = 1 时, 当前位 cur 的 1 的出现次数由高位 high 和低位 low 决定elif cur == 1: res += high * digit + low + 1# 当 cur = 2, 3, ⋯ , 9 时, 当前位 cur 的 1 出现次数只由高位 high 决定else: res += (high + 1) * digitlow += cur * digit  # 将 cur 加入 low ,组成下轮 lowcur = high % 10     # 下轮 cur 是本轮 high 的最低位high //= 10         # 将本轮 high 最低位删除,得到下轮 highdigit *= 10         # 位因子每轮 × 10return res 

4.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/572jxs/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/57nyhd/


五、剑指 Offer 44. 数字序列中某一位的数字

5.1 题求

5.2 求解

官方说明

digit, start, count = 1, 1, 9
while n > count:n -= countstart *= 10 # 1, 10, 100, ...digit += 1  # 1,  2,  3, ...count = 9 * start * digit # 9, 180, 2700, ...

num = start + (n - 1) // digit

s = str(num)  # 转化为 string
res = int(s[(n - 1) % digit])  # 获得 num 的 第 (n - 1) % digit 个数位,并转化为 int

# 32ms - 76.65%
class Solution:def findNthDigit(self, n: int) -> int:digit, start, count = 1, 1, 9while n > count:  # 1. 确定 n 所在数字的位数, 记为 digitn -= countstart *= 10digit += 1count = 9 * start * digitnum = start + (n - 1) // digit  # 2. 确定 n 所在的数字, 记为 numreturn int(str(num)[(n - 1) % digit])  # 3. 确定 n 是 num 中的哪一数位, 并返回结果

5.3 解答

# 28ms - 90.64%
class Solution:def findNthDigit(self, n: int) -> int:def count_of_integers(digit):''' 计算 digit 位数共有多少个 '''if digit == 1:return 10return int(math.pow(10, digit-1)) * 9def begin_number(digit):''' 给出 digit 位数的首个数字, 如 0, 10, 100 ...'''if digit == 1:return 0return int(math.pow(10, digit-1))def digit_at_index(index, digit):''' 已知 index 所在数字是 digit 位数, 找出准确的数字 '''number = begin_number(digit) + index / digit# 从右往左的相对位置 / 移动次数index_from_right = digit - index % digit# 从右往左取 number 的目标值for _ in range(1, index_from_right):number /= 10return int(number % 10)# 负数if n < 0:return -1# 位数digits = 1while True:# digits 位数的数字共有 numbers 个numbers = count_of_integers(digits)  # digits 位数的数字共占 p 个数的位置p = numbers * digits# 若当前剩余数的位置 n 小于 p, 则 n 就在范围内if n < p:# 找到return digit_at_index(n, digits)n -= pdigits += 1  # 位数 +1return -1

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/57vzfh/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/57w6b3/


六、剑指 Offer - II. 和为 s 的连续正数序列

6.1 题求

6.2 求解

法一:暴力法

# 276ms - 19.78%
class Solution:def findContinuousSequence(self, target: int) -> List[List[int]]:if target < 3:return []''' 举例target = 9target array:  1, 2, 3, 4, 5, 6, 7, 8, 9left index:    0  1  2  3  4  5  6  7  8half = target // 2 = 9 // 2 = 4so, left < half,  right < half'''half = target // 2   # 起点最多可达的数值left = 0res = []while left < half:# 右指针summ = right = left+1while summ < target:  # right 至多到 half (比 left 多 1), 故无需约束right += 1summ += right# 连续正整数序列和满足要求if summ == target:res.append([i for i in range(left+1, right+1)])# 左指针left += 1return res

官方说明

# 144ms - 42.56%
class Solution:def findContinuousSequence(self, target: int):if target < 3:return []i, j, res = 1, 2, []while i < j:# 直接根据公式计算右边界 jj = (-1 + (1 + 4 * (2 * target + i * i - i)) ** 0.5) / 2# 若计算结果为整数, 则存在可行的右边界 jif j == int(j):res.append([k for k in range(i, int(j)+1)])# 左边界 i +1i += 1return res

# 88ms - 82.65%
class Solution:def findContinuousSequence(self, target: int) -> List[List[int]]:if target < 3:return []i, j, s, res = 1, 2, 3, []while i < j:if s == target:res.append(list(range(i, j + 1)))if s >= target:s -= ii += 1else:j += 1s += jreturn res

6.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/eufzm7/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/eth6p5/


七、剑指 Offer 62. 圆圈中最后剩下的数字 ☆

7.1 题求

7.2 求解

官方说明

# 60ms - 95.16%
class Solution:def lastRemaining(self, n: int, m: int) -> int:x = 0  # 恒有:dp[1] = 0for i in range(2, n+1):x = (x + m) % i  # 状态转移公式:dp[i] = (dp[i-1] + m) % ireturn x

7.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/oxrkot/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/oxp3er/


八、剑指 Offer 66. 构建乘积数组

8.1 题求

8.2 求解

官方说明

# 60ms - 73.32%
class Solution:def constructArr(self, a: List[int]) -> List[int]:b, tmp = [1] * len(a), 1# 下三角for i in range(1, len(a)):b[i] = b[i-1] * a[i-1]    # 上三角for i in range(len(a)-2, -1, -1):tmp *= a[i+1]             b[i] *= tmp  # 下三角 * 上三角return b

8.3 解答

参考资料:

《剑指 Offer 第二版》

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/57d8cm/

https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/570i11/

【图解算法数据结构】(九)数学相关推荐

  1. 力扣K神图解算法数据结构解析04

    力扣K神图解算法数据结构点这里 四.搜索与回溯算法 DFS,本质是递归 递推参数 终止条件 递推工作 回溯 BFS,本质是队列 queue<int> que; que.push(第一个参数 ...

  2. 力扣K神图解算法数据结构解析10

    力扣K神图解算法数据结构点这里 十.分治算法 剑指07,重建二叉树 //时间O(n),空间O(n) //自己一直觉得这道题很难,没想到还是能够拿下,其实理论也清楚,前序遍历和中序遍历 //关键如下 / ...

  3. 图解算法数据结构刷题笔记02

    系列文章目录 图解算法数据结构刷题笔记01 本篇文章目录 系列文章目录 前言 1.剑指 Offer 05. 替换空格 2.剑指 Offer 06. 从尾到头打印链表 3.剑指 Offer 09. 用两 ...

  4. 【Code Pratice】—— 《图解算法数据结构 ~ 第一章》

    简述 本文主要记录了学习<图解算法数据结构>一书中"数据结构"章节所做练习题的笔记,记录其中的思路以及碰到的问题等.因为学习的这本书是在leetcode上的,但是感觉l ...

  5. 【图解算法数据结构】(二)动态规划

    目录 序.递归和循环 一.剑指 Offer 10- I. 斐波那契数列 1.1 题求 1.2 求解 1.3 解说 二.剑指 Offer 10- II. 青蛙跳台阶问题 2.1 题求 2.2 求解 2. ...

  6. 力扣-图解算法数据结构

    常见的数据结构可分为「线性数据结构」与「非线性数据结构」,具体为:「数组」.「链表」.「栈」.「队列」.「树」.「图」.「散列表」.「堆」. 数组 数组是将相同类型的元素存储于连续内存空间的数据结构, ...

  7. 【图解算法数据结构】数据结构篇 + Java代码实现

    文章目录 一.替换空格 二.从尾到头打印链表 三.用两个栈实现队列 四.表示数值的字符串 五.反转链表 六.包含 min 函数的栈 七.复杂链表的复制 八.II. 左旋转字符串 九.I. 滑动窗口的最 ...

  8. 力扣-图解算法数据结构-剑指 Offer 05. 替换空格

    题目要求 力扣题解 代码 /*** @program: mydemo* @description: 剑指 Offer 05. 替换空格* @author: Mr.zeng* @create: 2021 ...

  9. 09_JavaScript数据结构与算法(九)字典

    JavaScript 数据结构与算法(九)字典 字典 字典特点 字典存储的是键值对,主要特点是一一对应. 比如保存一个人的信息 数组形式:[19,"Tom", 1.65],可通过下 ...

最新文章

  1. C++后端向JS前端转换
  2. 第十六期:简单的介绍一下大数据中最重要的MapReduce
  3. 如何看待蒂姆·库克在苹果的地位
  4. Linux基础学习六:Nginx的使用教程
  5. docker删除所有镜像_Docker 常用命令
  6. iOS学习笔记(1)— UIView 渲染和内容管理
  7. python julia go_Python的四个挑战者:Swift、Go、Julia、R
  8. html考勤表格模板,Excel员工考勤表模板如何撤销工作表保护?
  9. 可视化数据库监控警报工具 —— Sampler
  10. 搜索引擎duckduckgo
  11. 算法-枚举法-已知xyz + yzz = 532,其中x、y、z都是数字(0~9),编写一个程序求出x、y、z分别代表什么数字。
  12. 拼多多又起一事:因为看到同事被抬上救护车我被拼多多开除了
  13. GoodSync(最好的文件同步软件)
  14. 微信小程序新手留言板
  15. address localhost:8080 is already in use(端口被占用)Windows系统问题解决
  16. 周哲_java软件工程师 简历
  17. 解决不同部门间防火墙的需求问题(转)
  18. html仿今日头条下拉刷新,小程序 仿今日头条 带滑动切换的文章列表
  19. 不会写Python代码如何抓取豆瓣电影 Top 250
  20. Java 诊断工具-Arthas(转载)

热门文章

  1. 100BASE-T1 /1000BASE-T1 车载以太网转换器产品汇总
  2. Qt - QTChart绘制图表
  3. 阿里大数据之路:数据管理篇大总结
  4. <read papers>学术论文的基金项目和研究成果格式怎么标注?
  5. ROS2 基础概念 节点
  6. logstash读取kafka所有topics 自动创建es 索引
  7. ubuntu 16.04安装TP-LINK TL-WDN5200H无线USB网卡驱动
  8. 小程序对企业、商家有哪些方面的好处?
  9. Spring @Value读取系统环境变量
  10. 【硬件和驱动相关】wifi设备没有工作 ubuntu18.0.4 无线网卡 intel 6 AX200