首页 > 试题广场 >

删除多余的字符得到字典序最小的字符串

[编程题]删除多余的字符得到字典序最小的字符串
  • 热度指数:1776 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给一个全是小写字母的字符串str,删除多余字符,使得每种字符只保留一个,并且让最终结果字符串字典序最小。

输入描述:
输入包含一行字符串,代表str


输出描述:
输出一行,代表删除后的字符串。
示例1

输入

acbc

输出

abc
示例2

输入

dbcacbca

输出

dabc

备注:
时间复杂度,额外空间复杂度
人生苦短,我用Python,c语言你起来一下,耽误我过OJ了~
string=input()
for i in string:
    counts = string.count(i)
    if counts>1:
        string =string.replace(i,'',counts-1)
print(string)


发表于 2020-01-01 10:20:05 回复(5)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXLEN 100001

char *removeDuplicateLetter(char *str) {
    int map[26], len = (int) strlen(str);
    char *res = (char *) malloc(len + 1);
    memset(map, 0, sizeof(int) * 26);
    for (int i = 0; i < len; i++) {
        map[str[i] - 'a']++;
    }
    int l = 0, r = 0, index = 0;
    while (r < len) {
        if (map[str[r] - 'a'] == -1 ||
            --map[str[r] - 'a'] > 0) {
            r++;
            continue;
        }
        int pick = -1;
        for (int i = l; i <= r; i++) {
            if (map[str[i] - 'a'] != -1 &&
                (pick == -1 || str[i] < str[pick]))
                pick = i;
        }
        res[index++] = str[pick];
        for (int i = pick + 1; i <= r; i++) {
            if (map[str[i] - 'a'] != -1)
                map[str[i] - 'a']++;
        }
        map[str[pick] - 'a'] = -1;
        l = pick + 1;
        r = l;
    }
    res[index] = '\0';
    return res;
}

int main(void) {
    char str[MAXLEN], *res;
    scanf("%s", str);
    res = removeDuplicateLetter(str);
    printf("%s", res);
    free(res);
    return 0;
}

发表于 2022-02-08 17:44:59 回复(0)
#获得输入的字符串
str = input()
#使用集合去重
str_set = set(str)
#sorted函数返回列表
out = sorted(str_set)
# "".join(out)列表转字符串  out.split(" ")反转
print("".join(out))
感觉题目有点问题,示例输入输出二和我本地运行不相同,在输入为dbcacbca时,我的输出为abcd

发表于 2019-08-12 08:47:41 回复(5)
遍历字符串,挨个存入set,用set来实现自动去重和排序。
发表于 2021-08-07 07:37:12 回复(0)
emmmm……,这个解法有点low,但还是AC了。先统计整个字符串中每个字符的频数,然后创建一个指向字符串头部的指针i,往右滑动更新频数表(自减),并在沿途记录最小ASCII码字符所在的位置minAsciiIndex,如果发现某个字符再自减一次就没有了,就进行如下操作
  1. minAsciiIndex之前的字符全部不要了,因为字典序比str[minAsciiIndex]大,且这些大字典序的字符在后面的子串中还有;
  2. minAsciiIndex之后的子串将str[minAsciiIndex]去掉,相当于确定了最小字符的位置,后面的最小字符是多余的,不再需要了;
  3. minAsciiIndex之后的子串再进行这个操作,确定第二小的字符拼接在最小字符的后面。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        System.out.println(remove(str));
    }
    
    private static String remove(String str) {
        if(str == null || str.length() < 2) return str;
        int[] termFreq = new int[26];
        for(int i = 0; i < str.length(); i++) termFreq[str.charAt(i) - 'a'] ++;
        int minAsciiIndex = 0;
        for(int i = 0; i < str.length(); i++){
            if(--termFreq[str.charAt(i) - 'a'] == 0){
                break;
            }else{
                minAsciiIndex = str.charAt(i) < str.charAt(minAsciiIndex)? i: minAsciiIndex;
            }
        }
        String minAlpha = String.valueOf(str.charAt(minAsciiIndex));
        return minAlpha + remove(str.substring(minAsciiIndex + 1).replaceAll(minAlpha, ""));
    }
}

发表于 2021-11-29 11:58:19 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    cin>>s;
    int n = s.length();
    map<char, int> mp;
    for(int i=0;i<n;i++)
        mp[s[i]]++;
    for(auto &c: mp)
        printf("%c", c.first);
    return 0;
}

发表于 2020-05-12 00:27:00 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String  s = in.nextLine();
        System.out.println(deal(s));
    }
    public static String deal(String s) {
        int n = s.length();
        HashMap<Character, Integer> map = new HashMap<>();
        boolean[] visited = new boolean[128];
        char[] cs = s.toCharArray();
        Stack<Character> stack = new Stack<>();
        //统计数字
        for (int i = 0; i < n; i++) {
            map.put(cs[i], map.getOrDefault(cs[i], 0) + 1);
        }
        for (int i = 0; i < n; i++) {
            char c = cs[i];
            map.put(c, map.get(c) - 1);
            if (visited[c]) continue;
            //没访问过的
            while (!stack.isEmpty() && stack.peek() > c && map.get(stack.peek()) > 0) {
                visited[stack.pop()] = false;
            }
            //当前字符计进入
            stack.push(c);
            visited[c] = true;
        }
        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()) {
            sb.insert(0, stack.pop());
        }
        return sb.toString();
    }
}

发表于 2023-03-20 16:27:52 回复(0)
这个题有问题吧,这样也过
import java.io.*;
public class Main{
    public static void main(String[] args) throws Exception{
        System.out.print("stupid problem");
    }
}


发表于 2022-05-25 21:18:00 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Main {
      public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String str = br.readLine();
            System.out.println(remove(str));
        }

        static String remove(String str) {
            Map<Character, Integer> strMap = new HashMap<>();
            for (Character c: str.toCharArray()) {
                strMap.put(c, strMap.getOrDefault(c, -1) + 1);
            }
            Stack<Character> s = new Stack();
            int len = strMap.keySet().size();
            for (Character c: str.toCharArray()) {
                while (!s.isEmpty() && s.peek() >= c && strMap.get(s.peek()) >= 1) {
                    Character top = s.peek();
                    s.pop();
                    strMap.put(top, strMap.get(top) - 1);
                }
                s.add(c);
            }
            StringBuilder res = new StringBuilder();
            while (!s.isEmpty() && len > 0) {
                res.append(s.peek());
                s.pop();
                len --;
            }
            res.reverse();
            return res.toString();
        }
}
发表于 2022-04-23 21:06:29 回复(0)
# 寻找字符串中字典序最小的字符
def getChar(string):
    string_length = len(string)
    if string_length == 0:
        return ''
    else:
        result = string[0]
        for i in range(1, string_length):
            if string[i] < result:
                result = string[i]
    return result


# 构建字符串的词频表
def getCharCount(string):
    result = {}
    for i in string:
        if i not in result.keys():
            result[i] = 1
        else:
            result[i] += 1
    return result


# 删除掉字符串中某个指定的字符
def deleteChar(string, char):
    result = ''
    for i in string:
        if i == char:
            continue
        else:
            result += i
    return str(result)


# 输入字符串
string = input()
# 获取字符串词频分布表
char_count = getCharCount(string)
char_count_length = len(char_count.keys())
result = []
while len(result) != char_count_length:
    # 当前遍历位置
    i = 0
    # 当前字符串长度
    string_length = len(string)
    # 遍历字符串
    for i in range(string_length):
        char_count[string[i]] -= 1
        # 需要进行选择的位置
        if char_count[string[i]] == 0:
            break
    # 如果当前位置是字符串最后一个位置
    if i + 1 == string_length:
        result_char = getChar(string)
        result.append(result_char)
        string = deleteChar(string, result_char)
    else:
        result_char = getChar(string[:i + 1])
        result.append(result_char)
        string = deleteChar(string[i:], result_char)

    # 重新构建词频表
    char_count = getCharCount(string)
print(''.join(result))
贪心思想
发表于 2022-04-03 11:10:09 回复(0)
c++ set实现
#include<bits/stdc++.h>
using namespace std;

int main() {
    string str;
    set<char> set;
    while (cin >> str) {
        for (char c : str) {
            set.emplace(c);
        }
    }
    for (auto iter = set.begin(); iter != set.end(); iter++) {
        cout << *iter;
    }
}


发表于 2022-03-31 17:40:40 回复(0)
这里的测试样例有问题,leetcode原题为316
发表于 2022-02-17 11:09:58 回复(0)
import java.util.LinkedList;
import java.util.Scanner;

public class Main {

    public static void main(String args[]) throws Exception{
        Scanner in = new Scanner(System.in);
        String str = in.next();
        int[] nums = new int[30];
        for (int i = 0; i < str.length(); i++) {
            nums[str.charAt(i) - 'a'] = i;
        }

        LinkedList<Character> queue = new LinkedList<>();
        queue.add(str.charAt(0));

        for(int i = 1; i < str.length(); i++) {

            while (!queue.isEmpty() &&
                    queue.indexOf(str.charAt(i)) == -1 &&
                    nums[queue.get(queue.size() - 1) - 'a'] > i &&
                    str.charAt(i) < queue.get(queue.size() - 1)) {
                queue.removeLast();
            }
            if(queue.indexOf(str.charAt(i)) == -1) {
                queue.add(str.charAt(i));
            }
        }

        StringBuilder sb = new StringBuilder("");
        for (char ch : queue) {
            sb.append(ch);
        }

        System.out.println(sb.toString());

    }


}

发表于 2021-07-27 10:16:13 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
             String str=sc.nextLine();
             solve(str,"");
        }
       
        sc.close();
    }
    public static void solve(String str,String res) {
		if(str.isEmpty()) {
			System.out.println(res);
			return;
		}
		String s=str.substring(0,1);
		if(res.contains(s)) {
			String tmp=res.replace(s, "").concat(s);
			if(tmp.compareTo(res)>0) {
				str=str.replace(s, "");
			}else {
				res=tmp;
				str=str.substring(1);
			}
		}else {
			res=res.concat(s);
			str=str.substring(1);
		}
		solve(str,res);
	}
}

发表于 2021-02-02 21:28:08 回复(0)
#data_in = input()
data_in = "cbbcbbcbcca"

def drawer(data_in):
    """用一个抽屉有序保存检测到的字母"""
    dr = [""]*26
    for i in data_in:
        index = ord(i) - ord("a")
        if not dr[index]:
            dr[index] = chr(ord("a")+index)
    print("".join(dr))

drawer(data_in)


编辑于 2021-01-25 15:03:58 回复(0)
#include<iostream>
#include<string.h>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        string ans="";
        int count[26]={0};
        for(auto ch:str)
            count[ch-'a']++;
        for(int i=0;i<26;i++)
            if(count[i]>=1)
                ans+='a'+i;
        cout<<ans<<endl;
    }
}

发表于 2020-12-01 17:08:44 回复(0)
if __name__ == '__main__':
    test_data = input()
    # test_data = 'dbcacbca'
    
    output = ''
    visual = [0, ] * 256
    record = [0, ] * 256
    
    # build record
    for vl in test_data:
        record[ord(vl)] = record[ord(vl)] + 1
        
    # filter    
    for vl in test_data:
        record[ord(vl)] = record[ord(vl)] - 1
        
        if visual[ord(vl)] == 1:
            continue
        
        while len(output) > 0 and output[-1] > vl and record[ord(output[-1])] > 0:
            visual[ord(output[-1])] = 0
            output = output[:-1]
        
        output  = output + vl
        visual[ord(vl)] = 1
        
    print(output)    

测试案例全通过,时间复杂度O(n)O(n),额外空间复杂度O(1)O(1)
编辑于 2020-05-26 22:22:39 回复(0)
public static String RemoveDup(String s){
        if (s.length() < 2) {
            return s;
        }
        Map<Character,Integer> m = new HashMap<Character,Integer>();
        char[] chs = s.toCharArray();
        List<Integer> list = new ArrayList<Integer>();
        int tmp = -1;
        ll:
        for(int i = chs.length-1; i >= 0; i--){
            if (m.containsKey(chs[i])){
                if (chs[i] >= tmp){
                    list.add(i);
                    continue ll;
                }else{
                    list.add(m.get(chs[i]));
                    m.put(chs[i], i);
                    tmp = (int)chs[i];
                    continue ll;
                }
            }
            m.put(chs[i], i);
            tmp = chs[i];
        }
        for (Integer num : list) {
            chs[num] = '-';
        }
        String str = new String(chs);
        return str.replaceAll("-", "");
    }


发表于 2020-05-08 11:45:27 回复(0)

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()){
            String input = scanner.next();
            System.out.println(del(input));
        }
    }

    public static String del(String input){
        char[] str  = input.toCharArray();
        int[] map = new int[26];
        for(int i=0;i<str.length;i++){
            // 字母出现次数统计,记得要减去'a'
            map[str[i] - 'a']++;
        }
        // 结果
        char[] res = new char[26];
        // res的目前最后一位
        int index = 0;
        int l = 0;
        int r = 0;
        while(r != str.length){
            // 若此字符已挑选过,或是后面还会出现,则跳过
            if(map[str[r] - 'a'] == -1 || --map[str[r] - 'a']>0){
                r++;
            }else{
                // 挑选出字典序最小的字符,遍历一遍从左到右依次比较即可
                int pick = -1;
                for(int i=l;i<=r;i++){
                    if(map[str[i] - 'a'] != -1 && (pick == -1 || str[i]<str[pick])){
                        pick = i;
                    }
                }
                // 把挑选结果放入结果
                res[index++] = str[pick];
                // 把后面的还要考虑的字符数加回来
                for(int i=pick+1;i<=r;i++){
                    if(map[str[i] - 'a'] != -1){
                        map[str[i] - 'a']++;
                    }
                }
                // 标记为已挑选过的字符
                map[str[pick] - 'a'] = -1;
                l = pick+1;
                r = pick+1;
            }
        }

        return String.valueOf(res);
    }

}

编辑于 2020-05-07 11:10:23 回复(0)
#include<stdio.h>
int main(){
    int d[201]={0};
    char c;
    while(scanf("%c",&c)!=EOF){
        int k=c;
        d[k]=1;
    }
    int i;
    for(i=97;i<201;i++){
        if(d[i]!=0) printf("%c",i);
    }printf("\n");
    return 0;
}

发表于 2020-03-29 22:21:04 回复(0)