首页 > 试题广场 >

最大子序列

[编程题]最大子序列
  • 热度指数:3949 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
对于字符串x和y, 如果擦除x中的某些字母(有可能全擦掉或者都不擦)能够得到y,我们就称y是x的子序列。例如."ncd"是"nowcoder"的子序列,而"xt"不是。
现在对于给定的一个字符串s,请计算出字典序最大的s的子序列。

输入描述:
输入包括一行,一个字符串s,字符串s长度length(1 ≤ length ≤ 50).
s中每个字符都是小写字母


输出描述:
输出一个字符串,即字典序最大的s的子序列。
示例1

输入

test

输出

tt

这里我必须要说一个问题,字典序较大,就是两个字符串中比较大的元素,也就是java中compareTo的实现。好吧!我***了,哈哈哈。既然要找最的字典序,肯定要找开头最大。贪心算法,从后往前找,如果前者比后者大,则保留,否则就删除。


public class Main { 
public static void main(String[] args) { 
    Scanner input = new Scanner(System.in); 
    String str = input.nextLine(); 
    char[] res = str.toCharArray(); 
    ArrayList<Character> arr = new ArrayList<>(); 
    arr.add(res[res.length-1]); 
    for (int i = res.length-1; i > 0; i--){ 
        if ( arr.get(arr.size()-1) <= res[i-1]){ 
            arr.add(res[i-1]);             
        }         
    }         
    StringBuilder sb = new StringBuilder();         
    for (int i = 0; i < arr.size(); i++){             
        sb.append(arr.get(i));         
    }         
    System.out.println(sb.reverse().toString());     
    } 
}

编辑于 2018-07-12 09:31:29 回复(0)
分析:从后面找单调递增的不连续序列

function getSeq(str) {
    var array = str.split('');
    var str1 = array[array.length-1];
    var res=[str1];
    for(var i=array.length-2;i>=0;i--){
        if(array[i]>=res[res.length-1]){
            res.push(array[i])
        }
    }
    return (res.reverse().join(""))
}
var line=readline();
console.log(getSeq(line));

发表于 2018-08-29 15:58:20 回复(3)
"""
@author:liang
"""
def solution(s):
    n=0
    res=[]
    while s != []:
        res.append(max(s))
        n=s.index(max(s))
        s=s[n+1:]
    return "".join(res)
s=raw_input().strip()
s=list(s)
print solution(s)

发表于 2018-07-19 09:24:52 回复(0)
while(line=readline()){
    var array = line.split("");
    for(var i=array.length-1; i>0; i--){
        if(array[i]>array[i-1]){//如果前一项小于本项
            array.splice(i-1,1)//剔除前一项,确保前面的永远大于后面的
        }
    }
    console.log(array.join(""))
}

发表于 2018-07-10 10:31:45 回复(0)
从后往前遍历字符串,为了保证字典序尽可能大,需要排在前面的字符有较大的ascii码。如果当前字符的ascii码比后面的大就继续向前遍历,否则就抹去该字符。
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));
        StringBuilder sb = new StringBuilder(br.readLine().trim());
        // 从后往前遍历,先把最后一个字符加入
        char lastChar = sb.charAt(sb.length() - 1);
        int i = sb.length() - 2;
        while(i >= 0){
            // 为了保证排在前面的字符ascii码更大,如果当前字符比后面的大就继续向前遍历
            if(sb.charAt(i) >= lastChar){
                lastChar = sb.charAt(i);
                i--;
            }else{
                // 否则就把当前字符删掉
                sb.deleteCharAt(i);
            }
        }
        System.out.println(sb);
    }
}


发表于 2021-02-25 11:37:00 回复(0)
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String in = sc.next();
        int n = in.length();
        TreeMap<Character, Integer> treeMap = new TreeMap<>(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return -o1.compareTo(o2);
            }
        });
        char[] inC = in.toCharArray();
        for (int i=0; i<in.length(); i++) {
            if (treeMap.containsKey(inC[i])) {
                treeMap.put(inC[i], treeMap.get(inC[i]) + 1);
            }
            else {
                treeMap.put(inC[i], 1);
            }
        }
        StringBuilder sb = new StringBuilder(); int index = 0;
        for (Map.Entry<Character, Integer> e: treeMap.entrySet()) {
            char c = e.getKey(); int v = e.getValue();
            if (v == 0) { continue; }
            while (index < n && v > 0) {
                if (inC[index] == c) {
                    v--;
                    sb.append(c);
                }
                treeMap.put(inC[index], treeMap.get(inC[index]) -1);
                index++;
            }
        }
        System.out.println(sb.toString());
    }
}
发表于 2019-04-01 17:26:51 回复(0)
publicclassMain {
publicstaticvoidmain(String[] args) {
Scanner input =newScanner(System.in);
String str = input.nextLine();
char[] res = str.toCharArray();
ArrayList<Character> arr =newArrayList<>();
arr.add(res[res.length-1]);
for(inti = res.length-1; i >0; i--){
if( arr.get(arr.size()-1) <= res[i-1]){
arr.add(res[i-1]);
}
}
StringBuilder sb =newStringBuilder();
for(inti =0; i < arr.size(); i++){
sb.append(arr.get(i));
}
System.out.println(sb.reverse().toString());
}
}

编辑于 2019-01-28 16:59:12 回复(0)
const lines = [];
while (line = readline()) {
    lines.push(line);
}
function MaxStr(s){
    var len=s.length,res=[s[len-1]]
    for(let i=len-2;i>=0;i--){
        if(s[i]>=res[0]){
            res.unshift(s[i])
        }
    }
    return res.join('')
    
}
console.log(MaxStr(lines[0]))

发表于 2018-07-10 23:01:10 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] s = br.readLine().toCharArray();

        StringBuilder sb = new StringBuilder();
        char ch = s[s.length - 1];
        for (int i = s.length - 1; i >= 0; i--) {
            if (s[i] >= ch) {
                sb.append(s[i]);
                ch = s[i];
            }
        }
        System.out.println(sb.reverse());
    }
}

编辑于 2019-01-18 12:29:57 回复(1)
#include <iostream>
using namespace std;
#include <string>
#include <algorithm>

int main()
{
    string s, ret;
    cin >> s;
    while (!s.empty())
    {
        auto it = max_element(s.begin(), s.end());
        ret += *it;
        s.erase(s.begin(), it+1);
    }

    cout << ret << endl;
}
发表于 2018-08-22 11:40:37 回复(0)
不一定要从左往右看,也可以从右往左看,就会发现一个规律:
1.题目要求的最小子序列res必定要取输入字符串s的最后一个元素,然后把min设为最后一个元素的值
2.之后每次取新元素的原则就是,从右往左看,只要新元素大于等于当前的min,就取它,并更新min为新元素的值。
3.重复步骤2,直至到达左端末尾。
代码实现如下:

#include <iostream>
#include <stack>
using namespace std;
int main(){
    string s;
    cin >> s;
    
    stack<char> sc;
    char min_c=*(s.rbegin());
    for(auto it=s.rbegin();it!=s.rend();it++){
        if((*it) >= min_c){
            sc.push(*it);
            min_c=*it;
        }
    }
    
    while(!sc.empty()){
        cout << sc.top();
        sc.pop();
    }
    return 0;
}

发表于 2018-07-25 10:00:57 回复(0)
#include <iostream>
#include <vector>
using namespace std;
//最大递减子序列
int main() {
    string s,res;
    cin>>s;
    char c = s[s.length()-1];
    res += c;
    for(int i=s.length()-2;i>=0;i--)
    {
        if(s[i]>=res[res.length()-1])
        {
            res+=s[i];
        }
    }
    for(int i=res.length()-1;i>=0;i--)
    {
        cout<<res[i];
    }
    cout<<endl;

}

发表于 2023-08-29 15:36:11 回复(0)
class Solution:
    def solve(self, s):
        """思路:单调递减队列(允许重复)"""
        import collections
        queue = collections.deque()
        for char in s:
            if not queue:
                queue.append(char)
                continue
            while queue and queue[-1] < char:
                queue.pop()
            queue.append(char)
        return ''.join(queue)


if __name__ == "__main__":
    so = Solution()
    s = input()
    print(so.solve(s))


def test():
    so = Solution()
    assert so.solve("test") == "tt"
    assert so.solve("ababba") == "bbba"

发表于 2022-04-10 21:00:56 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;cin>>s;
    string ans;
    int maxn=0;
    for(int i=s.length()-1;i>0;i--)
        if(s[i-1]<s[i])  s.erase(i-1,1);
    cout<<s<<endl;
}

从左往右麻烦的一    -----------   L->R(×),R->L(√).
发表于 2022-04-04 16:44:25 回复(0)
#include <iostream>
#include <string>
#include <stack>

using namespace std;

int main() {
    string s;
    getline(cin, s, '\n');
    int n = s.size();
    if (n<2) cout << s << endl;
    stack<char> str;
    str.push(s[n-1]);
    for (int i=n-2; i>=0; --i) {
        if (s[i]>=str.top()) str.push(s[i]);
    }
    string res;
    while (!str.empty()) {
        res += str.top();
        str.pop();
    }
    cout << res << endl;
    return 0;
}

发表于 2021-09-14 20:34:28 回复(0)
s = input().strip()
res = []
for c in s:
    while res and res[-1]<c:
        res.pop()
    res.append(c)
print("".join(res))


发表于 2021-09-07 15:47:06 回复(0)
python3比python2稍微有些不同
def solution(s):
    result = []
    n = 0
    while s != []:
        result.append(max(s))
        n = s.index(max(s))
        s = s[n+1:]
    return "".join(result)
print(solution(list(input())))

编辑于 2021-04-01 10:56:09 回复(0)
没啥可说的,序列自动机优化 - > 倒序遍历

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17+7;
const ll maxn = 2e5+700;
const ll mod= 1e9+7;
const double eps = 1e-9;
const double PI = acos(-1.0);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
char s[105];
int nex[105];
int main(){
	scanf("%s",s+1);
	n = strlen(s+1);
	int pos = -1,mx = -1;
	for(int i=n;i>=0;i--){
		nex[i] = pos;
		if(s[i]-'a'>= mx) pos = i,mx = s[i] - 'a'; 
	}
	int top = 0;
	while(~nex[top]){
		printf("%c",s[nex[top]]);
		top = nex[top];
	}
	return 0;
}
/***
***/


发表于 2020-12-31 13:06:08 回复(0)
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s;
    while(cin>>s)
    {
        for(int i=s.size()-2;i>=0;i--)
        {
            if(s[i]<s[i+1])
                s.erase(i,1);
        }
        cout<<s<<endl;
    }
    return 0;
}

发表于 2020-11-22 14:41:03 回复(0)
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            String str = sc.next();
            Stack<Character> stack = new Stack<>();
            for (char ch : str.toCharArray()){
                while (!stack.isEmpty() && ch > stack.peek())
                    stack.pop();
                stack.push(ch);
            }
            StringBuilder sb = new StringBuilder();
            while (!stack.isEmpty())
                sb.append(stack.pop());
            System.out.println(sb.reverse().toString());
        }

    }
}

发表于 2020-09-05 18:22:39 回复(0)