算法-leetcode-字符串问题- 316. 去除重复字母

文章目录

    • 9, `316. 去除重复字母`
      • 思路1: 暴力法贪心策略递归
      • 思路2: 暴力法贪心策略递归优化
      • 思路3: 栈结构实现:通过思路2优化中的方式来判断后续是否有副本
      • 思路4: 栈结构实现:通过hashmap存储最后索引来判断后续是否有副本

9, 316. 去除重复字母

思路1: 暴力法贪心策略递归

  • 找到结果的第一个字母:从原字符串的头遍历到尾,默认结果的第一个字母为原字符串的0位置字母,如果后续有比0位置字母小,设定为位置i,
    • 而且位置i之前的字母,位置i之后都有,那么i就可以成为首字母。
  • 遍历结束,最后的那个就是结果的首字母
  • 然后迭代调用上面的逻辑进行其余字母的确定
    • 迭代的时候,如果剩余的字符串包含首字母可以剔除处理

思路2: 暴力法贪心策略递归优化

  • 思路1中通过遍历i之前和i之后的位置的方式来确定:位置i之前的字母,位置i之后都有,那么i就可以成为首字母。
  • 这里通过直接记录每个字母的个数,在找i位置的过程的时候,直接把个数减去,如果到了i位置, 而且i之前的字母的个数不为0,则说明i之前的字母,在i之后还存在。那么i就可以成为代选首字母

思路3: 栈结构实现:通过思路2优化中的方式来判断后续是否有副本

  • 第一个字母先存入栈中
  • 第二个字母判断跟第一个字母关系,
    • 如果比第一个小, 而且第一个字母在后续还有其他的,那么第一个字母出栈丢弃,第二个字母入栈
    • 否则第二个字母入栈
  • 第三个字母判断跟第二个字母关系
    • 同上了

思路4: 栈结构实现:通过hashmap存储最后索引来判断后续是否有副本

package com.shangguigu.dachang.algrithm.A03_Strings;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;

/**
 * @author : 不二
 * @date : 2022/4/8-下午2:27
 * @desc : 316. 去除重复字母
 * https://leetcode-cn.com/problems/remove-duplicate-letters/
 *
 **/
public class A33_removeDuplicateLetters {
   
    public static void main(String[] args) {
   

//        String s = "db";
//        String s = "cbacdcbc";
        String s = "ecbacba";
        // String result = removeDuplicateLetters(s);
        // String result = removeDuplicateLetters_optimize(s);
        String result = removeDuplicateLetters_by_stack_v1(s);
        System.out.println("结果是:" + result);
    }


    /**
     * 思路4: 栈结构实现:通过hashmap存储最后索引来判断后续是否有副本
     * @param s
     * @return
     */
    public static String removeDuplicateLetters_by_stack_v1(String s) {
   
        Stack<Character> stack = new Stack<>();

        // 一共26个字母
        /*int[] theArr = new int[26];
        for (int i = 0; i < s.length(); i++) {
            theArr[s.charAt(i) - 'a'] += 1;
        }*/
        // 这里也可以通过hashmap实现去重,记录出现的最后位置, 也很妙
        // 后续判断获取的数据是否大于当前索引就能判断出后续是否有其他副本
        HashMap<Character, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
   
            hashMap.put(s.charAt(i), i);
        }


        HashSet<Character> set = new HashSet<>();

        // 第一个数据先入栈(这里不能这么搞,因为如果单独搞,后续这个数组里面的个数就无法减为0)
        // stack.push(s.charAt(0));
        // 第二个开始遍历
        for (int i = 0; i < s.length(); i++) {
   
            // theArr[s.charAt(i)-'a']--;

            // 如果当前的比之前的小,而且之前没有push过,而且之前的这个数据之后还有
            while (!stack.isEmpty() && stack.peek()>s.charAt(i) && hashMap.get(stack

你可能感兴趣的:(算法,java,算法,leetcode)