[LeetCode] 941. Valid Mountain Array

题:https://leetcode.com/problems/di-string-match/description/

题目

Given a string S that only contains “I” (increase) or “D” (decrease), let N = S.length.

Return any permutation A of [0, 1, …, N] such that for all i = 0, …, N-1:

If S[i] == “I”, then A[i] < A[i+1]
If S[i] == “D”, then A[i] > A[i+1]

Example 1:

Input: "IDID"
Output: [0,4,1,3,2]

Example 2:

Input: "III"
Output: [0,1,2,3]

Example 3:

Input: "DDI"
Output: [3,2,0,1]

Note:

  1. 1 <= S.length <= 10000
  2. S only contains characters “I” or “D”.

题目大意

给定一个字符串 S,长度为 n,构造一个长度为 n+1 的数组,数组元素为 0,1,2 …… n,且数组满足 下面的规则。

If S[i] == "I", then A[i] < A[i+1]
If S[i] == "D", then A[i] > A[i+1]

思路

方法一 取局部最小

找出 数组中的 局部最小,即 A[i-1] < A[i] > A[i+1],对于边界 A[0]<A[1] , A[n]<A[n-1]。对于这些局部最小A[i],从小到大分配 数组的元素(0,1,2,……,n)。

当确定一个局部最小后, 其左或右 位置的另一边 若是 小于 其他元素。那么左或右 位置也可以视为局部 最小。

class Solution {
    public int[] diStringMatch(String S) {
        int Slen = S.length();
        boolean [][] dp  = new boolean[Slen+1][2];
        dp[0][0] = true;
        dp[Slen][1] = true;
        for(int i = 0 ;i<Slen;i++){
            if(S.charAt(i) == 'I')
                dp[i][1] = true;
            else
                dp[i+1][0] = true;
        }
        int Cnt = 0 ;
        int[] res = new int[Slen+1];
        Queue<Integer> queue = new ArrayDeque<>();

        for(int i = 0 ;i <= Slen;i++){
            if(dp[i][0] == true && dp[i][1] == true){
                res[i] = Cnt++;
                queue.add(i);
            }
        }
        while(!queue.isEmpty()){
            int i = queue.poll();
            int l = i -1;
            int r = i+1;
            if(l>=0 && dp[l][1]==false){
                dp[l][1] = true;
                if(dp[l][0] == true){
                    res[l] = Cnt++;
                    queue.add(l);
                }
            }
            if(r<=Slen && dp[r][0]==false){
                dp[r][0] = true;
                if(dp[r][1] == true){
                    res[r] = Cnt++;
                    queue.add(r);
                }
            }
        }
        return res;
    }
}

方法二 更新边界

S[0]+S[1:],确定 A[i],i=0,1,2,……,n;
若S[0]<S[1],A[0] 可设为0, S[1:] 可确定出一个数组,数组元素为 1, 2, ……,n。
若S[0]>S[1],A[0] 可设为n, S[1:] 可确定出一个数组,数组元素为0, 1, 2, ……,n-1。

class Solution {
    public int[] diStringMatch(String S) {
        int Slen = S.length();
        int li = 0,ri = Slen;
        int[] res = new int[Slen+1];
        for(int i = 0 ; i < Slen;i++){
            if(S.charAt(i) == 'I')
                res[i] = li++;
            else
                res[i] = ri--;
        }
        res[Slen] = li;
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/u013383813/article/details/84255202