当前位置: 首页 > news >正文

LeetCode题练习与总结:拼接最大数--321

一、题目描述

给你两个整数数组 nums1 和 nums2,它们的长度分别为 m 和 n。数组 nums1 和 nums2 分别代表两个数各位上的数字。同时你也会得到一个整数 k

请你利用这两个数组中的数字中创建一个长度为 k <= m + n 的最大数,在这个必须保留来自同一数组的数字的相对顺序。

返回代表答案的长度为 k 的数组。

示例 1:

输入:nums1 = [3,4,6,5], nums2 = [9,1,2,5,8,3], k = 5
输出:[9,8,6,5,3]

示例 2:

输入:nums1 = [6,7], nums2 = [6,0,4], k = 5
输出:[6,7,6,0,4]

示例 3:

输入:nums1 = [3,9], nums2 = [8,9], k = 3
输出:[9,8,9]

提示:

  • m == nums1.length
  • n == nums2.length
  • 1 <= m, n <= 500
  • 0 <= nums1[i], nums2[i] <= 9
  • 1 <= k <= m + n

二、解题思路

  1. 创建一个辅助函数monoInc,该函数能够从一个数组中找出长度为k的最大单调递增子序列。这个子序列是在保持原数组元素相对顺序的情况下得到的。
  2. 创建另一个辅助函数merge,该函数能够合并两个单调递增的数组,并返回一个长度为k的最大单调递增数组。
  3. maxNumber函数中,遍历所有可能的从nums1中取i个元素,从nums2中取k-i个元素的情况(i的取值范围是0k,并且要满足i <= nums1.lengthk-i <= nums2.length),然后使用merge函数合并这些元素,并保留合并后的最大数组。

三、具体代码

class Solution {public int[] maxNumber(int[] nums1, int[] nums2, int k) {int m = nums1.length, n = nums2.length;int[] ans = new int[k];for (int i = Math.max(0, k - n); i <= k && i <= m; ++i) {int[] candidate = merge(monoInc(nums1, i), monoInc(nums2, k - i), k);if (greater(candidate, 0, ans, 0)) {ans = candidate;}}return ans;}private int[] monoInc(int[] nums, int k) {int n = nums.length;int[] res = new int[k];for (int i = 0, j = 0; i < n; ++i) {while (n - i > k - j && j > 0 && res[j - 1] < nums[i]) {--j;}if (j < k) {res[j++] = nums[i];}}return res;}private int[] merge(int[] nums1, int[] nums2, int k) {int[] res = new int[k];for (int i = 0, j = 0, r = 0; r < k; ++r) {res[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];}return res;}private boolean greater(int[] nums1, int i, int[] nums2, int j) {while (i < nums1.length && j < nums2.length && nums1[i] == nums2[j]) {++i; ++j;}return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]);}
}

在这段代码中:

  • monoInc函数通过贪心算法,维护一个单调递增的序列。
  • merge函数比较两个单调递增序列的元素,并合并成一个新的单调递增序列。
  • greater函数比较两个序列的元素,如果第一个序列在某个位置上的元素更大,或者第二个序列已经结束,则返回true
  • maxNumber函数遍历所有可能的组合,并保留合并后的最大数组。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • maxNumber 函数:

    • 外层循环的次数取决于nums1nums2的长度以及k的值,最坏情况下,循环次数为k
    • 在每次循环中,我们调用monoInc两次和merge一次。
    • greater函数在merge中被调用k次。
  • monoInc 函数:

    • 对于每个数组nums,我们进行一次遍历,时间复杂度为O(n),其中n是数组的长度。
    • 在每次遍历中,可能需要执行一个内部循环来移除不满足条件的元素,最坏情况下,内部循环可能执行k次。
    • 因此,monoInc函数的时间复杂度为O(nk)
  • merge 函数:

    • 这个函数对两个数组合并,每个数组长度为k,因此时间复杂度为O(k)
    • 在合并过程中,我们调用了greater函数,其时间复杂度在最坏情况下为O(k)
  • greater 函数:

    • 这个函数比较两个数组的元素,最坏情况下,它需要遍历整个数组,时间复杂度为O(k)

综合上述分析,总的时间复杂度为: O(k * (O(mk) + O(nk) + O(k) + O(k))) = O(k * (mk + nk + 2k)) = O(k^2 * (m + n + 2)) = O(k^2 * (m + n))

2. 空间复杂度
  • maxNumber 函数:

    • 需要常数空间来存储变量mnansi等。
    • 需要额外空间来存储每次merge函数的返回结果。
  • monoInc 函数:

    • 需要一个长度为k的数组res来存储结果。
  • merge 函数:

    • 需要一个长度为k的数组res来存储合并后的结果。
  • greater 函数:

    • 只需要常数空间。

综合上述分析,总的空间复杂度为:O(k),因为最大的空间占用是在monoIncmerge函数中创建的长度为k的数组。

五、总结知识点

  • 数组的操作

    • 数组的创建、初始化。
    • 数组的索引访问和赋值。
  • 辅助函数(Helper Functions)

    • 使用辅助函数来分解复杂问题,提高代码的可读性和可维护性。
  • 贪心算法

    • monoInc函数实现了贪心算法,通过维护一个单调递增的序列来找到最大子序列。
  • 双指针技术

    • monoInc函数中,使用双指针来维护单调递增序列。
    • merge函数中,使用双指针来合并两个单调递增序列。
  • 递归逻辑

    • greater函数中包含递归逻辑,用于比较两个序列的大小。
  • 循环与迭代

    • 使用for循环和while循环来遍历数组,以及执行迭代操作。
  • 边界条件处理

    • maxNumber函数中,通过Math.max(0, k - n)来确保索引不会超出数组的界限。
  • 逻辑运算

    • 使用逻辑运算符(如&&||!)来控制代码流程。
  • 条件判断

    • 使用ifelse语句进行条件判断。
  • 函数参数传递

    • 通过引用传递(数组)和值传递(基本数据类型)来传递函数参数。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。


http://www.mrgr.cn/news/53614.html

相关文章:

  • Python基础之元组使用详解
  • SQL 干货 | SQL 反连接
  • 基于java+springboot的宇宙动漫网站
  • 【编程语言】Kotlin快速入门 - 集合与Lambda
  • msfvenom生成木马-windows
  • Dockerfile样例
  • 小白学大模型 RAG:GraphRAG 概念、组成和流程,看完这一篇你就懂了!!
  • 出手!快手可灵开源版,AI视频生成整合包!
  • 84.【C语言】数据结构之顺序表的头部插入和删除
  • 医疗领域的RAG技术:如何通过知识图谱提升准确性
  • vb操作电子表格 文件夹内多表格 提取数据 在生成一个新表格
  • Leetcode—192. 统计词频【中等】(Shell)
  • 【树莓派】树莓派搭建个人服务器
  • Qt之QObject
  • Java并发编程深度解析:从基础到实战
  • Shades of Gray 算法
  • 问:MySQL数据库存储引擎及对应的锁有哪些?
  • ​AI Sketchnotes Generator——解锁创意表达的新方式
  • 83.【C语言】数据结构之顺序表的尾部插入和删除
  • C语言 | Leetcode C语言题解之第493题翻转对
  • [实时计算flink]DataStream连接器设置方法
  • 骑砍霸主MOD天芒传奇Ⅱ·前传-序章
  • Cuda By Example - 8 (性能测量)
  • ChatGPT的150个角色提示场景实测(17)营养师
  • 一天认识一个硬件之路由器
  • MobaXterm 中文乱码