20200213:去除重复字母(leetcode316)

去除重复字母

  • 题目
  • 思路与算法
  • 代码实现

题目

20200213:去除重复字母(leetcode316)_第1张图片

思路与算法

  • 首先对字符串进行遍历,将当前字符串依次入栈,

  • 注意入栈的条件:

    • 新入栈的元素在栈内没有出现过,必须是未出现过的元素
    • 新入栈的元素如果比栈顶元素大,(ASCII码大小关系)则直接入栈
    • 新入栈的元素如果比栈顶元素小,则需要判断当前栈顶元素在后续未入栈元素中是否还存在,如果存在,为了满足字典序的最小,则将当前栈顶元素直接出栈,入栈新元素即可。

根据以上三个条件,配合栈的数据结构,即可完成代码,跑题效果如下:
20200213:去除重复字母(leetcode316)_第2张图片

代码实现

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;
	}
}

你可能感兴趣的:(leetcode学习记录篇,算法,leetcode,数据结构,栈)