• 困难
  • 中等
  • 简单

    题目描述

    给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。

    来源,leetcode 每日一题 321. 拼接最大数字

求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例:

  1. 输入:
  2. nums1 = [3, 4, 6, 5]
  3. nums2 = [9, 1, 2, 5, 8, 3]
  4. k = 5
  5. 输出:
  6. [9, 8, 6, 5, 3]
  7. 输入:
  8. nums1 = [6, 7]
  9. nums2 = [6, 0, 4]
  10. k = 5
  11. 输出:
  12. [6, 7, 6, 0, 4]
  13. 输入:
  14. nums1 = [3, 9]
  15. nums2 = [8, 9]
  16. k = 3
  17. 输出:
  18. [9, 8, 9]

解题思路

相关题目:

image.png
image.png
image.pngimage.png
image.png
image.png
image.png
image.png


  1. ```cpp 给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。 需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例 1:

输入: “bcabc” 输出: “abc” 示例 2:

输入: “cbacdcbc” 输出: “acdb”

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/183814/1608273260113-51ac877a-9076-4713-bd47-a9d9fab19ca9.png#align=left&display=inline&height=561&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1121&originWidth=1501&size=252222&status=done&style=none&width=750.5)
  2. <a name="ur5Ae"></a>
  3. ## 本题思路
  4. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/183814/1608273296706-cb676994-d88e-427e-a01d-75e8d1dbce35.png#align=left&display=inline&height=589&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1178&originWidth=1497&size=292462&status=done&style=none&width=748.5)
  5. <a name="xZQIe"></a>
  6. # 代码
  7. ```cpp
  8. class Solution {
  9. public:
  10. vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
  11. int m = nums1.size(), n = nums2.size();
  12. vector<int> maxSubsequence(k, 0);
  13. int start = max(0, k - n), end = min(k, m);
  14. for (int i = start; i <= end; i++) {
  15. vector<int> subsequence1(MaxSubsequence(nums1, i));
  16. vector<int> subsequence2(MaxSubsequence(nums2, k - i));
  17. vector<int> curMaxSubsequence(merge(subsequence1, subsequence2));
  18. if (compare(curMaxSubsequence, 0, maxSubsequence, 0) > 0) {
  19. maxSubsequence.swap(curMaxSubsequence);
  20. }
  21. }
  22. return maxSubsequence;
  23. }
  24. vector<int> MaxSubsequence(vector<int>& nums, int k) {
  25. int length = nums.size();
  26. vector<int> stack(k, 0);
  27. int top = -1;
  28. int remain = length - k; // 需要抛弃的数量
  29. for (int i = 0; i < length; i++) {
  30. int num = nums[i];
  31. while (top >= 0 && stack[top] < num && remain > 0) { // 如果栈里有元素,且栈顶的元素小于当前元素,且还有需要抛弃的元素,则栈顶元素-1, 且需要抛弃的元素数量减一
  32. top--;
  33. remain--;
  34. }
  35. if (top < k - 1) { // 如果 栈未满,则直接入栈
  36. stack[++top] = num;
  37. } else {
  38. remain--; // 否则需要抛弃的元素数量减一
  39. }
  40. }
  41. return stack;
  42. }
  43. vector<int> merge(vector<int>& subsequence1, vector<int>& subsequence2) {
  44. int x = subsequence1.size(), y = subsequence2.size();
  45. if (x == 0) {
  46. return subsequence2;
  47. }
  48. if (y == 0) {
  49. return subsequence1;
  50. }
  51. int mergeLength = x + y;
  52. vector<int> merged(mergeLength);
  53. int index1 = 0, index2 = 0;
  54. for (int i = 0; i < mergeLength; i++) {
  55. if (compare(subsequence1, index1, subsequence2, index2) > 0) {
  56. merged[i] = subsequence1[index1++];
  57. } else {
  58. merged[i] = subsequence2[index2++];
  59. }
  60. }
  61. return merged;
  62. }
  63. int compare(vector<int>& subsequence1, int index1, vector<int>& subsequence2, int index2) {
  64. int x = subsequence1.size(), y = subsequence2.size();
  65. while (index1 < x && index2 < y) {
  66. int difference = subsequence1[index1] - subsequence2[index2];
  67. if (difference != 0) {
  68. return difference;
  69. }
  70. index1++;
  71. index2++;
  72. }
  73. return (x - index1) - (y - index2);
  74. }
  75. };

总结

image.png