跳至主要內容

942-增减字符串匹配

daipeng大约 2 分钟

由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:

如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I' 
如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D' 
给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。

 

示例 1:

输入:s = "IDID"
输出:[0,4,1,3,2]

示例 2:

输入:s = "III"
输出:[0,1,2,3]

示例 3:

输入:s = "DDI"
输出:[3,2,0,1]
 

提示:

1 <= s.length <= 105
s 只包含字符 "I""D"

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/di-string-match
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

刚开始我的想法是找到一个小的数字,然后找一个刚好大一点的数字,作为一组,但很快发现这样找还需要满足第二个数字与第3个数字之间的大小关系, 比如对于"IDID",先找到[0,1],可以满足第一个I,但第二个D就无法满足了。 看到示例3时,发现可以将数字按照大小分成两组,比如[0,1,2,3],可以分成[3,2],[0,1]或者[3],[0,1,2],特点就是第一组的任何值都大于第二组的任何值,这样我们就可以把第一组的值放到D的位置,将第二组的小的值放到I的位置。 比如"IDID",数组长度是5,先从最大数字开始进行填充。 遍历"IDID",将4 3 先放到D的位置,变成:[x,4,x,3,x] 再将剩余的较小的数字放到I的位置.[0,4,1,3,x], 最后注意还剩一个x没放,注意填充即可。

这道题实际是对于每个D,都放当前剩余的最大值。这样对于剩余的I,则可以放置当前任一剩余值。

public int[] diStringMatch(String s) {
        char[] chs = s.toCharArray();
        int lo = 0;
        int hi = chs.length;
        int[] res = new int[chs.length + 1]; // 数字长度比字符数量要多一个
        int idx = 0;
        for (char ch : chs) {
            if (ch == 'I') {
                res[idx] = lo++; //对于I,我们先放较小的数
            }else{
                res[idx] = hi--; //对于D,我们先放较大的数
            }
            idx++;
        }
        res[idx] = lo; //最后一定有lo==hi,也就是最后一个字符的位置放最后一个数字
        return res;
    }