leetCode316:去除重复字母

目录

一、题目描述

二、解题思路

三、代码实现


一、题目描述

给你一个字符串 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 由小写英文字母组成

二、解题思路

这道题看题目要求字符去重并且字典序最小,字符要去重肯定要统计字符的出现次数,保持字符的相对顺序不变,是不是很熟悉的要求,没错,这题是单调栈和哈希的结合。需要注意的点有两个:

  1. 栈顶弹出的要求:当前字符比栈顶字符小时需要考虑是否弹出栈顶;
  2. 弹出的条件是当前字符没有在栈中出现(换句话说如果当前字符已经在栈中,则直接跳过不做处理);

三、代码实现

#include <bits/stdc++.h>
using namespace std;

//再用一个数组记录字符是否出现在栈中时间效率会比使用find好
//另外使用栈的时候注意可替代的数据结构,vector,string等都具有栈具备的操作,使用时灵活选择
//本题选用string替换栈效率就比直接使用栈或者vector的效率好
string removeDuplicateLetters(string s) {
	int length = s.size();
	unordered_map<char, int> chCnt;
	for (int i = 0; i < length; i++) {
		chCnt[s[i]]++;
	}
	string chSta;
	for (int i = 0; i < length; i++) {
		chCnt[s[i]]--;
		if (chSta.empty()) {
			chSta.push_back(s[i]);
		}else {
			//如果栈中已有这个字符就直接跳过
			if (chSta.find(s[i]) != string::npos) continue; 
			while (!chSta.empty() && s[i] < chSta.back() && chCnt[chSta.back()] > 0) {
					chSta.pop_back();
			}
				chSta.push_back(s[i]);
		}
	}
	return chSta;
}
	
int main() {
	string s = "aeace";
	cout << removeDuplicateLetters(s);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值