过了太久我已经不记得这个是啥玩意了,隐约觉得第二第三题方法都太笨了

这篇博客讨论了两个JavaScript编程挑战:1) 找到数列中最长的上升下降序列的数组下标,使用一次扫描实现;2) 给定查询组和被查询组,找到相同单词最多的句子,作者提到了使用哈希预处理的方法;3) 在给定条件组的情况下找出满足条件的数组下标,提出了可能使用树状数组进行优化。此外,作者分享了编程中的经验教训和一些在线编程提示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.找一个数列中的最长”上升下降“序列的数组下标
比如
8 //数列长度
1 3 1 2 5 4 3 9 //数列
0 1 2 3 4 5 6 7 //数列下标
那么下标就是
2 6

这个需要设参数来确保是上升还是下降序列,看代码吧。

var incredecre=function(array){
var incre;
var finalstart=-1,finalend=-1,maxlen=0;
var len=0,start=-1,end=-1;
if (array.length<3) {return false;}
else{
for (var i = 0; i < array.length-1; i++) {
    if(array[i]<array[i+1]) {
    if (incre!=true) {start=i;len=1;}    
    else{len++;}
    incre=true;
  }
  else {
    if(incre===true){
      len++;
      if(!array[i+2]||array[i+1]<=array[i+2]){
        len++;end=i+1;
        if(maxlen<len){maxlen=len;finalstart=start;finalend=end;}
      }
    }
    else if(incre===false){
      if(!array[i+2]||array[i+1]<=array[i+2]){
        len+=2;end=i+1;
        if(maxlen<len){maxlen=len;finalstart=start;finalend=end;}
      }
      else {len++;}
    }
    incre=false;}
    console.log("start "+start+" end "+end+" len "+len+"incre "+incre);
}
console.log("finalstart "+finalstart+"finalend "+finalend+"maxlen "+maxlen);
return true;
} //end of else
}; //end of function incredecre

只扫一遍。

为了表示效果,console台输出了整个过程,比如:这里写图片描述

测试代码如下,本来还想小数点保留1位的,但发现1位小数点我就开始晕了(啊,为我的脑容量默哀。。。。)所以都搞成了整数。

var createRandomList=function(){ 
var list=[];
for (var i = 0; i < 10; i++) {
  var item=10*Math.random();
  list.push(+item.toFixed(0));}
  return list;
};

如果上面那种不是非常好理解的话,还可以用找极大点的方法,先扫到某个数arrary[i]>array[i+1]&&array[i]>array[i-1],然后对这个极大点向左向右扫,找到start和end。但在坏的情况下,要扫2*array.length次。效率不高。

2.给出包括m个句子的查询组(B),和n个句子的被查询组(A)。对查询组中的每个句子,找出被查询组中相同单词数最多的句子。

更新:还是用hash做预处理。

下面是原来的暴力解法

var eqcount_sentence=function(sen1array,sen2array){
    var eqnum=0;
    for(var i=0;i<sen1array.length;i++){
        for(var j=0;j<sen2array.length;j++){
            if(sen1array[i]===sen2array[j])
            {eqnum++;}
        }
    }
    return eqnum;
};

var nm="3 2";
var n,m;
n=nm.split(" ")[0];
m=nm.split(" ")[1];
var l=[],w=[],senl=[],sen=[];
var eqnum=[];maxeq=[];
sen[0]="i love you";
sen[1]="i love i love";
sen[2]="you hate you";
for(var i=0;i<n;i++){
    // sen[i]=read_line();
    senl[i]=sen[i].split(" ");
}
var query=[],qul=[],qlen=[],x=[];
query[0]="love i";
query[1]="you hate love";
for(i=0;i<m;i++){
    //query[i]=read_line();
    qul[i]=query[i].split(" ");
    eqnum[i]=[];maxeq[i]=-1;x[i]=-1;
    for(var k=0;k<n;k++){
        eqnum[i][k]=eqcount_sentence(qul[i],senl[k]); //eqnum[i]是第i行查询行对第k行被查询行的相同单词数
        if(maxeq[i]<eqnum[i][k]){
        maxeq[i]=eqnum[i][k];   
        x[i]=k;     
        }
    }
console.log(sen[x[i]]);
}

关于怎么算两个句子中的相同单词数,我是这么理解的:
这里写图片描述

这是最笨的暴力求解法,有人说用hash,我想到了kmp,但都觉得不是很实用。而且kmp想来想去无从下手。毕竟是真实的单词和句子。扫n, 扫m感觉都是必须的。能优化的应该是那个两个句子统计相同单词数的地方吧。
一个是两个单词比较的部分,代码里直接是===,但如果将单词看作字符串的话,可以先比个长度再依次比,或者跳跃比(类似希尔排序),因为单词的前后缀可能相同,这样打乱顺序比较概率上说如果有不同可以尽快发现。
一个是用自带的indexOf来做,相信js 自带的功能跑的要快。。。

var eqcount_sentence=function(sen1array,sen2array){
    var eqnum=0;
    for(var i=0;i<sen1array.length;i++){ //sen1array当做查询组
        var item=sen1array[i];
        var y=sen2array.indexOf(item);
            if(y!=-1){
                y=sen2array.indexOf(item,y+1);
                eqnum++;
            }
    }
    return eqnum;
};

还有个好处就是不用把被查询组的句子转成单词数组了,可以少扫一遍段落。这个还是挺好的。
这样做的注意事项是,两个参数的位置不能颠倒,不然结果减半。
这里写图片描述

senl是啥见上面的代码,自定义的。没了编译器,js读入数据要自己搞,这个真愁人。赶紧学nodejs!

再有就是先学习查询句的结构了,比如看看有没有相同的单词,可以直接砍掉,然后对那个单词eq*2。这个如果查询句长的话也许有点用,但现实生活的话,一个句子中某个单词多次出现,应该是歌词吧。。。

3.给出A,B两个数组和条件组,每个条件组x,y两个数,找出满足Ai>=x&&Bi>=y的i的个数。隐含条件是A,B两个数组等长??

var counti=function(arr,brr,condition){
var num=0;
for(var i=0;i<arr.length;i++){
    if(arr[i]>=condition[0]&&brr[i]>=condition[1]){
      num++;
    }
}
return num;
};
var A="3 2 4";
var B="6 5 8";
var a=A.split(" ");
var b=B.split(" ");
condition1=[1,1];
condition2=[4,8];
counti(a,b,condition1);
counti(a,b,condition2);

结果是
3
1

不是很理解,感觉这也太简单了吧?不知道是不是理解错了题意,明天应该就有官方答案出来了。到时看看。
更新,啊啊,就知道没那么简单,肯定是要靠通过率卡优化的。回去整树状数组。

考试的时候出了点问题,一个都没通过。啊。等于编程空白了。
上午写了一道,把电脑锁在柜子里,晚上准备继续,发现柜子打不开了。。。守到8点多终于来了人把电脑解救出来。差一点电脑就要在柜子里过清明了。。。
登录网易官网想查询一下信息,说没有投递记录,换了另一个邮箱登录,说没有这个用户。可是笔试通知还是发到这个邮箱的。。。真是醉了。我可能投了个假简历。不过反正笔试的也不好,就随意吧。
去登录爱奇艺的招聘,发现居然注册过手机号,还是个男性头像,还是个非主流名字,完全没有印象。啊,我究竟有没有脑子?这是个老问题了。

最后是javascript的在线编程tips:

  • for循环不要用let 不要用es6
  • 如果让外部调试,一上来先写封装好的函数和console.log输出,不要直接print||read_line() 除非有把握一次成功。
  • 如果不让调试,唉,那就听天由命吧。
  • 赶紧瞅吧瞅吧node!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值