持续创作,加速成长!这是我参与「掘金日新计划 · 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
的结果数组。根据题目描述以及相关提示,我们可以总结出以下几点:
- 在字符串中有两个字符
I
和D
,其中字符I
表示当前元素是较小的元素,字符D
表示当前元素为较大元素; - 结果数组的范围是
[0, n + 1]
; - 有多个有效排列的,可以 任选一个 排列结果返回;
总结了上面这几点之后,这里就可以采用双指针的方式来进行解题了:
- 定义指针
left, right
分别指向数组范围的左右边界; - 识别当前元素类型,如果是
D
,则取大的元素,也就是右边指针指向的元素,反之,则取左边指针指向的元素,同时将指针向中间移动; - 将元素赋值给结果数组;
- 最后需要将中间的元素赋值给最后面的一位;
- 返回结果;
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;
}
}