【经典】942.DI String Match【排序的变种:按规则排序】

题目

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".

解答1:(排序变种角度理解题目)

  • 【排序规则】字符串S中规定了排序的规则,为此需要将0到 N 按照其规则进行排序。
  • 【对比常见的数字排序】以往的数字排序往往结果是要求单调的,即这里面的特殊情况 IIIII ... 或者 DDDDD ...。
  • 【该规则下的排序】下面的排序借鉴了插入排序的思路,按照规则进行插入排序。
  • 【不借鉴:快速排序】 快速排序依赖于整个数组的单调性,所以能够提升速度,但是当规则不确定时,快速排序的优势也就不存在了。(可以从逆序数角度证明这一点)
public class DiStringMatch {
    public int[] diStringMatch(String S) {
        int length = S.length();
        int[] results = new int[length +1];
        //初始化为从小到大排序
        for(int i = 0; i < results.length;i++){
            results[i] = i;
        }
        for(int i = 0; i < length;i++){
            sort(results,S,i);
        }
        return results;
    }

    private void sort(int[] results,String S,int position){
        //每一次根据规则进行改变,都会对之前的数据造成一定的影响,所以需要重新处理之前的数据。(所以此处设置i从position处从后向前遍历)
        for(int i = position; i >= 0; i--){
            if(S.charAt(i) == 'I'){
                if(results[i] < results[i+1]){
                    return;
                }else{
                    swap(results,i,i+1);
                }
            }else{
                if(results[i] > results[i+1]){
                    return;
                }else{
                    swap(results,i,i+1);
                }
            }
        }
    }
    private void swap(int[] results, int position1, int position2){
        int tmp = results[position1];
        results[position1] = results[position2];
        results[position2] = tmp;
    }
}

猜你喜欢

转载自blog.csdn.net/TheSnowBoy_2/article/details/87904635