leetcode刷题笔记316题 去除重复字母
源地址:316. 去除重复字母
问题描述:
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同
示例 1:
输入:s = "bcabc"
输出:"abc"
示例 2:输入:s = "cbacdcbc"
输出:"acdb"提示:
1 <= s.length <= 104
s 由小写英文字母组成
//结合贪心与栈的方法
//使用一个数组存储每个字符的最后位置 使用一个stack存储结果
//若语言缺乏包含函数,使用一个map存储当前字符是否已经存在
//核心思想 当前字符不存在于结果中 并且 结果末尾字符比当前字符大 且 当前字符未到达其最大位置 将其弹出
//否则压入栈中
import scala.collection.mutable
import util.control.Breaks._
object Solution {
def removeDuplicateLetters(s: String): String = {
val stack = mutable.Stack[Char]()
val lastMap = mutable.Map[Char, Int]()
for (i <- 0 to s.length-1) {
lastMap(s(i)) = i
}
for (i <- 0 to s.length-1) {
breakable{
val temp = s(i)
if (stack.contains(temp) == true) break()
//println("-------------------------")
//println("stack.length: " + stack.length)
//println("stack.top: " + stack.top)
//println("prestack: " + stack.mkString)
while (stack.length > 0 && stack.top > temp && lastMap(stack.top) > i) {
//println("stack.top: " + stack.top)
val top = stack.pop
//stack.push(temp)
}
stack.push(temp)
}
//println("afterstack: " + stack.mkString)
}
return stack.mkString.reverse
}
}
import "fmt"
func removeDuplicateLetters(s string) string {
length := len(s)
stack := []byte{}
ins := make(map[byte]bool)
last := make(map[byte]int)
for i := 0; i < length; i++ {
last[s[i]] = i
}
for i := 0; i < length; i++ {
temp := s[i]
if ins[s[i]] == true {
continue
} else {
for len(stack) > 0 && stack[len(stack) - 1] > temp && last[stack[len(stack) - 1]] > i {
ins[stack[len(stack) - 1]] = false
stack = stack[0:len(stack) - 1]
}
stack = append(stack, temp)
ins[temp] = true
}
}
return string(stack)
}