【每日算法0227】排序(简单)

79 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 19天,点击查看活动详情

题目

面试题45. 把数组排成最小的数

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例:

输入: [10,2]
输出: "102"

分析

说实话本题思路着实不大好想,看了答案琢磨半天

此题求拼接起来的最小数字,本质上是一个排序问题。设数组 nums 中任意两数字的字符串为 xy ,则规定 排序判断规则 为:

  • 若拼接字符串 x + y > y + x, 则 x "大于" y
  • 反之,若 x + y < y + x,则 x "小于" y

理解了上面的判断条件就很简单了,我们的解题步骤是:

  • 对数组进行字符串计算排序
  • 对数组进行转字符串处理

实现

function minNumber(nums: number[]): string {
    nums.sort((a, b) => {
        let x = a.toString() + b.toString()
        let y = b.toString() + a.toString()
​
        return Number(x) - Number(y)
    })
​
    return nums.join('')
};

题目

面试题61. 扑克牌中的顺子

从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

示例:

输入: [1,2,3,4,5]
输出: True

分析

这道题关键点要找到顺子成立的条件

  • 先进行排序,方便我们找出特殊值
  • 如果出现非0重复项,直接返回 false
  • 找出数组的非0最大值与最小值,满足 max - min < 5 则符合要求

实现

function isStraight(nums: number[]): boolean {
    nums.sort((a, b) => {
        return a - b
    })
​
    let min = null
    let max = null
​
    for (let i = 0; i < nums.length; i ++) {
        if (nums[i] == 0) continue
​
        if (nums[i] == nums[i + 1]) return false
​
        if(!min) {
            min = nums[i]
        } else if (i == nums.length - 1) {
            max = nums[i]
        }
    }
​
    return max - min < 5
};

由于数组重新排序过,可以简化下获取最大最小值的方法

function isStraight(nums: number[]): boolean {
    nums.sort((a, b) => a - b)
​
    let zero = 0
​
    for (let i = 0; i < nums.length - 1; i ++) {
        if (nums[i] == 0) {
            zero ++
            continue
        }
        if (nums[i] == nums[i+1]) {
            return false
        }
    }
​
    return nums[nums.length - 1] - nums[zero] < 5
};