• Java 特定规则排序-LeetCode 179 Largest Number


    Given a list of non negative integers, arrange them such that they form the largest number.

    For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

    Note: The result may be very large, so you need to return a string instead of an integer.

    题意:

    给出无序数组A,利用数组A中的数字进行排列得出一个数字N,使得N最大

    分析:

    该题归根结底是按照一种特殊的规则对原数组进行排序,使得排序后的数组拼接在一起得到的数字最大。

    而这个规则便是:数字按照字典序排序比如321和4,那么321<4,因为从高位开始3<4(ascii码)

    但是有一种特殊情况,如30和3,按照字典序排序应该是30>3,但是在本题目中如果我们想组成最大数字必须是30<3,因为303<330

    这样我们就得出了排序的规则,那么如何实现这两种规则

    解法1

    给出整数o1和o2,我们知道字符串之间的比较就是按照字典序进行的,那么我们比较o1+o2和o2+o1即可完成上述规则

    代码如下:

     1 public String largestNumber(int[] nums) {
     2         PriorityQueue<String> pq = new PriorityQueue<>(10,
     3                 new Comparator<String>() {
     4                     @Override
     5                     public int compare(String o1, String o2) {
     6                         return (o1 + o2).compareTo(o2 + o1);
     7                     }
     8                 });
     9         for (int i = 0; i < nums.length; i++) {
    10             pq.add(Integer.toString(nums[i]));
    11         }
    12         StringBuilder sb = new StringBuilder();
    13         while (!pq.isEmpty()) {
    14             sb.insert(0, pq.poll());
    15         }
    16         String tmp = sb.toString();
    17         if (tmp.charAt(0) == '0')
    18             return "0";
    19         return sb.toString();
    20     }

    这里我用的是优先队列(即二叉堆,直接用排序也可以)

    解法2

    这是与实验室师弟讨论的结果,由于在这次排序中无论数字有几位,如果每一位上全是9那么这个数字一定是最大的,必须排在最前面,如{99, 30, 9, 5}那么99和9一定是放在最前面的,那么换个思路,我比较两个数字大小那么可以比较在对应最大的数字所占的百分比。如3和30,那么我比较3/9和30/99的大小来判断30和3的大小

    代码如下:

     1 public String largestNumber2(int[] nums) {
     2         PriorityQueue<Integer> pq = new PriorityQueue<>(10,
     3                 new Comparator<Integer>() {
     4                     @Override
     5                     public int compare(Integer o1, Integer o2) {
     6                         int t1 = o1, t2 = o2;
     7                         double a1 = 0.0, a2 = 0.0;
     8                         do {
     9                             a1 = a1 * 10 + 9;
    10                             t1 /= 10;
    11                         } while (t1 != 0);
    12                         do {
    13                             a2 = a2 * 10 + 9;
    14                             t2 /= 10;
    15                         } while (t2 != 0);
    16                         if (o1 / a1 > o2 / a2)
    17                             return 1;
    18                         else if (o1 / a1 < o2 / a2)
    19                             return -1;
    20                         else
    21                             return 0;
    22                     }
    23                 });
    24         for (int i = 0; i < nums.length; i++) {
    25             pq.add(nums[i]);
    26         }
    27         StringBuilder sb = new StringBuilder();
    28         while (!pq.isEmpty()) {
    29             sb.insert(0, pq.poll());
    30         }
    31         String tmp = sb.toString();
    32         if (tmp.charAt(0) == '0')
    33             return "0";
    34         return sb.toString();
    35     }

    注意特殊情况处理就是数组中给出的全是0,而题目要求返回字符串,注意别返回"000"这种情况,特殊处理下。

    我看了下Discuss差不多就这两种,大同小异

  • 相关阅读:
    thinkphp5 模板中截取中文字符串
    .NET 操作PDF文档以及PDF文件打印摸索总结
    Mongodb 启动时 lock文件访问没有权限处理
    ASP.NET Web API 通过参数控制返回类型(JSON|XML)
    C# url 路径转换 相对路径 转换为 绝对路径
    Chrome浏览器允许跨域请求配置
    如何配置visual studio 2013进行负载测试-万事开头难
    分享:带波形的语音播放工具(wavesurfer-js)
    使用裸协议(相对协议)
    javascript ~~ 符号的使用
  • 原文地址:https://www.cnblogs.com/xlturing/p/4473551.html
Copyright © 2020-2023  润新知