【每日一题】力扣316.去除重复字母

题目描述(传送门

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例

示例 1:

输入:s = "bcabc"
输出:"abc"

示例 2:

输入:s = "cbacdcbc"
输出:"acdb"

思路

这里首先来看看代码

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @ClassName Demo
 * @Description ${DESCRIPTION}
 * @Author Fangwenhui
 * @Date 2020/12/20/15:46
 */
public class Demo {
    
    
    public static String removeDuplicateLetters(String s) {
    
    
        int len = s.length();
        char[] charArray = s.toCharArray();// 转为字符数组
        int[] lastIndex = new int[26];
        for (int i = 0; i < len ; i++) {
    
    
            lastIndex[charArray[i] - 'a'] = i;//保存字符串中字符最后出现的下标,后边用于判断该元素后边还会不会出现
        }
        Deque<Character>  stack = new ArrayDeque<>();// 双端队列尾插尾删当作栈使用
        boolean[] visited = new boolean[26];// 监视栈里边的元素
        for (int i = 0; i < len ; i++) {
    
    
            if (visited[charArray[i] - 'a']) {
    
    
                continue;// 如果栈内已经出现,那么这里为什莫可以直接舍弃呢,如果栈里边已经存在,如果不丢弃则不能保证最小字典序
                // 如果当前看到的字母已经在栈中,则它一定不是某一段单点递增字母的最后一个字母,所以可以直接舍弃
            }
            while (!stack.isEmpty() && stack.peekLast() > charArray[i] && lastIndex[stack.peekLast() - 'a'] > i) {
    
    
                // 栈顶元素大于字符数组的元素,并且后边还会出现的话就移出栈顶元素
                Character top = stack.removeLast();
                visited[top - 'a'] = false;// 维护visited
            }// 注意这里是while循环,循环结束后保证栈里边都是按照字典序排好的
            stack.addLast(charArray[i]);//说明可以入栈
            visited[charArray[i] - 'a'] = true;// 维护visited

        }
        // 程序走到这里,栈里边保存的就是结果
        StringBuilder stringBuilder = new StringBuilder();
        for (char c : stack) {
    
    
            //System.out.println(c);//注意的是这里用的是双端队列,从头在加入StringBuffer 这样就避免使用栈后还需要反转的问题
            stringBuilder.append(c);
            //System.out.println(stringBuilder.toString());
        }
        return stringBuilder.toString();

    }

    public static void main(String[] args) {
    
    
        System.out.println(removeDuplicateLetters("aqaqwe").toString());

    }
}

首先将字符串转为字符数组,这样就和小标关联起来。方便操作。
需要二个数组,
== lastIndex ==负责记录每个元素在字符串中最后出现的下标;
visited负责记录栈中的元素是否存在,使用Boolean数组
以及需要一个双端队列,和StringBuffer。具体解释见代码里边。

猜你喜欢

转载自blog.csdn.net/weixin_45532227/article/details/111461715