夯实算法-自定义字符串排序

160 阅读2分钟

题目:自定义字符串排序

给定两个字符串 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"

提示:

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

解题思路

由于排序是不稳定排序,为了防止意外的交换,保证进行排序的部分都在order中出现过,因此将s划分成两部分。 首先将s中的字符分为在order中出现过和没有出现过两部分,然后对出现过的部分按照在order中出现的下标排序,另外一部分最后添加到结果中即可。

题目就是要求重排s,使其字符排列顺序与order一致。如果以字符串排序的角度,以s为核心出发,想着怎么交换其字符 顺序可能会陷入困境,极难得出思路。

但如果运用逆向思维,想着怎么从orderorderorder来构造出结果字符串,那么就会豁然开朗。题目要求是,order中有的字符,一定要按order来排序,其他字符随意。那么,就按照order的要求来构造结果字串 就好了。具体的,统计s中每个字符的个数,然后遍历order,按其顺序把字符都写入结果字符串。然后最后再把不在order中的字符写进去,就完事儿。

代码实现

public String customSortString(String order, String s) {
    // 桶排序
    int[] charCount = new int[26];
    for (char c: s.toCharArray()) {
        ++charCount[c - 'a'];
    }
    // 按照规定顺序收集桶
    StringBuilder sb = new StringBuilder();
    for (char c: order.toCharArray()) {
        for (int i = 0; i < charCount[c - 'a']; i++) {
            sb.append(c);
        }
        charCount[c - 'a'] = 0;
    }
    // 收集哪些没有出现在排序里面的字符
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < charCount[i]; j++) {
            sb.append((char)(i + 'a'));
        }
    }
    return sb.toString();
}

运行结果

Snipaste_2023-06-12_23-10-05.png

复杂度分析

  • 空间复杂度:O(1)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!