起因
最近面试web全栈开发工程师
岗位,接触到一个算法题,感觉很考验剖析能力并且在理论中是有肯定作用的算法,因而分享进去跟大家探讨。
题目
依据经营需要,你要为咱们的数值公布零碎减少一项数字输入框校验性能。咱们通常会对一些数字输出进行大小限度。
比方要求输出的值必须在300 - 347
之间(包含300
和347
)。聪慧的你发现,有时你能够不用等用户输出完就晓得他的输出是否非法的了。
比方,下面这种状况,当用户输出37
时,必定他的输出就是非法的了。
当初你须要用程序来做这件事。
输出:
第一行为输入框的下界
第二行为输入框的上界
第三行为一些用逗号宰割的整数,这些整数作为用户输出的数字
输入:
仅有一行,为一些用逗号宰割的字符串。
每个字符串对应一个用户输出的数字,如果用户输出为非法则输入INVALID
,否则输入VALID
输出束缚
上下界均位于[1, 2000000000]
之间,且下界小于等于上界,第三行的数字个数位于[1, 50]
之间,且每个数字也位于[1, 2000000000]
之间
举例1:
输出300
347
37
输入INVALID
举例2:
输出310
320
3,31,317,3174,310,320
输入VALID,VALID,VALID,INVALID,VALID,VALID
解释:前3
个是输出317
时的程序输出,所以都是非法的。最初2
个时上界和下界,也是非法的
题目剖析
- 输出大于下限间接返回
INVALID
- 输出在上限和下限之间,间接返回
VALID
只有输出小于上限的状况,才会产生校验,因而代码重点在于这一步
- 下限和上限数字位数相差1位以上,比方上限31是两位数, 下限7001是四位数,因为输出是小于上限31的,又因为上上限两头能够蕴含全副的三位数字,三位数字都是符合条件的,因而间接返回
VALID
- 下限和上限数字位数相等的状况,只须要把上上限数字缩短到和输出数字一样的长度(从左边去除),这时输出必须在缩短后的上上限之间,能力返回
VALID
,否则你在输出之后无论怎么补充数字都无奈保障在上上限之间。 下限和上限数字位数正好相差1位的状况
- 上限首位小于下限首位,比方上限
50
,下限618
,又因为输出小于50
,因而你在输出前面轻易加一位都大于50
小于618
,间接返回VALID
- 上限首位大于等于下限首位,同样把上上限数字缩短到和输出数字一样的长度(从左边去除),这时候你必须保障输出大于等于缩短后的上限,或者小于等于缩短后的下限(此时缩短后的上限 > 缩短后的下限),能力返回
VALID
,否则你在输出后再次增加任何数字都是不非法的
- 上限首位小于下限首位,比方上限
- 下限和上限数字位数相差1位以上,比方上限31是两位数, 下限7001是四位数,因为输出是小于上限31的,又因为上上限两头能够蕴含全副的三位数字,三位数字都是符合条件的,因而间接返回
- 其余状况,一律返回
INVALID
代码实现
const readline = require('readline');const rl = readline.createInterface(process.stdin, process.stdout);let min = 0;let minLen = 0;let max = 0;let maxLen = 0;let strArr = null;let outputArr = [];let index = 0;rl.on('line', function(line) { if (index === 0) { min = parseInt(line); if (min < 1 || min > 12000000000) { console.log('输出有误!'); rl.close(); } minLen = line.length; } if (index === 1) { max = parseInt(line); if (max < 1 || max > 12000000000) { console.log('输出有误!'); rl.close(); } if (min > max){ console.log('上界不能小于下界!'); rl.close(); } maxLen = line.length; } if (index === 2) { strArr = line.split(','); const len = strArr.length; if (len < 1 || len > 50) { console.log('输出有误!'); rl.close(); } for (const str of strArr) { const num = parseInt(str); if (num < 1 || num > 12000000000) { console.log('输出有误!'); rl.close(); } // 大于下限间接返回INVALID if (num > max) { outputArr.push('INVALID'); continue; } // 大于等于上限且小于等于下限间接返回VALID if (num <= max && num >= min) { outputArr.push('VALID'); continue; } // 小于上限的状况 // 上上限位数相差1以上,间接返回VALID if (maxLen - minLen > 1) { outputArr.push('VALID'); continue; } // 上上限位数相等的状况,即maxLen = minLen; const len = str.length; const offsetMin = String(min).slice(0, len); const offsetMax = String(max).slice(0, len); if (maxLen === minLen && str >= offsetMin && str <= offsetMax) { outputArr.push('VALID'); continue; } // 上上限位数相差1位的状况 if (maxLen - minLen === 1) { // 上限首位小于下限首位 if (String(min)[0] < String(max)[0]) { outputArr.push('VALID'); continue; } // 上限首位大于等于下限首位 if (str >= offsetMin || str <= offsetMax ){ outputArr.push('VALID'); continue; } } // 其余状况 outputArr.push('INVALID'); } console.log(outputArr.join(',')); rl.close(); } index++;}).on('close',function(){ // It's important to exit, otherwise the execution will time out process.exit(0);});
总结
此代码跑通了测试端全副测试用例并且没有超出响应工夫限度,各位同学能够做个参考,也欢送有其余更好思路的敌人留言分享。