20200213:去除重複字母(leetcode316)

題目

在這裏插入圖片描述

思路與算法

  • 首先對字符串進行遍歷,將當前字符串依次入棧,

  • 注意入棧的條件:

    • 新入棧的元素在棧內沒有出現過,必須是未出現過的元素
    • 新入棧的元素如果比棧頂元素大,(ASCII碼大小關係)則直接入棧
    • 新入棧的元素如果比棧頂元素小,則需要判斷當前棧頂元素在後續未入棧元素中是否還存在,如果存在,爲了滿足字典序的最小,則將當前棧頂元素直接出棧,入棧新元素即可。

根據以上三個條件,配合棧的數據結構,即可完成代碼,跑題效果如下:
在這裏插入圖片描述

代碼實現

package com.immunize.leetcode.removeDuplicateLetters;

import java.util.Stack;

public class Solution {

	public String removeDuplicateLetters(String s) {
		String res;
		int len = s.length();
		// 特判
		if (len < 2) {
			return s;
		}

		// 記錄是否在已經得到的字符串中
		boolean[] Existed = new boolean[26];

		// 記錄每個字符出現的最後一個位置
		int[] lastIndex = new int[26];
		for (int i = 0; i < len; i++) {
			lastIndex[s.charAt(i) - 'a'] = i;
		}

		// 新建字符棧
		Stack<Character> stack = new Stack<>();
		stack.push('a');
		// 遍歷字符串s的每一個字符,
		for (int j = 0; j < len; j++) {
			char currentChar = s.charAt(j);
			// 如果當前字符已經在set中出現過了,則這個我們不需要
			if (Existed[currentChar - 'a']) {
				continue;
			}
			// 如果棧非空,且棧頂元素比當前元素大且棧頂字符後面還有,則將棧頂元素出棧,並將對應的set設爲false,表示這個字符不要了,後續碰到新的可以直接加
			while (stack.peek() > currentChar && lastIndex[stack.peek() - 'a'] >= j) {
				char top = stack.pop();
				Existed[top - 'a'] = false;
			}
			// 否則,直接入棧,並將set設爲true,表示棧內現在有這個元素
			stack.push(currentChar);
			Existed[currentChar - 'a'] = true;
		}
		int size = stack.size();
		// 新建sb,如果棧非空,則將棧內元素依次出棧,並放入sb,最後轉化爲string類型即可。
		StringBuilder stringBuilder = new StringBuilder();
		for (int k = 0; k < size - 1; k++) {
			stringBuilder.insert(0, stack.pop());
		}
		res = stringBuilder.toString();
		return res;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章