题目
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"
, thenA[i] < A[i+1]
- If
S[i] == "D"
, thenA[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 <= S.length <= 10000
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;
}
}