leetcode 763. 划分字母区间
题目:763. 划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
- 划分结果为 “ababcbaca”, “defegde”, “hijhklij”。
- 每个字母最多出现在一个片段中。
- 像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。
提示:
- S的长度在[1, 500]之间。
- S只包含小写字母 ‘a’ 到 ‘z’ 。
方法一:双指针(对撞指针)
思路:双指针(对撞指针),将需要划分的字符串装换成字符数组,从左到右遍历数组,假设遍历的第一个字符为’a’,再从右到左遍历数组,找到’a’最后出现的位置,依次类推找每一个字符的最后出现位置,并记录最远的字符位置,直到从左到右遍历到了当前记录的最远位置,此位置即为第一段字符串的结束位置,接着按照此方法继续找下一段字符串的结束位置。
运行数据:执行用时:10 ms,内存消耗:38.4 MB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public List<Integer> partitionLabels(String S) {
List<Integer> list = new ArrayList<Integer>();
char[] chars = S.toCharArray();
int charsLen = chars.length;
int index = 0;
int preStringLength = 0;
for (int i = 0; i < charsLen; i++) {
for (int j = charsLen - 1; j >= index ; j--) { if (chars[i] == chars[j]) { index = j; break; } }
if (i == index) {
list.add(index + 1 - preStringLength);
preStringLength = index + 1; } }
return list; }
|
方法二:贪心
思路:由于字符串都是由小写字母组成,所以可以通过一个循环用一个长度为26的字符数组记录每一个字符的最后出现位置,然后遍历需要划分的字符串,更新当前字符串的结束位置,直到遍历需要划分的字符串到当前这一段字符串的结束位置时,此位置即为这一段字符串的最终结束位置,以此类推继续找下一段字符串。
运行数据:执行用时:2 ms,内存消耗:38 MB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public List<Integer> partitionLabels(String S) {
List<Integer> list = new ArrayList<Integer>();
char[] chars = S.toCharArray();
int charsLen = chars.length;
int[] lastPosition = new int[26];
for (int i = 0; i < charsLen; i++) { lastPosition[chars[i] - 'a'] = i; }
int left = 0;
int right = 0;
for (int i = 0; i < charsLen; i++) {
right = Math.max(right, lastPosition[chars[i] - 'a']);
if (i == right) {
list.add(right + 1 - left);
left = right + 1; } }
return list; }
|
相关链接:
学习所得,资料、图片部分来源于网络,如有侵权,请联系本人删除。
才疏学浅,若有错误或不当之处,可批评指正,还请见谅!