zoukankan      html  css  js  c++  java
  • JS Leetcode 179. 最大数 题解分析,sort a-b与b-a的区别,sort排序原理解析

    壹 ❀ 引

    今天的题目来自LeetCode179. 最大数,题目描述如下:

    给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。

    注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。

    示例 1:

    输入:nums = [10,2]
    输出:"210"
    

    示例 2:

    输入:nums = [3,30,34,5,9]
    输出:"9534330"
    

    示例 3:

    输入:nums = [1]
    输出:"1"
    

    示例 4:

    输入:nums = [10]
    输出:"10"
    

    提示:

    • 1 <= nums.length <= 100
    • 0 <= nums[i] <= 109

    让我们简单分析题目,然后开始实现它。

    贰 ❀ 题解与分析

    其实通过第一个例子,题意就很清晰了,10和2一共就2种组合方式,由于210大于102,所以最终返回210。所以直观的做法就是将两个数字转为字符串,不然数字类型2+10=12不可能是210。假设有x,y两个数字,通过转为字符串,我们只需比较x+yy+x的大小,便可作为排序的规则。

    具体如何比较呢?如果让你做数组排序,可能首先想到的是通过sort方法,比如:

    //升序
    [1, 0, 2, 5].sort((a, b) => a - b); //[0,1,2,5]
    //降序
    [1, 0, 2, 5].sort((a, b) => b - a); //[5,2,1,0]
    

    我在JS 数组常见操作汇总,数组去重、降维、排序、多数组合并实现思路整理一文中,在数组排序部分对于sort做过简单介绍,这里我们简单复习下。

    其实,sort中callback回调中参与计算的a与b我们是可以自定义的,且它们的计算结果满足一个规则。不管是a-b还是b-a,它可以返回的结果分三种情况,小于0,等于0或者大于0。当结果为负数,a排在b的前面,当结果等于0,两者顺序不变,当结果为正数,那么b在a前面。觉得比较混乱的,建议找个简单的数组理一理,比如[5,4]。算了,还是我帮你们理一理。

    以数组[5,4],先看a-b的情况(虽然看起来很荒谬,但是sort确实反着取数的):

    [5,4].sort((a,b) => a - b);//a是4,b是5
    //因为a-b是负数,所以a在b前面,所以4在5前面,得到[4,5]
    

    我们再看b-a的情况:

    [5,4].sort((a,b) => b - a);//a是4,b是5
    //因为5-4是正数,正数b在a前面,所以5在4前面,得到[5,4]
    

    而所谓真正参与比较的a,b支持自定义,我们看个例子就懂了:

    let arr = [{
        name: 'echo',
        age: 18
    }, {
        name: '听风是风',
        age: 26
    }, {
        name: '时间跳跃',
        age: 10
    }, {
        name: '行星飞行',
        age: 16
    }];
    arr.sort((a, b) => {
        var a_ = a.age;
        var b_ = b.age;
        return a_ - b_;
    });
    

    这个例子就是按照年龄属性对对象进行升序排列,说直白点,只要你能拿出两个数字进行对比,sort就能按照你的期望对原数组进行排序。

    而前面我们虽然将数字转为了字符串,但本意只是希望x+y=能组合成xy,组合好了之后别忘了两个数字字符串进行减法操作时,它们其实还是会还原成数字并做运算。

    根据提议,因为我们期望最终数组能组合最大的数字,所以这个数组应该按降序排列,结合上面提到的sort,我们来实现这段代码:

    var largestNumber = function(nums) {
        nums.sort((a, b) => {
          	// 组合成字符串
            let S1 = a + '' + b;// 这里的S1你可以理解为a
            let S2 = b + '' + a;// 这里的S2你可以理解为b
          	// 如果ba比ab大,b应该在a前面,按降序排列
            return S2 - S1;// 这里你可以理解为b-a,如果b比a大,差为正数,那么b会排在a前面
        });
      	// 考虑[0,0]的情况,
        return nums[0] ? nums.join('') : '0';
    };
    

    如果你觉得还有点绕,可以根据注释来理解,因为前面我们说了,a与b其实是可以进行自定义的,且排列顺序是按照callback中差集的值来决定a与b的先后顺序。我们期望是baab大时,b在a前面,那自然是ba-ab为正数才行,大概就是这么个道理。而最终有个小坑就是避免[0,0]的情况,那么本题解析就到这里了。

  • 相关阅读:
    MySql 用户 及权限操作
    MAC 重置MySQL root 密码
    在mac系统安装Apache Tomcat的详细步骤[转]
    Maven:mirror和repository 区别
    ES6 入门系列
    转场动画CALayer (Transition)
    OC 异常处理
    Foundation 框架
    Enum枚举
    Invalid App Store Icon. The App Store Icon in the asset catalog in 'xxx.app' can’t be transparent nor contain an alpha channel.
  • 原文地址:https://www.cnblogs.com/echolun/p/14660744.html
Copyright © 2011-2022 走看看