[每日一题][找工作第89天][2025-12-20] Leetcode 763. 划分字母区间

题目

763. 划分字母区间
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。例如,字符串 “ababcc” 能够被分为 [“abab”, “cc”],但类似 [“aba”, “bcc”] 或 [“ab”, “ab”, “cc”] 的划分是非法的。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
 
示例 1:
输入:s = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、”defegde”、”hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。
示例 2:
输入:s = “eccbbbbdec”
输出:[10]
 
提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成

我的代码(TypeScript)

function partitionLabels(s: string): number[] {
    let cntArray: number[][] = Array.from({ length: 26 }, () => [-1, -1]);
    for (let i: number = 0; i < s.length; i++) {
        const idx: number = s[i].charCodeAt(0) - 97;
        if (cntArray[idx][0] == -1) {
            cntArray[idx][0] = i;
        }
        cntArray[idx][1] = i;
    }
    cntArray.sort((a, b) => a[0] - b[0]);
    let result: number[][] = [];
    for (let i = 0; i < 26; i++) {
        if (cntArray[i][0] == -1) {
            continue;
        }
        let combined: Boolean = false;
        for (let j: number = 0; j < result.length; j++) {
            if (cntArray[i][1] > result[j][0] && cntArray[i][0] < result[j][1]) {
                result[j][0] = Math.min(cntArray[i][0], result[j][0]);
                result[j][1] = Math.max(cntArray[i][1], result[j][1]);
                combined = true;
                break;
            }
        }
        if (!combined) {
            result.push(cntArray[i]);
        }
    }
    return result.sort((a, b) => a[0] - b[0]).map(r => r[1] - r[0] + 1);
};

点评

思路是找出各个字母的起始和结束索引,然后把有重叠的进行合并。
合并这里用了直接遍历,不确定有没有更简单的方法。
效率不算很好。
官方的贪心算法需要遍历字符串两次,
我只遍历一次,所以如果字符串很长,可能我的方法会好一点。
不过这里长度只有500,所以相比来说效率不算好。
另外我的算法还处理了起始位置,这一点似乎有些多余。


baddif@gmail.com

AI简历优化站

Nonpareil.me:优化简历,助力职场
开源代码

AI求职跟踪器(建设中)

开源代码

主站(建设中)

Nonpareil Me

相关平台

Github Issues / Notion / Blog

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部