首页 > 试题广场 >

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

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

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


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

输入

acbc

输出

abc
示例2

输入

dbcacbca

输出

dabc

备注:
时间复杂度,额外空间复杂度
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)
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)
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)
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)