首页 > 其他分享 >leet code 316. 去除重复字母

leet code 316. 去除重复字母

时间:2023-11-19 21:02:01浏览次数:28  
标签:字符 leet 遍历 charAt int 316 length code ans

316. 去除重复字母

题目描述

  • 给你一个字符串 s
  • 请你去除字符串中重复的字母
  • 使得每个字母只出现一次。
  • 需保证 返回结果的字典序最小
  • (要求不能打乱其他字符的相对位置)。

示例 1:

输入:s = "bcabc" 输出:"abc"

示例 2:

输入:s = "cbacdcbc" 输出:"acdb"

提示:

  • leet code 316. 去除重复字母_结果集
  • s 由小写英文字母组成

题目解析

  • 考虑从前往后遍历或者从后往前遍历
  • 题目要求需要保证字典序不变
  • 那么最终的输出结果中的每一个字符,需要考虑和全局的关系
  • 以 字符串 s = "cbacdcbc" 为例
  • 遍历到字符 c,记结果集为 ans = c
  • 遍历到字符 b,很显然 b < c 并且没有遍历到的字符中,还存在有 c
  • 所以删除 c, ans = b
  • 遍历到字符a, a < b同理删除b,ans = a
  • 遍历到字符c, c > a, --> ans = ac
  • ...................d, d > c, --> ans = acd
  • ...................c, ans = acd,字符c已经存在跳过
  • ...................b, b < d,后续没有 b 了,---> ans = acdb
  • ...................c,跳过,最终 ans = acdb
  • 所以需要预统计字符串s中各个字符出现的次数

show code

class Solution {
    public String removeDuplicateLetters(String s) {
        int[] cnt = new int[26];
        int n = s.length();
        // 统计 s 中各个字符各多少个
        for (int i = 0; i < n; i++) {
            cnt[s.charAt(i) - 'a']++;
        }
        // 用于标记结果集合中已经添加的字符
        boolean[] sign = new boolean[26];


        StringBuilder ans = new StringBuilder();
        for (int i = 0; i < n; i++) {
            char at = s.charAt(i);
            cnt[at - 'a']--;
            // 重复的字符直接跳过
            if(sign[at - 'a']) {
                continue;
            }
            // 以 c b 为例,遍历到字符 b; b < c  并且后续还有字符 c 
            // 判断条件:结果集中存在有值 且 at < 结果集中的最后一个字符,且该字符在右边还有
            while(ans.length() > 0 && at < ans.charAt(ans.length() - 1) && cnt[ans.charAt(ans.length() - 1) - 'a'] > 0) {
                // 移除 标记
                sign[ans.charAt(ans.length() - 1) - 'a'] = false;
                // 移除 c
                ans.deleteCharAt(ans.length() - 1);
            }
            ans.append(at);
            // 标记
            sign[at - 'a'] = true;
        }
        return ans.toString();
    }
}

参考

https://leetcode.cn/problems/remove-duplicate-letters/solutions/2381483/gen-zhao-wo-guo-yi-bian-shi-li-2ni-jiu-m-zd6u/

标签:字符,leet,遍历,charAt,int,316,length,code,ans
From: https://blog.51cto.com/u_16079703/8475564

相关文章

  • 【11月LeetCode组队打卡】Task2--TrieTree
    字典树Trie音同try,又称前缀树,是一颗有根树,根节点到树节点的一个路径就代表一个单词,多用于关键词检索,自动补完和拼写检查用空间换时间:借公共前缀来降低查询时间的开销根节点无内容(参考:字典树TrieTree图文详解——CSDN实现Trie题解——力扣)208.实现Trie复习一下this......
  • 探索CodeFuse:AI助力编程效率的新高度
    引言在人工智能与软件开发的交汇点,CodeFuse以其独树一帜的技术实力和应用广度,正引领着一场编程界的AI革命。作为蚂蚁集团自研的代码生成模型,CodeFuse不仅在多语言编程支持、代码生成和优化方面展现出卓越性能,而且在提升开发效率、降低编程门槛方面具有革命性意义。CodeFuse技术深度......
  • AtCoder Beginner Contest(abc) 329
    B-Next难度:⭐题目大意给定n个数,输出其去重后的次大值;解题思路暴力就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#defineendl'\n'usingnamespacestd;constintN=2e......
  • AT_code_festival_2018_quala_b题解
    题意给定一个序列,里面的值只有可能是\(a\)或\(b\)(\(a<b\))。有\(m\)个区间,这里面的值必须是\(a\),求如何是序列总和最大。思路因为\(n\)和\(m\)都只有100,所以可以先暴力将所有值设为\(b\),再将区间里的值暴力修改为\(a\),最后统计答案。ACCODE#include<bits/stdc......
  • AT_gigacode_2019_b 题解
    本题考查基本语法。思路用while来枚举每一组数据,用if判断是否合法。在判断时需要使用逻辑运算符&&,它的意思是左右两个要求如果同时成立,则会返回true,否则返回false。\(a\gex\),\(b\gey\),\(a+b\gez\)。这三个条件都要同时成立,所以可以使用&&。ACCODE#include......
  • leet code78. 子集 && 90. 子集 II
    78.子集90.子集II78.题目描述给你一个整数数组nums,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。示例1:输入:nums=[1,2,3]输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]示例2:输入:nums=[0]输......
  • Siemens和Codesys关于OPC UA 服务器的基础配置
    西门子配置步骤如下打开设备属性——>OPCUA 激活OPCUA服务 设备URL地址 通用设置端口:设置服务器的端口号,默认4840,允许范围:1024-49151之间最大会话超时时间:指定在不进行数据交换的情况下OPCUA服务器关闭会话之前的最大时长。默认30s,允许范围:1-600000s之......
  • AtCoder Beginner Contest(abc) 296
    B-Chessboard难度:⭐题目大意给定一个8*8的字符矩阵,其中只有一个'*',输出它的坐标;其坐标的列用字母表示,行用数字表示,具体看样例解释;解题思路签到题不多嗦了;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio......
  • Code-C++-字符串分割
    Code-C++-字符串分割转自【C++中string如何实现字符串分割函数split()——4种方法-CSDNApp】http://t.csdnimg.cn/8iWb7stringstreamgetline()stringfind()substr()ccharstrtok()strtok_r()regex_token_iterator<>getline()voidStringsplit(stringstr,const......
  • Educational Codeforces Round 13 E
    tilian最开始看错了以为是可以任意选择两人or选择一人胜出但题意是可以选择下一个擂主是谁考虑dp的话我们显然需要记录一个state以及当前擂主是谁转移就是dp[state][i]=max(dp[state][i],dp[state(1<<j)][j]*a[i][j]+dp[state(1<<i)]*a[j][i])意义是我们枚举他后一个交......