增减字符串匹配

126 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

题目描述

由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:
如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I' 
如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D' 
给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个。(出自力扣)

  • 示例1:
输入: s = "IDID"
输出: [0,4,1,3,2]
  • 示例2:
输入: s = "III"
输出: [0,1,2,3]
  • 示例3:
输入: s = "DDI"
输出: [3,2,0,1]

提示:

  • 1 <= s.length <= 105
  • s 只包含字符 "I" 或 "D"

思路分析

根据题意可知,字符串s的长度为n,目标数组perm的长度就是n+1,数组里面的元素最大的是n,也就是字符串s的长度,最小值是0;并且字符串s全部由ID组成;若是s[i]=='I',那么perm[i] < perm[i + 1];若是s[i] == 'D',那么perm[i] > perm[i + 1];通过观察规律发现,I所对应的元素都是递增的,而D所对应的元素都是递减的,也就是说第一个I是最小的也就是0,第一个D是最大的,是n
我们可以这样,根据规律,若是当前的字符是I,那么就是区间内剩下的最小值,后面遇到I的话,就上一个I所对应的元素加1;若是当前的字符是D,那么就是区间内剩下的最大值,后面遇到D的话,就上一个D所对应的元素减1; 若要循环次数足够,需要在循环体中增加一个字符I或者D都可以;在每一次的循环中,将当前元素push到新数组arr里面。

AC代码

let typed = "IDID";
function solution(s) {
  let arr = [];
  let min = 0;
  let max = s.length
  s += s+'I';
  for (let i = 0; i < s.length; i++) {
    if (s[i] === 'I') {
      arr.push(min)
      min++
    } else {
      arr.push(max)
      max--
    }
  }
  console.log(arr);
}
solution(typed)