LeetCode~942. 增减字符串匹配

100 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

题目描述

由范围 [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,则返回其中 任何一个

示例

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

提示

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

双指针

该题的需求是需要根据字符串s中的值,来得到一个长度为n + 1的结果数组。根据题目描述以及相关提示,我们可以总结出以下几点:

  1. 在字符串中有两个字符ID,其中字符I表示当前元素是较小的元素,字符D表示当前元素为较大元素;
  2. 结果数组的范围是[0, n + 1];
  3. 有多个有效排列的,可以 任选一个 排列结果返回;

总结了上面这几点之后,这里就可以采用双指针的方式来进行解题了:

  1. 定义指针left, right分别指向数组范围的左右边界;
  2. 识别当前元素类型,如果是D,则取大的元素,也就是右边指针指向的元素,反之,则取左边指针指向的元素,同时将指针向中间移动;
  3. 将元素赋值给结果数组;
  4. 最后需要将中间的元素赋值给最后面的一位;
  5. 返回结果;
class Solution {
    public int[] diStringMatch(String s) {
        // 将字符串转换成字节数组
        char[] c = s.toCharArray();
        // 定义边界变量以及双指针
        int n = c.length, left = 0, right = n;
        // 结果数组
        int[] res = new int[n + 1];

        // 遍历目标数组
        for(int i = 0; i < n; ++i){
            // 判断当前元素是小于下一元素,还是大于下一元素
            res[i] = c[i] == 'I' ? left++ : right--;
        }

        // 补充最后一个元素
        res[n] = left;

        // 返回结果
        return res;
    }
}