Question Bank

本贴最后更新于 579 天前,其中的信息可能已经事过境迁
  1. ⚙ Question Template1
  2. 📄 [975] 奇偶跳2
  3. 📄 [1155] 掷骰子等于目标和的方法数5
  4. 📄 [1726] 同积元组6
  5. 📄 [2530] 执行 K 次操作后的最大分数7


  1. Question Template

    [id] Question Name

    • address

      question address

    • tags

      ​#leetcode#​

    • solution explain

    • solution code

      • Python3

  2. [975] 奇偶跳

    • address

      [975] 奇偶跳

    • tags

      ​#leetcode#​ #alg/动态规划#​ ​#alg/单调栈#​

    • solution explain

      在给定的数组中,每个位置使用奇数跳跃或者偶数跳跃,落点都是可以唯一确定的。确定了在每个位点奇偶跳的落点,即可判断从每个点能否最终到达末尾。

      奇数跳,只不过是在后续大于等于自己的元素中找值最接近的位置;
      反之偶数跳,是在小于等于自己的元素中找最接近自己的元素。

      • 单调栈解法

        统计在 i​点的奇数跳落点时:

        将原始数组 A​的索引按位置的数值从小到大进行排序。即 B = sorted(range(N), key = lambda i: A[i])

        这样就可以知道每个位置与之数值最接近的值(A[B[1]]与之最接近的值是 A[B[2]]),但是不能这样这样粗暴认为 A[B[n+1]]就是 A[B[i]]的奇数跳落点坐标,因为 B[n+1]和 B[n]还必须满足 B[n+1] > B[n],即索引位置关系。

        因为 A[B[n]]这个数组已经是升序,于是我们就可以总结:“==在 B 数组中 B[n]之后首个大于 B[n]的值 B[m]即为 A[B[n]]的奇数跳落点 A 坐标 A[B[m]]==”(细细品~) 相当于在 B 数组中寻找递减序列

        使用一个单调栈即可实现,遍历 B,保证栈内元素由低至顶递减,当新元素 Y 大于栈顶元素时,弹出栈顶 X,即 A 数组中索引为 X 的点奇数跳落点索引为 Y,遍历完成后仍然在栈中的元素,表明在 A 数组中这些索引位置处无法进行奇数跳,落点记为 None。详见 Python3 - 单调栈1make

        偶数跳同理,只需将元素取负即可(小于等于并最接近自己的元素,取负后成为大于等于并最接近自己)。

      在奇偶数跳跃落点两个数组的基础上即可求出 DP 数组,dp[i][0]​表示能否从 i 处通过偶数跳最终到达终点,dp[i][1]​表示能否从 i 处通过奇数跳最终到达终点,且 dp[len-1][0] = dp[len-1][1] = 1​,从末尾往前推导即可完善整个 DP 数组,规则为:

      1. 如果 i 处能进行偶数跳(即 even[i] is not None),此处能否偶数跳最终最终到达终点取决于跳跃落点处能否通过奇数跳并最终到达终点(即 dp[i][0] = dp[even[i]][1]​)
      2. 奇数跳与上同理。

      因为起始跳跃为奇数跳,对 dp[][1]​进行求和即为题解。

      • TreeMap​解法

        单调栈解法1中我们所做的事情 TreeMap​提供了 API:lowerKey(v)​和 higherKey(v)​,即为略小于 v 的值,略大于 v 的值。

    • solution code

      • Python3 - 单调栈

        class Solution(object): def oddEvenJumps(self, A): N = len(A) def make(B): ans = [None] * N stack = [] # invariant: stack is decreasing for i in B: while stack and i > stack[-1]: ans[stack.pop()] = i stack.append(i) return ans B = sorted(range(N), key = lambda i: A[i]) oddnext = make(B) B.sort(key = lambda i: -A[i]) evennext = make(B) odd = [False] * N even = [False] * N odd[N-1] = even[N-1] = True for i in range(N-2, -1, -1): if oddnext[i] is not None: odd[i] = even[oddnext[i]] if evennext[i] is not None: even[i] = odd[evennext[i]] return sum(odd) 作者:LeetCode 链接:https://leetcode.cn/problems/odd-even-jump/solutions/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
      • Java - TreeMap 解法

        class Solution { public int oddEvenJumps(int[] A) { int N = A.length; if (N <= 1) return N; boolean[] odd = new boolean[N]; boolean[] even = new boolean[N]; odd[N-1] = even[N-1] = true; TreeMap<Integer, Integer> vals = new TreeMap(); vals.put(A[N-1], N-1); for (int i = N-2; i >= 0; --i) { int v = A[i]; if (vals.containsKey(v)) { odd[i] = even[vals.get(v)]; even[i] = odd[vals.get(v)]; } else { Integer lower = vals.lowerKey(v); Integer higher = vals.higherKey(v); if (lower != null) even[i] = odd[vals.get(lower)]; if (higher != null) { odd[i] = even[vals.get(higher)]; } } vals.put(v, i); } int ans = 0; for (boolean b: odd) if (b) ans++; return ans; } } 作者:LeetCode 链接:https://leetcode.cn/problems/odd-even-jump/solutions/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    • Python3 - 单调栈
    class Solution(object): def oddEvenJumps(self, A): N = len(A) def make(B): ans = [None] * N stack = [] # invariant: stack is decreasing for i in B: while stack and i > stack[-1]: ans[stack.pop()] = i stack.append(i) return ans B = sorted(range(N), key = lambda i: A[i]) oddnext = make(B) B.sort(key = lambda i: -A[i]) evennext = make(B) odd = [False] * N even = [False] * N odd[N-1] = even[N-1] = True for i in range(N-2, -1, -1): if oddnext[i] is not None: odd[i] = even[oddnext[i]] if evennext[i] is not None: even[i] = odd[evennext[i]] return sum(odd) 作者:LeetCode 链接:https://leetcode.cn/problems/odd-even-jump/solutions/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    • 单调栈解法

    统计在 i​点的奇数跳落点时:

    将原始数组 A​的索引按位置的数值从小到大进行排序。即 B = sorted(range(N), key = lambda i: A[i])

    这样就可以知道每个位置与之数值最接近的值(A[B[1]]与之最接近的值是 A[B[2]]),但是不能这样这样粗暴认为 A[B[n+1]]就是 A[B[i]]的奇数跳落点坐标,因为 B[n+1]和 B[n]还必须满足 B[n+1] > B[n],即索引位置关系。

    因为 A[B[n]]这个数组已经是升序,于是我们就可以总结:“==在 B 数组中 B[n]之后首个大于 B[n]的值 B[m]即为 A[B[n]]的奇数跳落点 A 坐标 A[B[m]]==”(细细品~) 相当于在 B 数组中寻找递减序列

    使用一个单调栈即可实现,遍历 B,保证栈内元素由低至顶递减,当新元素 Y 大于栈顶元素时,弹出栈顶 X,即 A 数组中索引为 X 的点奇数跳落点索引为 Y,遍历完成后仍然在栈中的元素,表明在 A 数组中这些索引位置处无法进行奇数跳,落点记为 None。详见 Python3 - 单调栈1make

    偶数跳同理,只需将元素取负即可(小于等于并最接近自己的元素,取负后成为大于等于并最接近自己)。

  3. [1155] 掷骰子等于目标和的方法数

    • address

      [1155] 掷骰子等于目标和的方法数

    • tags

      ​#leetcode#​ ​#alg/动态规划#​

    • solution explain

      🥰 很经典的动态规划题

      首先按题意 n​个 k​面骰子一共能产生种结果,要从这些结果中筛选出结果为 target​的结果数量。

      k​可以视为常量,利用动态规划思想拆分问题:

      n 个骰子能组合出 target 的结果数量 = n-1 个骰子能组合出 target - 1 的结果数量(假设第 n 个骰子掷出点数为 1) + ... + n-1 个骰子能组合出 target - k 的结果数量(假设第 n 个骰子掷出点数为 k)

      这样转换公式就显而易见了:

      因为条件限制了 1 <= n,k <= 30​,则初始状态就是,当我们只有一个骰子时,所有小于等于**k**​的 target, 其结果都是 1,反之则为 0

      这样从上直下,就可以推算出整个 dp 数组,dp[n][target] = 即为所求

    • solution code

      • Python3

        class Solution: def numRollsToTarget(self, n: int, k: int, target: int) -> int: dp = [[0] * (target + 1) for _ in range(n + 1)] for i in range(1, target + 1): if k >= i: dp[1][i] = 1 for cnt in range(2, n + 1): for sum in range(1, target + 1): for pick in range(1, k + 1): if sum > pick: dp[cnt][sum] += dp[cnt - 1][sum - pick] dp[cnt][sum] %= (10 ** 9 + 7) return dp[-1][-1]

        Tips: 在确定了 target 和 k 之后,可以通过大小关系对循环次数进行缩减,甚至可以对 dp 数组进行压缩,以优化空间占用和运行时间。

  4. [1726] 同积元组

    • address

      [1726] 同积元组

    • tags

      ​#leetcode#​ #alg/哈希表#​

    • solution explain

      在所给的数组中均为不同的正整数,任意 4 个符合要求的数字,通过排列组合即可形成 8 个元组。

      统计数组中所有的乘积(共 len(nums) * (len(nums) - 1)​个乘积),这些乘积结果中必然有相同的,那么即为一组题解。

      针对每一个乘积结果,统计数对个数,即可得出 a * b = c * d = product​的题解数:

      例如有`n`​个数对乘积均为`product`​,那么从`n`​个数对中任意取出两个即可组成一个题解,共有$C_n^2$种取法即$\frac{n(n - 1)}{2}$

      将题解个数 * 8 即为最终元组个数。

    • solution code

      • Python3

        class Solution: def tupleSameProduct(self, nums: List[int]) -> int: res = 0 productCount: dict = {} for i in range(len(nums)): for j in range(i + 1, len(nums)): product = nums[i] * nums[j] productCount[product] = productCount.get(product, 0) + 1 for _, cnt in productCount.items(): res += int((cnt * (cnt - 1)) / 2) return res * 8

  5. [2530] 执行 K 次操作后的最大分数

    • address

      [2530] 执行 K 次操作后的最大分数

    • tags

      ​#leetcode#​​​ #alg/堆(优先队列)#​​​ #alg/贪心#​​​

    • solution explain

      看到“最”即联想贪心算法,每次都从待选列表(nums​)中取出最大的元素即为目标实现。

      Q: 每次元素变化后如何快速从其中找到最值元素?

      A: 大/小根堆(优先队列)

    • solution code

      • Python3

        from heapq import heapify, heappush, heappop class Solution: def maxKelements(self, nums: List[int], k: int) -> int: nums = [-num for num in nums] heapify(nums) res: int = 0 for _ in range(k): top = heappop(nums) res += -top heappush(nums, -((-top + 2) // 3)) return res

        Python 中 heapify​​默认小根堆,通过对元素进行取反实现所需的“大根堆”,每次取出堆顶值 top​​,然后进行 (-top+2) // 3​​【等效 ceil(top / 3)​​】,将结果取负后重新 push 进堆中。

      • Java

        使用 PriorityQueue​作为堆的替代实现

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    557 引用 • 675 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    246 引用 • 1338 回帖 • 1 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 18 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 762 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 399 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 3 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 830 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖 • 3 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 650 关注
  • Visio
    1 引用 • 2 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 5 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2040 回帖
  • 996
    13 引用 • 200 回帖 • 5 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 1 关注
  • gRpc
    11 引用 • 9 回帖 • 95 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 738 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 77 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 2 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 552 关注
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    93 引用 • 113 回帖
  • 印象笔记
    3 引用 • 16 回帖
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    200 引用 • 543 回帖 • 2 关注
  • 导航

    各种网址链接、内容导航。

    44 引用 • 177 回帖 • 1 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 634 关注