leetcode 去除重复字母

题目:

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

示例 1:

输入: "bcabc"
输出: "abc"

示例 2:

输入: "cbacdcbc"
输出: "acdb"

分析:

1.什么叫字典序:26个英文字母的顺序

2.什么叫字符的相对位置,就是你只能删除重复的但是不能左右移动元素

我们来模拟下从第一个元素到最后一个元素的过程算法就出来了:

 step1:c

step2:cb

step3:cba

step4:bac

step5:bacd

step6:acdb

按照我们的思维来写算法:定义一个结果集,依次遍历每个元素,结果集不存在就加入,如果存在就判断两个元素之间的元素有没有比当前元素小的,有的话就删掉之前的,比如bacdb,两个b之间有a比b小,所以要删掉之前的b,改成acdb

这里用另一个方法栈+标志来实现

说明:栈中存的元素满足两个条件之一就可以:1.元素都是递增的,2,当前元素在后续不在出现(过了这个村就没这个店了)

算法:

package com.bysj.common.算法;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 给定一个仅包含小写字母的字符串,去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
 * <p>
 * 示例 1:
 * <p>
 * 输入: "bcabc"
 * 输出: "abc"
 * <p>
 * 示例 2:
 * <p>
 * 输入: "cbacdcbc"
 * 输出: "acdb"
 */
public class 去除重复字母 {
    public static String removeDuplicateLetters(String s) {
        if (s == null || s.equals("")) {
            return "";
        }
        char[] strArr = s.toCharArray();
        return getResult(strArr);
    }

    public static String getResult(char[] strArr) {
        String result = "";
        //记录所有几点的最后一个出现的位置
        Map<Character, Integer> memory = new HashMap<>();
        //记录哪些节点已经放入了栈中
        Map<Character, Boolean> memory2 = new HashMap<>();
        Stack<Character> stack = new Stack();

        for (int i = 0; i < strArr.length; i++) {
            memory.put(strArr[i], i);
            memory2.put(strArr[i], false);
        }
        //第一个元素特殊处理下便于理解
        stack.add(strArr[0]);
        memory2.put(strArr[0], true);

        for (int i = 1; i < strArr.length; i++) {
            //如果节点没有出现在栈中
            if (!memory2.get(strArr[i])) {
                //如果栈顶节点大于当前节点并且该节点后续还会出现,取出栈顶节点然后继续取栈第二节点继续比较
                while (!stack.isEmpty() && strArr[i] < stack.peek()) {
                    if (memory.get(stack.peek()) > i) {
                        memory2.put(stack.peek(), false);
                        stack.pop();
                    } else {
                        break;
                    }
                }
                //当循环完了后,当前节点肯定大于栈顶元素,入栈,记录该节点已经入栈了
                stack.push(strArr[i]);
                memory2.put(strArr[i], true);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        while (!stack.empty()) {
            stringBuilder.insert(0, stack.pop());
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        String result = removeDuplicateLetters("bacacca");
        System.out.println(result);
    }
}
发布了23 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq1076472549/article/details/103753434