LeetCode 942 di-string-match 增减字符串匹配

题目链接

LeetCode 周赛 111场B题

https://leetcode-cn.com/problems/di-string-match/

题意

        是有点难懂了,给出一个字符串S,S全部由‘D’和‘I’组成,然后现在需要解出一个数组,而这个数组需要和S相匹配。假设S的长度为N,那么这个数组的长度是N+1,并且值是集合{0...N}的任意排列。给出一个例子,假设有字符串S1 = "DIDID",那么S1的长度为5,那么答案就必须是集合{0,1,2,3,4,5}的一个排序,可能是{5,4,3,2,1,0},也可能是{0,1,3,5,2,4}等等。

        而这个排序必须是与字符串S相匹配的。这里上题目的example:

“IDID”

[0,4,1,3,2]

题目的意思是,将字符串与数组一一对应,因为数组多一位,不考虑这一位。剩下的位置,如果字符串写的是‘I’,那么该位置上的数应该比右边所有的数都小。而如果是‘D’,则是比右边的都大。现在需要找到其中任意一组。

题解

        其实这个题是一个贪心,并且有点dp的感觉。感觉这个题解不唯一,其实还是比较简单能够证明反例。评论有人提出了解法证明,可以看一下:

只需要证明,对于任何 > 或者 < , 算法的规则都能满足。
△N = max-min; 由于每次遇到一个符号,△N-1。
当符号为“ <   <   <”: max--可以保证符号的正确性。
当符号为“ >   >   >”: min++可以保住符号的正确性。
当符号为“ ……<   >   < ":  任意时刻max和min开始比较,是否满足 min < max?
答案是:YES! 由于符号的数量为N,最开始△N = N。由于至少出现一对大于号和小于号 , min(△N)= 1,仍然满足min < max;
综上,得证。

因为每一位对应的数字只有两种情况:比右边所有数都大,或者都小。那么我们可以设定两个值,初始的话:low = 0,high = N。这样,从左开始遍历字符串,碰见一个字符,如果是‘I’,那么就直接赋值low,同时low++。这样,‘I’右边所有的数,一定是都比这个位置大的。因为此时low>a[i],同时high > low。

        反而言之,碰见‘D’,直接赋值hight,同时high--。这样所有的数就一定比这个小了。大概就是这样,在O(n)的时间复杂度下就能构造出答案数组。

Java 代码

class Solution {
    public int[] diStringMatch(String S) {
        int max = S.length();
        int len = S.length();
        int min = 0;
        int[] ans = new int[max+1];
        for(int i = 0;i < len;i++){
            char c = S.charAt(i);
            if(c == 'D'){
                ans[i] = max--;
            }else{
                ans[i] = min++;
            }
        }
        ans[len] = min;
        return ans;
    }
}

 

你可能感兴趣的:(LeetCode)