package a_od_test;
import java.util.*;
/*
字符串解密
知识点数组字符串排序Q
时间限制:1s空间限制:256MB限定语言:不限
题目描述:
给定两个字符串string1和string2。
string1是一个被加扰的字符串。string1由小写英文字母('a'~'z)和数字字符(0'~'9)组成,而加扰字符串由'0'~'9'、'a'~'f'组成。
string1里面可能包含0个或多个加扰子串,剩下可能有0个或多个有效子串,这些有效子串被加扰子串隔开。
string2是一个参考字符串,仅由小写英文字母('a'~'z')组成。
你需要在string1字符串里找到一个有效子串,这个有效子串要同时满足下面两个条件:
(1)这个有效子串里不同字母的数量不超过且最接近于string2里不同字母的数量,即小于或等于string2里不同字母的数量的同时且最大。
(2)这个有效子串是满足条件(1)里的所有子串(如果有多个的话)里字典
序Q最大的一个。
如果没有找到合适条件的子串的话,请输出"Not Found"
示例:
输入字符串string1为"thisisanewday111 forme",
输入字符串string2为"good"。
string1里有效子串和加扰子串分割后可表示为:"thisis"+"a"+"n"+"e"+"w"+"da"+"y"+"111f"+"orm"+"e",
去除加扰子串("a"、"e"、"da"、"111f"、"e")后的有效子串候选为("thisis'”,"n","w","y","orm")。
输入字符串string2里不同字母的数量为3('g、'o'、'd),从有效子串候选里可以找出“orm"满足要求,
其不同字母的数量为3,最接近于string2不同字母的数量。
输入描述:
input string1 input string2
说明:输入为两个字符串,第1行是题目里的string1(被加扰的字符串),第2行是题目里的string2(参考字符串)
输出描述:
output string
说明:输出为一个字符串(有效字符串)
补充说明:
输入字符串string1的长度在1~100000之间,string2的长度在1~500之间
示例1
输入:
123admyffc79pt ssyy
输出:
pt
说明:
将输入字符串1里的加扰子串"123ad"、"c79"去除后得到有效子串序列:"my"、"pt",
其中"my"里不同字母的数量为2(有'm和'y两个不同字母),"pt"里不同字母的数量为2(有和't两个不同字母)同时字典序最大。
示例2
输入:
123admyffc79ptaagghi2222smeersst88mnrt ssyyfgh
输出:
mnrt
说明:
将输入字符串1里的加扰子串"123ad"、fc79"、"aa"、"2222""ee"、"88"去除后得到有效子串序列:"my"、"pt"、"gghi"、"sm"、"rsst"、"mnrt";
输入字符串2里不同字母的数量为5(有s、y、f、g、h'5个不同字母)。
可得到最终输出结果为"mnt",其不同字母的数量(为4)最接近于"ssyyfgh"里不同字母的数量,其他有效子串不同字母的数量都小于"mnrt"。
示例3
输入:
abcmnq rt
输出:
Not Found
说明:
将输入字符串1里的加扰子串"abc"去除后得到有效子串序列:"mnq";输入字符串2里不同字母的数量为2(有'、t两个不同的字母)。
可得到最终的输出结果为"Not Found",没有符合要求的有效子串,因有效子串的里不同字母的数量(为3),大于输入字符串2里的不同字母的数量
解题思路:
根据题意:
string1的子串要求:1、只包含字母g~z
2、且子中不同字母的数量小于等于string2中的不同字母数量
求字符串中不同字母数量可以使用set,set可以去重,set的长度则为不同字母的数量。
*/
public class Main21 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] split = sc.nextLine().split(" ");
String string1 = split[0];
String string2 = split[1];
ArrayList<String> result = new ArrayList<>();
String temp = "";
int len2 = diffCharLenth(string2);
int max = 0;
for (int i = 0; i < string1.length(); i++) {
char c = string1.charAt(i);
//f-z为有效字符
if (c > 'f' && c < 'z') {
temp += c;
//处理最后一个字符
if (i == string1.length() - 1) {
int len1 = diffCharLenth(temp);
if (len1 <= len2) {
//当前子串长度大于列表中的最大长度,则清空列表
if (len1 >= max) {
result.clear();
//最接近对比字符串长度
max = Math.max(len1, max);
}
result.add(temp);
}
}
} else {
if ("".equals(temp)) continue;
int len1 = diffCharLenth(temp);
//有效字符串不同字符个数要小于等于对比字符串
if (len1 <= len2) {
//当前子串长度大于列表中的最大长度,则清空列表
if (len1 >= max) {
result.clear();
//最接近对比字符串长度
max = Math.max(len1, max);
}
result.add(temp);
}
//tmp置为空
temp = "";
}
}
Collections.sort(result);
System.out.println(result.size() == 0 ? "Not Found" : result.get(result.size() - 1));
}
/**
*
* @param str 传入字符串
* @return 返回不同字符的个数
*/
public static int diffCharLenth(String str) {
HashSet<Character> set = new HashSet<>();
for (char c: str.toCharArray()) {
set.add(c);
}
return set.size();
}
}
华为OD机试:21 字符串解密
最新推荐文章于 2024-06-13 10:20:49 发布