第四十五题
题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
function IsContinuous(numbers)
{
// write code here
let times=[]
for(let i=0;i<13;i++){
times[i]=0
}
if(numbers.length!=5){
return false
}
let max=-1
let min=14
for(let i=0;i<numbers.length;i++){
times[numbers[i]]++
if(numbers[i]==0){
continue
}
if(times[numbers[i]]>1){
return false
}
if(numbers[i]>max){
max=numbers[i]
}
if(numbers[i]<min){
min=numbers[i]
}
}
return max-min<5
}
该问题的思路是先定义一个数组times,里面储存牌面数字出现的次数,当有重复数字出现时,return false,大小王可以看成任何数字,且在数组里显示为0,则判断拿到的牌组最大差值是否小于5即可
第四十六题
题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
function LastRemaining_Solution(n, m)
{
// write code here
if(n===0){
return -1
}
if(n===1){
return 0
}else{
return (LastRemaining_Solution(n-1,m)+m )%n
}
}
第四十七题
题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
function Sum_Solution(n)
{
// write code here
let sum=0
plus(n)
return sum
function plus(num){
sum+=num
num>0&&plus(--num)
}
}
第四十八题
题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
function Add(num1, num2)
{
// write code here
let sum,carry
do{
sum=num1^num2
carry=(num1&num2)<<1
num1=sum
num2=carry
}while(num2!=0){
return num1
}
}
需要利用按位操作符来解决该问题
比如我们计算5+17=22这个结果,世界上,我们可以分为3个步骤计算,第一步各位数相加不进位,此时的结果是12(个位相加不进位是2,十位相加是1),所以结果是12; 第二步做进位,5+7有进位,进位值是10;第三步是把前两步计算结果加起来。12 + 10 = 22.
那么运用位运算二进制的数字也可以这么考虑,5是二进制的101,17是二进制的10001。试着把计算分为3步走,第一步各位相加不进位,得到的结果是10100;第二步是记下进位,根据这个例子进位计算结果是10;第三步是把前两步计算结果相加得到结果10110.转化为10进制刚好是22。 用二进制计算,第一步不考虑进位,即每一位相加 0+0=0,1+1=0,0+1=1,1+0=1。结果符合二进制数据的异或运算。第二步只考虑进位运算,0+0,0+1,1+0都不会进位,只有1+1才会进位,结果符合两个数的与运算结果然后向左移动一位。第三步,把前两步骤的结果相加,相加步骤仍然是重复前两步骤。直到不产生进位值。
第四十九题
题目描述
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入
+2147483647
1a33
输出
2147483647
0
function StrToInt(str)
{
// write code here
if(!str||str.length===0){
return 0
}
let reg=/^(\+?\-?)(\d+)$/
if(!str.match(reg)){
return 0
}
return parseInt(str)
}
第五十题
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
function duplicate(numbers, duplication)
{
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
if(!numbers||numbers.length===0){
return false
}
let len=numbers.length
for(let i=0;i<len;i++){
let curr=numbers[i]
if(numbers.indexOf(curr)!==i){
duplication[0]=curr
return true
}
}
return false
}
第五十一题
题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。
function multiply(array)
{
// write code here
if(!array||array.length===0){
return []
}
let result=[]
for(let i=0;i<array.length;i++){
let tempArr=array.filter((item,index)=>{
return index!==i
})
let temp=1
tempArr.map(item=>temp*=item)
result[i]=temp
}
return result
}
数组过滤
第五十二题
题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
//s, pattern都是字符串
function match(s, pattern)
{
// write code here
if(s===""&&pattern===""){
return true
}
if(!pattern||pattern.length===0){
return false
}
let reg=new RegExp('^'+pattern+'$')
return reg.test(s)
}
第五十三题
题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
//s字符串
function isNumeric(s)
{
// write code here
let reg=/^[+-]?(?:(\d+)(\.\d+)?|(\.\d+))([eE][+-]?\d+)?$/
return reg.test(s)
}
第五十四题
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
//Init module if you need
let map
function Init()
{
// write code here
map={}
}
//Insert one char from stringstream
function Insert(ch)
{
// write code here
if(!map[ch]){
map[ch]=1
}else{
map[ch]++
}
}
//return the first appearence once char in current stringstream
function FirstAppearingOnce()
{
// write code here
for(let ch in map){
if(map.hasOwnProperty(ch)&&map[ch]===1){
return ch
}
}
return '#'
}
利用map计数的思路
第五十五题
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function EntryNodeOfLoop(pHead)
{
// write code here
if(pHead==null||pHead.next==null){
return null
}
let fast=pHead
let slow=pHead
while(slow!==null&&fast.next!==null){
slow=slow.next
fast=fast.next.next
if(slow===fast) break
}
let p1=slow
let p2=pHead
while(p1!=p2){
p1=p1.next
p2=p2.next
}
return p1
}
这道题的思路大概如下:
我们设:
a=入口到相遇点的距离
x=起点到入口点的距离
c=环长
此时设置两个指针,fast,slow
每次前进一个节点的路径长度Sslow=x+a+mc
每次前进两个节点的路径长度Sfast=x+a+nc
2 Sslow = Sfast
2 * ( x + m*c + a ) = (x + n *c + a)
从而可以推导出:
x = (n - 2 * m )*c - a
= (n - 2 *m -1 )*c + c - a
起点到入口的距离等于相遇点开始,若干环长+环-入口到相遇点
此时再设置两个指针p1,p2
p1起点为pHead,p2起点为相遇点
这个两个指针相遇点为入口点