数据结构与算法之字符串: LeetCode 791. 自定义字符串排序 (Ts版)

自定义字符串排序

描述

  • 给定两个字符串 order 和 s 。order 的所有字母都是 唯一 的,并且以前按照一些自定义的顺序排序

  • 对 s 的字符进行置换,使其与排序的 order 相匹配。更具体地说,如果在 order 中的字符 x 出现字符 y 之前,那么在排列后的字符串中, x 也应该出现在 y 之前

  • 返回 满足这个性质的 s 的任意一种排列

示例 1:

输入: order = "cba", s = "abcd"
输出: "cbad"

解释:
“a”、“b”、“c"是按顺序出现的,所以"a”、“b”、“c"的顺序应该是"c”、“b”、“a”。
因为"d"不是按顺序出现的,所以它可以在返回的字符串中的任何位置。“dcba”、“cdba”、"cbda"也是有效的输出。

示例 2

输入: order = "cbafg", s = "abcd"
输出: "cbad"

解释:字符 “b”、“c” 和 “a” 规定了 s 中字符的顺序。s 中的字符 “d” 没有在 order 中出现,所以它的位置是弹性的。

按照出现的顺序,s 中的 “b”、“c”、“a” 应排列为"b"、“c”、“a”。“d” 可以放在任何位置,因为它没有按顺序排列。输出 “bcad” 遵循这一规则。其他排序如 “dbca” 或 “bcda” 也是有效的,只要维持 “b”、“c”、“a” 的顺序。

提示

  • 1 <= order.length <= 26
  • 1 <= s.length <= 200
  • order 和 s 由小写英文字母组成
  • order 中的所有字符都 不同

Typescript 版算法实现


1 ) 方案1:自定义排序

function customSortString(order: string, s: string): string {
    // 创建一个数组来存储每个字符的优先级值
    const val: number[] = new Array(26).fill(0);

    // 根据 `order` 字符串设置每个字符的优先级值
    for (let i = 0; i < order.length; ++i) {
        const charCode = order[i].charCodeAt(0) - 'a'.charCodeAt(0);
        val[charCode] = i + 1;
    }

    // 将字符串 `s` 转换为字符数组
    const arr: string[] = Array.from(s);

    // 按照 `val` 数组中的优先级对字符数组进行排序
    arr.sort((c0, c1) => {
        const index0 = c0.charCodeAt(0) - 'a'.charCodeAt(0);
        const index1 = c1.charCodeAt(0) - 'a'.charCodeAt(0);
        return val[index0] - val[index1];
    });

    // 将排序后的字符数组拼接成字符串并返回
    return arr.join('');
}

2 ) 方案2:计数排序

function customSortString(order: string, s: string): string {
    // 创建一个数组来存储每个字符的频率
    const freq: number[] = new Array(26).fill(0);

    // 统计字符串 `s` 中每个字符的出现次数
    for (let i = 0; i < s.length; ++i) {
        const ch: string = s[i];
        freq[ch.charCodeAt(0) - 'a'.charCodeAt(0)]++;
    }

    let ans: string = '';

    // 根据 `order` 字符串中的顺序构建结果字符串
    for (let i = 0; i < order.length; ++i) {
        const ch: string = order[i];
        while (freq[ch.charCodeAt(0) - 'a'.charCodeAt(0)] > 0) {
            ans += ch;
            freq[ch.charCodeAt(0) - 'a'.charCodeAt(0)]--;
        }
    }

    // 将剩余的字符(不在 `order` 中的字符)添加到结果字符串中
    for (let i = 0; i < 26; ++i) {
        while (freq[i] > 0) {
            ans += String.fromCharCode(i + 'a'.charCodeAt(0));
            freq[i]--;
        }
    }
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值