package com.heu.wsq.leetcode.monotone_stack;
/**
* 316. 去除重复字母
* @author wsq
* @date 2020/12/20
* 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
* 注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同
*
* 示例 1:
* 输入:s = "bcabc"
* 输出:"abc"
*
* 链接:https://leetcode-cn.com/problems/remove-duplicate-letters
*/
public class RemoveDuplicateLetters {
/**
* 单调栈 + 贪心的思想
* 什么时候去单调栈?目前先放着,后头再琢磨,看论文去
* @param s
* @return
*/
public String removeDuplicateLetters(String s){
// 统计每个字母的数量
int[] nums = new int[26];
for (char c : s.toCharArray()) {
nums[c - 'a']++;
}
// 标记对应字符是否在sb构成的字符串中存在
boolean[] existence = new boolean[26];
StringBuilder sb = new StringBuilder();
for(char c : s.toCharArray()){
if (!existence[c - 'a']){
while (sb.length() > 0){
char lastC = sb.charAt(sb.length() - 1);
if (!(lastC > c)) break;
// 判断最后一个字符对应的数量是否大于0,如果c字符后面没有该字符了,那么直接跳出循环
if (nums[lastC - 'a'] > 0){
existence[lastC - 'a'] = false;
sb.deleteCharAt(sb.length() - 1);
}else {
break;
}
}
// 将该字符加入到sb字符串末尾
existence[c - 'a'] = true;
nums[c - 'a']--;
sb.append(c);
}else{
nums[c - 'a']--;
}
}
return sb.toString();
}
public static void main(String[] args) {
String s = "cbabc";
RemoveDuplicateLetters rd = new RemoveDuplicateLetters();
String ans = rd.removeDuplicateLetters(s);
System.out.println(ans);
}
}
316. 去除重复字母(单调栈)
最新推荐文章于 2022-09-01 21:26:11 发布