目录
题目描述
输入描述
输出描述
用例
题目解析
算法源码
在一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码,
在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的为唯一的真正的密码,求唯一的真正的密码。
无
无
| 输入 | h he hel hell hello o ok n ni nin ninj ninja |
| 输出 | ninja |
| 说明 | 按要求,hello、ok、ninja都是潜在密码。 检查长度,hello、ninja是真正的密码。 检查字典序,ninja是唯一真正密码。 |
| 输入 | a b c d f |
| 输出 | f |
| 说明 | 按要求,a b c d f 都是潜在密码。 检查长度,a b c d f 是真正的密码。 检查字典序,f是唯一真正密码。 |
本题难点在于如果找出“潜在密码”,即找到一个字符串,它的所有前缀(比如hello字符串,的所有前缀包括:h,he,hel,hell,hello)都在第一行输入中。
这里,我们需要先将首字母相同的字符串缓存arr在一起,然后从最长的字符串开始判断:
先截取 str.substring(0,1) 左闭右开,即str的第一个字母,看是否存在于arr中,若不存在则验证下一个最长字符串,若存在,则继续截取str.substring(0, 2),即str的前两个字母,看是否存在于arr中,处理逻辑同上。
一直处理到,str.substring(0, str.length-1),如果还是存在于arr中的话,则str就是arr中最长的潜在密码。
同理,处理其他首字母相同的情况。最终比较出,长度最长,字典序最高的潜在密码作为真正的密码。
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});rl.on("line", (line) => {const arr = line.split(" ");console.log(getResult(arr));
});function getResult(arr) {// 统计前缀相同的字符串const prefixObj = arr.sort().reduce((p, c) => {const prefix = c[0];p[prefix] ? p[prefix].push(c) : (p[prefix] = [c]);return p;}, {});const ans = []; // ans用于缓存潜在密码for (let k in prefixObj) {const arr = prefixObj[k];const set = new Set(arr);while (arr.length) {const top = arr.pop();let i = 1;while (i < top.length && set.has(top.substring(0, i))) {i++;}if (i === top.length) {ans.push(top);break;}}}// 返回真正的密码return ans.sort((a, b) =>a.length !== b.length ? b.length - a.length : b > a ? 1 : -1)[0];
}