LeetCode-321. Create Maximum Number

来源:互联网 发布:开启云服务器端口命令 编辑:程序博客网 时间:2024/05/17 03:47

Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits. You should try to optimize your time and space complexity.

Example 1:

nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
return [9, 8, 6, 5, 3]

Example 2:

nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
return [6, 7, 6, 0, 4]

Example 3:

nums1 = [3, 9]
nums2 = [8, 9]
k = 3

return [9, 8, 9]   



这一题挺难的,我用的最慢的方法~将k分成两部分,首先从第一个数组里取i个可以组成最大i位数的数,然后从第二个数组里取k-i个可以组成最大数的数,然后组合起来成一个最大的数,i从最小到最大遍历一次,从而求得最大的数。当然很慢了,我看tags里是用动态规划或贪婪算法的。不过我去大家的博客里看了看,都是这种方法~那就酱紫吧~


import java.math.BigInteger;public class Solution {     public int[] maxNumber(int[] nums1, int[] nums2, int k) {    int len1 = nums1.length;        int len2 = nums2.length;        int i = k;        BigInteger max = BigInteger.ZERO;        if(k>len1){        i = len1;        }    for(; i >= 0 && k-i<=len2; i--){        int[] num1 = calmaxnum(nums1,i);        int[] num2 = calmaxnum(nums2,k-i);        BigInteger maxnum = totalmaxnum(num1,num2);        if(maxnum.compareTo(max)>0){        max = maxnum;        }                }    int[] ans = convertToArray(max);    return ans;                }       int[]  calmaxnum(int[] num,int k){    int[] ans = new int[k];    int len = num.length;    int index = 0;    for(int i = 0; i < k; i++){    int[] ans2= findmaxnum(num,index,len-k+i+1);    ans[i] = ans2[0];    index = ans2[1]+1;    }        return ans;    }       int[]  findmaxnum(int[] num,int left,int right){    int max = num[left];   //int max = 0;    int index = left;    for(int i = left;i<right;i++){    if(num[i]>max){    max = num[i];    index = i;    }    }    int[] ans = {max , index};    return ans;    }       BigInteger totalmaxnum(int[] num1, int[] num2){    int len1 = num1.length;    int len2 = num2.length;    int index1 = 0;    int index2 = 0;    String str = "";    for(int i = 0; i<len1+len2; i++){    if(index1>=len1){    str += num2[index2++];    }else if(index2 >= len2){    str += num1[index1++];    }else if(num1[index1]>num2[index2]){    str += num1[index1++];    }else if(num1[index1]<num2[index2]){    str += num2[index2++];    }else{    int tempindex1 = index1;    int tempindex2 = index2;    while(true){    tempindex1++;    tempindex2++;    if(tempindex1 >=len1){        str += num2[index2++];        break;        }else if(tempindex2 >= len2){        str += num1[index1++];        break;        }else if(num1[tempindex1]>num2[tempindex2]){        str += num1[index1++];        break;        }else if(num1[tempindex1]<num2[tempindex2]){        str += num2[index2++];        break;        }    }        }    }    BigInteger ans = new BigInteger(str);    return ans;    }        int[] convertToArray(BigInteger max){    String str = ""+max;    int len = str.length();    int[] ans = new int[len];    for(int i = len-1; i>=0; i--){    ans[i] = (max.remainder(BigInteger.valueOf(10))).intValue();    max = max.divide(BigInteger.valueOf(10));    }        return ans;    }}




2016/6/5更新:后来又偶尔回顾这一题,本来想尝试两种新方法的,结果都失败告终了。。这道题真的是情况太多了。思路还是原来的,不过从第一个主要步骤的代码有所改进

第一步:分别从两个数组里选i / k-i位最大的数

入栈的顺序: 
首先检查当前数组元素和栈顶元素相对大小: 
1、大于栈顶元素,把栈顶元素弹出 
2、小于等于栈顶元素,直接入栈 
3、如果栈length+数组剩余length==需要入栈的总数量,则全部入栈 
比如9,1,9,8,3,2,需要入4个 

1,9 
9,9 
8,9,9 
3,8,9,9 
最后出栈的是9,9,8,3

不过要注意要是栈里已经满了就不要再入栈了

第二步:合并这两个数,这里没什么改进


public class Solution {    public int[] maxNumber(int[] nums1, int[] nums2, int k) {     Stack<Integer> st1 = new Stack<Integer>();     Stack<Integer> st2 = new Stack<Integer>();     List<Integer> max_list = new ArrayList<Integer>();    int len1 = nums1.length;        int len2 = nums2.length;        int i = k;              if(k>len1){        i = len1;        }    for(; i >= 0 && k-i<=len2; i--){        st1 = tempmaxnum(nums1,i);        st2 = tempmaxnum(nums2,k-i);        List<Integer> tempList = merge_maxList(st1,st2);        if(compareTwoLists(tempList,max_list) > 0){        max_list = tempList;        }             }    int[] ans = convertToArray(max_list,k);    return ans;        }      private int compareTwoLists(List<Integer> tempList, List<Integer> max_list) {   if(tempList.size() > max_list.size()){   return 1;   }else if(tempList.size() < max_list.size()){   return -1;   }else{   for(int i = 0; i < tempList.size(); i++){   if(tempList.get(i) > max_list.get(i)){   return 1;   }else if(tempList.get(i) < max_list.get(i)){   return -1;   }   }   }   // TODO Auto-generated method stubreturn 0;}private List<Integer> merge_maxList(Stack<Integer> l1, Stack<Integer> l2) {// TODO Auto-generated method stub   List<Integer> result = new ArrayList<Integer>();for(int i = 0, j = 0; i <= l1.size() || j <= l2.size(); ){if( i == l1.size()){while(j<l2.size()){result.add(l2.get(j++));}break;}else if(j == l2.size()){while(i<l1.size()){result.add(l1.get(i++));}break;}else if(l1.get(i) < l2.get(j)){result.add(l2.get(j++));}else if(l1.get(i) > l2.get(j)){result.add(l1.get(i++));}else{boolean flag = false;int temp1 = i+1;int temp2 = j+1;while(flag == false){if(temp1 == l1.size()){result.add(l2.get(j++));break;}else if(temp2 == l2.size()){result.add(l1.get(i++));break;}else if(l1.get(temp1) > l2.get(temp2)){result.add(l1.get(i++));break;}else if(l1.get(temp1) < l2.get(temp2)){result.add(l2.get(j++));break;}else{temp1++;temp2++;}}}}return result;}private int[] convertToArray(List<Integer> max_num,int k) {// TODO Auto-generated method stub    int[] result = new int[k];    for(int i = k-1 ; i >=0; i--){    result[i] = max_num.get(i);    }return result;}   private Stack<Integer> tempmaxnum(int[] nums, int l) {// TODO Auto-generated method stub   Stack<Integer> result = new Stack<Integer>();   int num = 0;   for( int i = 0 ; i < nums.length; i++){   if(!result.isEmpty() && (nums.length-i-1) >= (l - num) && nums[i] > result.get(num-1)){   result.pop();   num--;   i--;   continue;   }else if(num<l){   result.push(nums[i]);   num++;   }   }return result;}}


0 0
原创粉丝点击