【经典】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;
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值