leetcode_321 Create Maximum Number

  • 题目分析:

    给定两个长度分别为m和n的数组,数组元素为0-9,每个数组元素代表一个数字。从这两个数组中选出一些数字,组成一个数组,是这个数组中的数尽可能大,其长度k <= m + n。要求数组中选出的元素的相对顺序与原数组保持一致。最终返回一个包含k个数字的数组。

  • 解题思路:

    1)分别从nums1(长度为m)和nums2(长度为n)中挑选出i(max(0, k - n) <= i <= min(m, k) 和k-i个数,在保持挑选数组的元素相对顺序不变的情况下,使选出的子数组最大化,主要利用贪心算法进行选取;

    2)在保持元素相对位置不变的前提下,将数组nums1与nums2合并,使合并的数组最大化。

  • 实现程序

    • C++版本

      // 贪心求数组中的最大子数组 
      vector<int> findMaxKValue(vector<int> &nums, int k)
      {
          vector<int> result;
          if (k == 0)
              return result;
          result = vector<int>(k, 0);
          int j = 0;
          int n = nums.size();
          for (int i = 0; i < n; i++)
          {
              // 出栈操作 
              while (j > 0 && n - i + j > k && nums[i] > result[j - 1])
                  j--;
              // 入栈操作 
              if (j < k)
                  result[j++] = nums[i]; 
          }
          return result;
      }
      // merge操作中的对比函数 
      bool compare(vector<int> &result1, int i, vector<int> &result2, int j)
      {
          while (i < result1.size() && j < result2.size() && result1[i] == result2[j])
          {
              i++;
              j++;
          }
          return j == result2.size() || (i < result1.size() && result1[i] > result2[j]);
      }
      // 两个数组的merge操作 
      vector<int> merge(vector<int> &nums1, vector<int> &nums2)
      {
          int m = nums1.size();
          int n = nums2.size();
          if (!m)
              return nums2;
          if (!n)
              return nums1;
          vector<int> result(m + n, 0);
          int i = 0; 
          int j = 0;
          int k = 0;
          // 数组合并操作 
          while (i < m || j < n)
          {
              result[k++] = compare(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
          }
          return result;
      }
      // 返回两个数组中最大的k个数,并保持每个数组中的元素相对位置不变 
      vector<int> maxNumber(vector<int> &nums1, vector<int> &nums2, int k)
      {
          int m = nums1.size();
          int n = nums2.size();
          vector<int> result(k, 0);
          // 从数组nums中挑选k个数,在保持元素相对顺序不变的情况下,使得选出的子数组最大化。 
          for (int i = max(0, k - n); i <= min(m, k); i++)
          {
              // 在数组nums1中挑选i个数 
              vector<int> result1 = findMaxKValue(nums1, i);
              // 在数组nums2中挑选k-i个数 
              vector<int> result2 = findMaxKValue(nums2, k - i);
              // 将两个挑选出的子数组进行合并 
              vector<int> temp = merge(result1, result2);
              // 比较大小,来判断是否更新数组 
              if (compare(temp, 0, result, 0))
                  result = temp;
          }
          return result;
      }   
      
    • Java版本

      private boolean compare(int[] result1, int pos1, int[] result2, int pos2) {
          for ( ; pos1 < result1.length && pos2 < result2.length; pos1++, pos2++){
              if (result1[pos1] > result2[pos2])
                  return true;
              if (result1[pos1] < result2[pos2])
                  return false;
          }
          return pos1 != result1.length;
      }
      
      private int[] findMaxKValue(int[] nums, int k) {
          int[] result = new int[k];
          int len = 0;
          for (int i = 0; i < nums.length; i++){
              while (len > 0 && len + nums.length - i > k && result[len - 1] < nums[i]){
                  len--;
              }
              if (len < k)
                  result[len++] = nums[i];
          }
          return result;
      }
      
      public int[] maxNumber(int[] nums1, int[] nums2, int k){
          int[] result = new int[k];
          for (int i = Math.max(k - nums2.length, 0); i <= Math.min(nums1.length, k); i++){
              int[] result1 = findMaxKValue(nums1, i);
              int[] result2 = findMaxKValue(nums2, k - i);
              // 对两个数组执行merge操作
              int[] temp = new int[k];
              int pos1 = 0;
              int pos2 = 0;
              int tpos = 0;
              while (pos1 < result1.length || pos2 < result2.length){
                  temp[tpos++] = compare(result1, pos1, result2, pos2) ? result1[pos1++] : result2[pos2++];
              }
              if (!compare(result, 0, temp, 0))
                  result = temp;
          }
          return result;
      }
      
  • 参考文献

    http://bookshadow.com/weblog/2015/12/24/leetcode-create-maximum-number/

    http://blog.csdn.net/murmured/article/details/50392234

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值