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;

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

* 示例 1: *

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

* 示例 2: *

* 输入: "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 memory = new HashMap<>(); //记录哪些节点已经放入了栈中 Map memory2 = new HashMap<>(); Stack 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); } }

 

 

 

 

 

你可能感兴趣的:(基础算法学习)