【每日一题】Leetcode - 1081. 不同字符的最小子序列

题目

Leetcode - 1081. 不同字符的最小子序列

解题思路

基本问题:字符串中去除哪一个位置的字符,使得字符串成为只去除一个字符情况下的最小子串?
基本思路:依次比较两个字符,删除大的字符,如果一样大,则后移一位接着两两判断;重复以上操作,(1)如果两个字符不相等,则必定有一个更大,删除大的,结束;(2)如果两个字符相等,一直后移到最后了也依然相等,则只需要丢掉最后一个,结束;

	if (s.length() == 1) {
	    return s;
	}
	
	int delPos = -1;
	for (int i = 1; i < s.length(); i++) {
	    if (s.charAt(i) > s.charAt(i - 1)) {
	        delPos = i;
	        break;
	    } else if (s.charAt(i) < s.charAt(i - 1)) {
	        delPos = i - 1;
	        break;
	    }
	}
	//  has bigger
	if (delPos != - 1) {
	    StringBuilder sb = new StringBuilder();
	    for (int i = 0; i < s.length(); i++) {
	        if (i == delPos) {
	            continue;
	        }
	        sb.append(s.charAt(i));
	    }
	    return sb.toString();
	}// all is equals
	else {
	    return s.substring(0, s.length() - 1 - 1);
	}

本题解题思路就是从以上基本思路中来的,从删一个变成删多个,在上面的情况下每一次要删除或者添加额外需要我们保证唯一可行性和唯一性
唯一可行性:删除的元素,要保证后面还能再找到,也就是不能删掉唯一的元素
唯一性:添加的元素不能重复

正解代码

class Solution {
    
    public String smallestSubsequence(String s) {
        //  simple judge
        if (s.length() == 1) {
            return s;
        }
        
        //  define variable
        char[] chars = s.toCharArray();
        char[] stack = new char[chars.length];
        int[] map = new int[128];

        //  get the count of unique element in the string
        int count = 0;
        for (char ch : chars) {
            if (map[ch] == 0) {
                count++;
                map[ch] = 1;
            }
        }

        // recover map
        Arrays.fill(map, 0);

        int top = -1;
        stack[++top] = chars[0];
        map[chars[0]] = 1;
        for (int i = 1; i < chars.length; i++) {
            //  stack has curent element, skip
            if (map[chars[i]] == 1) {
                continue;
            }
            //  cycle update smaller element
            while (top != -1 && chars[i] < stack[top]) {
                //  try push, judge the bigger element has more after the pos
                int j;
                for (j = i + 1; j < chars.length; j++) {
                    if (stack[top] == chars[j]) {
                        break;
                    }
                }

                // after do not have the bigger element, keep now, think it bigger than top
                if (j == chars.length) {
                    break;
                }
                //  delete its mark
                map[stack[top]] = 0;
                //  delete it in the stack,
                --top;
            }
            //  element bigger than top of stack, push it to stack
            stack[++top] = chars[i];
            //  mark it
            map[chars[i]] = 1;
        }

        return String.valueOf(stack, 0, count);
    }

}

在这里插入图片描述

优化

相似

Leetcode - 402. 移掉 K 位数字
Leetcode - 1081. 不同字符的最小子序列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值