前端程序員面試分類真題14_第1頁
前端程序員面試分類真題14_第2頁
前端程序員面試分類真題14_第3頁
前端程序員面試分類真題14_第4頁
前端程序員面試分類真題14_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

前端程序員面試分類真題14簡答題1.

下面是兩個數(shù)組,求出這兩個數(shù)組的交集。

vararr1=[1,2,3,4,5];

vararr2=[4,1,5,8,9,6,7(江南博哥)];正確答案:數(shù)組的交集是指都包含的元素,可以通過Array對象的兩個方法filter()和indexOf()找到兩個數(shù)組中的交集。filter()方法接收2個參數(shù),第一個參數(shù)是一個回調(diào)函數(shù),第二個參數(shù)是一個可選值,表示執(zhí)行回調(diào)函數(shù)時使用的this對象(即調(diào)用上下文)。它能過濾掉回調(diào)函數(shù)結(jié)果為假值的元素,然后把剩余的元素組成一個新數(shù)組。具體的實現(xiàn)思路是用filter()方法遍歷第一個數(shù)組,然后用第二個數(shù)組是否包含當前元素作為過濾條件,如下所示。

functionintersection(arr1,arr2){

returnarr1.filter(function(value,index){

returnarr2.indexOf(value)>=0;

});

}[考點]數(shù)組

2.

數(shù)字1~1000放在含有1001個元素的數(shù)組中,其中只有唯一的一個元素值重復,其他數(shù)字均只出現(xiàn)一次。設(shè)計一個算法,將重復元素找出來,要求每個數(shù)組元素只能訪問一次。正確答案:根據(jù)異或運算的性質(zhì)可知,當相同元素異或時,其運算結(jié)果為0;當相異元素異或時,其運算結(jié)果為非0;任何數(shù)與數(shù)字0進行異或運算,其運算結(jié)果為該數(shù)。本題中,正好可以使用到此方法,即將數(shù)組里的元素逐一進行異或運算,得到的值再與數(shù)字1,2,3,…,N進行異或運算,得到的最終結(jié)果即為所求的重復元素。

以數(shù)組[1,3,4,2,5,3]為例。(1^3^4^2^5^3)^(1^2^3^4^5)=(1^l)^(2^2)^(3^3^3)^(4^4)^(5^5)=0^0^3^0^0=3。示例代碼如下所示。

functionfindDup(array){

varlen=array.length,

result=0;

if(!array||len<1)

return-1;

for(vari=0;i<len;i++)

result^=array[i];

for(i=1;i<len;i++)

result^=i;

returnresult;

}[考點]數(shù)組

3.

給定數(shù)組[a1,a2,a3,...,an],要求找出數(shù)組中的最大值和最小值。假設(shè)數(shù)組中的值各不相同。正確答案:可以利用分治法找出數(shù)組中的最大值和最小值。分治法就是將一個規(guī)模為n的、難以直接解決的大問題,分割為k個規(guī)模較小的子問題,采取各個擊破、分而治之的策略得到各個子問題的解,然后將各個子問題的解進行合并,從而得到原問題解的一種方法。

本題中,當采用分治法求解時,就是將數(shù)組兩兩一對分組,如果數(shù)組元素個數(shù)為奇數(shù),就把最后一個元素單獨分為一組,再分別對每一組中相鄰的兩個元數(shù)進行比較,把二者中值小的數(shù)放在數(shù)組的左邊,值大的數(shù)放在數(shù)組右邊,只需要比較n/2次就可以將數(shù)組分組完成。然后可以得出結(jié)論:最小值一定在每一組的左邊部分,最大值一定在每一組的右邊部分,接著只需要在每一組的左邊部分找最小值,右邊部分找最大值,查找分別需要比較n/2-1次和n/2-1次;因此,總共比較的次數(shù)大約為n/2×3-2次。實現(xiàn)代碼如下所示。

functiongetMaxMin(arr){

varlen=arr.length;

if(!arr||len<1){

return;

}

varmax,min,tmp;

//兩兩分組,把較小的數(shù)放到左半部分,較大的放到右半部分

for(vari=0;i<len;i++){

if(arr[i+1]!==undefined&&arr[i]>arr[i+1]){

tmp=arr[i];

arr[i]=arr[i+1];

arr[i+1]=tmp;

}

}

//在各個分組的左半部分找最小值

min=arr[0];

for(i=2;i<len;i+=2){

if(arr[i]<min){

min=arr[i];

}

}

//在各個分組的右半部分找最大值

max=arr[l];

for(i=3;i<len;i+=2){

if(arr[i]>max){

max=arr[i];

}

}

//如果數(shù)組中元素個數(shù)是奇數(shù),最后一個元素被分為一組,需要特殊處理

if(len%2=1){

if(max<arr[len-1])

max=arr[len-1];

if(min>arr[len-1])

min=arr[len-1];

}

console.log("最大值:",max);

console.log("最小值:",min);

}[考點]數(shù)組

4.

把一個有序數(shù)組最開始的若干個元素搬到數(shù)組的末尾,稱之為數(shù)組的旋轉(zhuǎn)。輸入一個排好序的數(shù)組的一個旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。例如數(shù)組[3,4,5,1,2]為數(shù)組[1,2,3,4,5]的一個旋轉(zhuǎn),該數(shù)組的最小值為1。正確答案:通過數(shù)組的特性可以發(fā)現(xiàn),數(shù)組元素首先是遞增的,然后突然下降到最小值,再遞增。雖然如此,但是還有下面三種特殊情況需要注意:

(1)數(shù)組本身是沒有發(fā)生過旋轉(zhuǎn)的,還是一個有序的數(shù)組,例如序列[1,2,3,4,5,6]。

(2)數(shù)組中元素值全部相等,例如序列[1,1,1,1,1,1]。

(3)數(shù)組中元素值大部分都相等,例如序列[1,0,1,1,1,1]。

通過旋轉(zhuǎn)數(shù)組的定義可知,經(jīng)過旋轉(zhuǎn)之后的數(shù)組實際上可以劃分為兩個有序的子數(shù)組,前面子數(shù)組的元素值都大于或者等于后面子數(shù)組的元素值。可以根據(jù)數(shù)組元素的這個特點,采用二分查找的思想不斷縮小查找范圍,最終找出問題的解決方案,具體實現(xiàn)思路如下。

按照二分查找的思想,給定數(shù)組arr,首先定義兩個變量low和high,分別表示數(shù)組的第一個元素和最后一個元素的下標。按照題目中對旋轉(zhuǎn)規(guī)則的定義,第一個元素應該是大于或者等于最后一個元素的(當旋轉(zhuǎn)個數(shù)為0,即沒有旋轉(zhuǎn)的時候,要單獨處理,直接返回數(shù)組第一個元素)。接著遍歷數(shù)組中間的元素arr[mid],其中mid=(high+low)/2。

(1)如果arr[mid]<arr[mid-1],那么arr[mid]一定是最小值。

(2)如果arr[mid+1]<arr[mid],那么arr[mid+1]一定是最小值。

(3)如果arr[high]>arr[mid],那么最小值一定在數(shù)組左半部分。

(4)如果arr[mid]>arr[low],那么最小值一定在數(shù)組右半部分。

(5)如果arr[low]==arr[mid]且arr[high]=arr[mid],那么此時無法區(qū)分最小值是在數(shù)組的左半部分還是右半部分(例如[2,2,2,2,1,2]或[2,1,2,2,2,2,2])。在這種情況下,只能分別在數(shù)組的左右兩部分找最小值minL與minR,最后求出minL與minR的最小值。

示例代碼如下所示。

functionminNum(x,y){

return(x<y)?x:y;

}

functionfindMin(arr,low,high){

//如果旋轉(zhuǎn)個數(shù)為0(即沒有旋轉(zhuǎn)),則單獨處理,直接返回數(shù)組頭元素

if(high<low)

returnarr[0];

//只剩下—個元素一定是最小值

if(high==low)

returnarr[low];

varmid=low+((high-low)>>1);

//采用這種寫法防止溢出

if(arr[mid]<arr[mid-1])

//判斷arr[mid]是否為最小值

returnarr[midl;

if(arr[mid+1]<arr[mid])

//判斷arr[mid+1]是否為最小值

returnarr[mid+1];

if(arr[high]>arr[mid])

//最小值一定在數(shù)組左半部分

returnfindMin(arr,Iow,mid-1);

if(arr[mid]>arr[low])

//最小值一定在數(shù)組右半部分

returnfindMin(arr,mid+1,high);

//這種情況下無法確定最小值所在的位置,需要在左右兩部分分別進行查找

returnminNum(findMin(arr,low,mid-1),findMin(arr,mid+1,high));

}[考點]數(shù)組

5.

給定一個由n-1個整數(shù)組成的未排序的數(shù)組,其元素是1~n中的不同整數(shù)。請寫出一個尋找數(shù)組中缺失整數(shù)的線性時間算法。正確答案:首先分析一下數(shù)學性質(zhì)。假設(shè)缺失的數(shù)字是X,那么這n-1個數(shù)一定是1~n之間除了X以外的所有數(shù)。試想一下,1~n一共n個數(shù)的和是可以求出來的,數(shù)組中的元素和也是可以求出來的,二者相減,其值是不是就是缺失的數(shù)字X呢?

為了更好地說明上述方法,舉一個簡單的例子加以說明。假設(shè)數(shù)組為[2,1,4,5],一共4個元素,n的值為5,要想找出這個缺失的數(shù)字,可以首先對1~5五個數(shù)字求和,求和結(jié)果為15(1+2+3+4+5=15),而數(shù)組元素的和為array[0]+array[1]+array[2]+array[3]=2+1+4+5=12,所以,缺失的數(shù)字為15-12=3。

通過上面的例子可以很容易形成以下具體思路:定義兩個數(shù)suma與sumb,其中suma表示的是這n-1個數(shù)的和,sumb表示的是這n個數(shù)的和,很顯然,缺失數(shù)字的值即為sumb-suma的值。示例代碼如下所示。

functiongetNum(arr){

varlen=arr.length;

if(!arr||len<=0){

return-1;

}

varsuma=0,

sumb=0;

for(vari=0;i<len;i++){

suma+=arr[i];

//數(shù)組元素相加

sumb+=i+1;

//1~n-1相加

}

//與第n個數(shù)相加

sumb+=len+1;

returnsumb-suma;

}[考點]數(shù)組

6.

給定一個數(shù)組,數(shù)組中含有重復元素,給定兩個數(shù)字num1和num2,求這兩個數(shù)字在數(shù)組中出現(xiàn)位置的最小距離。正確答案:可以采用動態(tài)規(guī)劃的方法把每次遍歷的結(jié)果都記錄下來從而減少遍歷次數(shù)。具體實現(xiàn)思路如下。當遍歷數(shù)組時,會遇到以下兩種情況:

(1)當遇到num1時,記錄下num1對應的數(shù)組下標lastPos1,通過求lastPos1與上次遍歷到的num2下標lastPos2的差可以求出最近一次遍歷到的num1與num2的距離。

(2)當遇到num2時,同樣記錄下它所對應的數(shù)組下標lastPos2,然后通過求lastPos2與上次遍歷到的num1下標lastPos1,求出最近一次遍歷到的num1與num2的距離。

假設(shè)給定數(shù)組為:[4,5,6,4,7,4,6,4,7,8,5,6,4,3,10,8],num1=4,num2=8。根據(jù)以上方法,執(zhí)行過程如下:

(1)在遍歷的時候首先會遍歷到4,下標為lastPos1=0,由于此時還沒有遍歷到num2,因此,沒必要計算num1與num2的最小距離。

(2)然后往下遍歷,又遍歷到num1=4,更新lastPos1=3。

(3)繼續(xù)往下遍歷,又遍歷到num1=4,更新lastPos1=7。

(4)接著往下遍歷,又遍歷到num2=8,更新lastPos2=9;此時,由于前面已經(jīng)遍歷到num1,就可以求出當前num1與num2的最小距離為|lastPos2-lastPos1|=2。

(5)再往下遍歷,又遍歷到num2=8,更新lastPos2=15;此時,由于前面已經(jīng)遍歷到num1,就可以求出當前num1與num2的最小距離為|lastPos2-lastPos1|=8;由于8>2,所以,num1與num2的最小距離為2。

實現(xiàn)代碼如下所示。

functionminNum(x,y){

return(x<y)?x:y;

}

functionminDistance(arr,num1,num2){

varlen=arr.length;

if(!arr||len<=0){

return;

}

varlastPos1=-1,

//上次遍歷到num1的位置

lastPos2=-1,

//上次遍歷到num2的位置

minDis=Math.max.apply(null,arr);

//num1與num2的最小距離

for(vari=0;i<len;++i){

if(arr[i]=num1){

lastPos1=i;

if(lastPos2>=0)

minDis=minNum(minDis,lastPos1-lastPos2);

}

if(arr[i]==num2){

lastPos2=i;

if(lastPos1>=0)

minDis=minNum(minDis,lastPos2-lastPos1);

}

}

returnminDis;

}[考點]數(shù)組

7.

有一個有n個元素的數(shù)組,這n個元素既可以是正數(shù)也可以是負數(shù),數(shù)組中連續(xù)的一個或多個元素可以組成一個連續(xù)的子數(shù)組,一個數(shù)組可能有多個這種連續(xù)的子數(shù)組,求子數(shù)組元素和的最大值。例如:對于數(shù)組[1,-2,4,8,-4,7,-1,-5]而言,其具有最大元素和的子數(shù)組為[4,8,-4,7],和為15。正確答案:由于Sum[i,j]=Sum[i,j-1]+arr[j],所以在計算Sum[i,j]的時候可以使用前面已計算出的Sum[i,j-1]而不需要重新計算。采用這種方法可以省去計算Sum[i,j-1]的時間,因此,可以提高程序的效率。實現(xiàn)代碼如下所示。

functionmaxSubArray(arr){

varmaxSum=Math.min.apply(null,arr),

len=arr.length,

sum;

for(vari=0;i<len;i++){

sum=0;

for(varj=i;j<len;j++){

sum+=arr[j];

if(sum>maxSum){

maxSum=sum;

}

}

}

returnmaxSum;

}[考點]數(shù)組

8.

有一個升序排列的數(shù)組,數(shù)組中可能有正數(shù)、負數(shù)或0,求數(shù)組中絕對值最小的數(shù)。例如數(shù)組[-10,-5,-2,7,15,50],該數(shù)組中絕對值最小的數(shù)是-2。正確答案:在求絕對值最小的數(shù)時可以分為如下三種情況:

(1)如果數(shù)組第一個元素為非負數(shù),那么絕對值最小的數(shù)肯定為數(shù)組第一個元素。

(2)如果數(shù)組最后一個元素的值為負數(shù),那么絕對值最小的數(shù)肯定是數(shù)組最后一個元素。

(3)如果數(shù)組中既有正數(shù)又有負數(shù),首先找到正數(shù)與負數(shù)的分界點,如果分界點恰好為0,那么0就是絕對值最小的數(shù)。否則通過比較分界點左右的正數(shù)與負數(shù)的絕對值來確定最小的數(shù)。

那么如何來查找正數(shù)與負數(shù)的分界點呢?最簡單的方法仍然是順序遍歷數(shù)組,找出第一個非負數(shù)(前提是數(shù)組中既有正數(shù)又有負數(shù)),接著通過比較分界點左右兩個數(shù)的值來找出絕對值最小的數(shù)。這種方法在最壞的情況下時間復雜度為O(N)。下面主要介紹采用二分法來查找正數(shù)與負數(shù)分界點的方法。主要思路如下。取數(shù)組中間位置的值a[mid],并將它與0值比較,比較結(jié)果分為以下3種情況:

(1)如果a[mid]==0,那么這個數(shù)就是絕對值最小的數(shù)。

(2)如果a[mid]>0,a[mid-1]<0,那么就找到了分界點,通過比較a[mid]與a[mid-1]的絕對值就可以找到數(shù)組中絕對值最小的數(shù);如果a[mid-1]=0,那么a[mid-1]就是要找的數(shù);否則接著在數(shù)組的左半部分查找。

(3)如果a[mid]<0,a[mid+1]>0,那么通過比較a[mid]與a[mid+1]的絕對值即可;如果a[mid+1]==0,那么a[mid+1]就是要查找的數(shù);否則接著在數(shù)組的右半部分繼續(xù)查找。

實現(xiàn)代碼如下所示。

functionfindMin(arr){

varlen=arr.length;

if(!arr||len<=0){

return;

}

if(arr[0]>=0)

//數(shù)組中沒有負數(shù)

returnarr[0];

if(arr[len-1]<=0)

//數(shù)組中沒有正數(shù)

returnarr[len-1];

varmid=0,

begin=0,

end=len-1,

absMin=0;

while(1){

//數(shù)組中既有正數(shù)又有負數(shù)

mid=begin+Math.floor((end-begin)/2);

if(arr[mid]==0){

//如果中間值等于0,那么就是絕對值最小的數(shù)

return0;

}

if(arr[mid]>0){

//如果中間值大于0,并且正負數(shù)的分界點在左側(cè)

if(arr[mid-1]==0)

return0;

if(arr[mid-1]>0)

end=mid-1;

//繼續(xù)在數(shù)組的左半部分查找

else

break;

//找到正負數(shù)的分界點

}else{

//如果中間值小于0,那么在數(shù)組右半部分查找

if(arr[mid+1]==0)

return0;

if(arr[mid+1]<0)

begin=mid+1;

//在數(shù)組右半部分繼續(xù)查找

else

break;

//找到正負數(shù)的分界點

}

}

//求出正負數(shù)分界點中絕對值最小的值

absMin=Math.abs(arr[mid])<Math.abs(arr[mid+1])?

arr[mid]:

arr[mid+1];

returnabsMin;

}[考點]數(shù)組

9.

把一個含有N個元素的數(shù)組循環(huán)右移K(K是正數(shù))位,要求時間復雜度為O(N),且只允許使用兩個附加變量。正確答案:把數(shù)組看成由兩段組成,記為XY。左旋轉(zhuǎn)相當于要把數(shù)組XY變成YX。先在數(shù)組上定義一種翻轉(zhuǎn)的操作,就是翻轉(zhuǎn)數(shù)組中數(shù)字的先后順序。X翻轉(zhuǎn)后記為XT,顯然有(XT)T=X。

先對X和Y兩段分別進行翻轉(zhuǎn)操作,這樣就能得到XTYT。接著再對XTYT進行翻轉(zhuǎn)操作,得到(XTYT)T=(YT)T(XT)T=YX,正好是期待的結(jié)果。

回到原來的題目。根據(jù)上述分析,要做的僅僅是把數(shù)組分成兩段,再定義一個翻轉(zhuǎn)子數(shù)組的函數(shù),按照前面的步驟翻轉(zhuǎn)3次就行了。時間復雜度和空間復雜度都合乎要求。

對于數(shù)組A=[1,2,3,4,5,6],如何實現(xiàn)對其循環(huán)右移2位的功能呢?首先將數(shù)組A分成兩個部分:A[0~n-k-1]和A[n-k~n-1],再將這兩個部分分別翻轉(zhuǎn),然后放在一起再翻轉(zhuǎn)(反序)。具體是這樣的:

(1)翻轉(zhuǎn)1234,123456--->432156。

(2)翻轉(zhuǎn)56,432156--->432165。

(3)翻轉(zhuǎn)432165,432165--->561234。

示例代碼如下所示。

functionreverse(arr,start,end){

vartemp;

while(start<end){

temp=arr[start];

arr[start]=arr[end];

arr[end]=temp;

start++;

end--;

}

}

functionrightShift(arr,k){

varlen=arr.length;

if(!arr||len<1){

return;

}

k%=len;

reverse(arr,0,len-k-1);

reverse(arr,len-k,len-1);

reverse(arr,0,len-1);

}[考點]數(shù)組

10.

坐標軸上從左到右的點依次為a[0],a[1],a[2],…,a[n-1],設(shè)一根木棒的長度為L,求L最多能覆蓋坐標軸的幾個點?正確答案:本題求滿足a[j]-a[i]≤L和a[j+1]-a[i]>L這兩個條件的j與i之間所覆蓋的點個數(shù)的最大值,即(j-i+1)最大值。這樣題目就簡單多了,方法也很簡單:直接從左至0右掃描,使用兩個索引i和j,i從位置0開始,j從位置1開始,如果a[j]-a[i]≤L,則執(zhí)行j++前進,并記錄中間經(jīng)過的點個數(shù);如果a[j]-a[i]>L,則執(zhí)行j--回退,覆蓋的點個數(shù)減1,回到剛好滿足條件的時候,將滿足條件的最大值與前面找出的最大值比較,記錄下當前的最大值;然后執(zhí)行i++、j++,直到求出最大的點個數(shù)。有兩點需要注意,如下所列:

(1)這里可能不存在i和j使得a[j]-a[i]剛好等于L的情況發(fā)生,所以,判斷條件不能為a[j]-a[i]==L。

(2)可能存在覆蓋點不同但覆蓋長度相同的情況發(fā)生,此時只選取第一次覆蓋的點。

實現(xiàn)代碼如下所示。

functionmaxCover(a,L){

varn=a.length,

count=2,

maxCount=1,

//覆蓋的最大點數(shù)

start,

//覆蓋坐標的起始位置

i=0,

j=1;

while(i<n&&j<n){

while((j<n)&&(a[j]-a[i]<=L)){

j++;

count++;

}

j--;

count--;

if(count>maxCount){

start=i;

maxCount=count;

}

i++;

j++;

}

varcover=a.slice(start,start+maxCount);

console.log("覆蓋的坐標點:",cover.join(""))

returnmaxCount;

}[考點]數(shù)組

11.

給定一個數(shù)組a[N],希望構(gòu)造一個新數(shù)組b[N],其中b[i]=a[0]×a[1]×...×a[N-1]/a[i]。在構(gòu)造數(shù)組的過程中,有如下幾點要求:

(a)不允許使用除法。

(b)要求O(l)空間復雜度和O(N)時間復雜度。

(c)除遍歷計數(shù)器與a[N]和b[N]外,不可以使用新的變量(包括棧臨時變量、堆空間和全局變量等)。

(d)請用程序?qū)崿F(xiàn)并簡單描述。正確答案:如果沒有時間復雜度與空間復雜度的要求,算法將非常簡單。首先遍歷一次數(shù)組a,計算數(shù)組a中所有元素的乘積,并保存到一個臨時變量tmp中,然后再遍歷一次數(shù)組a并給數(shù)組賦值:b[i]=tmp/a[i]。但是這種方法使用了一個臨時變量,不滿足題目的要求。下面介紹另外一種方法。

在計算b[i]的時候,只要將數(shù)組a中除了a[i]以外的所有值相乘即可。這種方法的主要思路為:首先遍歷一次數(shù)組a,在遍歷的過程中對數(shù)組b進行賦值,b[i]=a[i-1]×b[i-1],這樣經(jīng)過一次遍歷后,數(shù)組b的值為b[i]=a[0]×a[1]×...×a[i-1]。此時只需要將數(shù)組中的值b[i]再乘以a[i+1]×a[i+2]×...×a[N-1],實現(xiàn)方法為逆向遍歷數(shù)組a,把數(shù)組后半段值的乘積記錄到b[0]中,通過b[i]與b[0]的乘積就可以得到滿足題目要求的b[i]。具體而言,先執(zhí)行b[i]=b[i]×b[0](執(zhí)行的目的是保證在執(zhí)行下面一個計算的時候,b[0]中不包含與b[i]的乘積),接著記錄數(shù)組后半段的乘積到b[0]中,即b[0]=b[0]×a[i]。實現(xiàn)代碼如下所示。

functioncalculate(a,b,N){

b[0]=1;

for(vari=1;i<N;++i){

//正向計算乘積

b[i]=a[i-1]*b[i-1];

}

b[0]=a[N-1];

for(i=N-2;i>=1;--1){

//逆向計算乘積

b[i]*=b[0];

b[0]*=a[i];

}

}

varN=10,

a=[1,2,3,4,5,6,7,8,9,10],

b=[];

calculate(a,b,N);

console.log(b.join(""));

程序的運行結(jié)果為:

362880018144001209600907200725760604800518400453600403200362880[考點]數(shù)組

12.

給定以非遞減順序排序的三個數(shù)組,找出這三個數(shù)組中的所有公共元素。例如,給出下面三個數(shù)組:ar1=[2,5,12,20,45,85],ar2=[16,19,20,85,200],ar3=[3,4,15,20,39,72,85,190]。那么這三個數(shù)組的公共元素為{20,85}。正確答案:最容易想到的方法是首先找出兩個數(shù)組的交集,然后再把這個交集存儲在一個臨時數(shù)組中,最后再找出這個臨時數(shù)組與第三個數(shù)組的交集。這個算法的時間復雜度為O(N1+N2+N3),其中N1、N2和N3分別為三個數(shù)組的長度。這種方法不僅需要額外的存儲空間,而且還需要額外的兩次循環(huán)遍歷。下面介紹另外一種只需要一次循環(huán)遍歷、而且不需要額外存儲空間的方法,主要思路如下。

假設(shè)當前遍歷的三個數(shù)組元素分別為ar1[i]、ar2[j]和ar3[k],則存在以下幾種可能性:

(1)如果ar1[i]、ar2[j]和ar3[k]相等,那么說明當前遍歷的元素是三個數(shù)組的公有元素,可以直接打印出來,然后通過執(zhí)行i++,j++,k++,使三個數(shù)組同時向后移動,此時繼續(xù)遍歷各數(shù)組后面的元素。

(2)如果ar1[i]<ar2[j],則執(zhí)行i++來繼續(xù)遍歷ar1后面的元素,因為ar1[i]不可能是三個數(shù)組公有的元素。

(3)如果ar2[j]<ar3[k],同理可以通過j++來繼續(xù)遍歷ar2后面的元素。

(4)如果前面的條件都不滿足,說明ar1[i]>ar2[j]且ar2[j]>ar3[k],此時可以通過k++來繼續(xù)遍歷ar3后面的元素。

實現(xiàn)代碼如下所示。

functionfindCommon(ar1,ar2,ar3){

vari=0,j=0,k=0,

n1=ar1.length,

n2=ar2.length,

n3=ar3.length,

share="";

//遍歷三個數(shù)組

while(i<n1&&j<n2&&k<n3){

if(arl[i]==ar2[j]&&ar2[j]==ar3[k]){

//找到公有元素就保存

share+=ar1[i]+"";

i++;

j++;

k++;

}

elseif(ar1[i]<ar2[j])

//ar1[i]不可能是共有的元素

i++;

elseif(ar2[j]<ar3[k])

//ar2[j]不可能是共有的元素

j++;

else

//ar3[k]不可能是共有的元素

k++;

}

console.log(share);

}[考點]數(shù)組

13.

函數(shù)聲明和函數(shù)表達式有哪些區(qū)別?正確答案:函數(shù)通常有2種創(chuàng)建方式:函數(shù)聲明和函數(shù)表達式。它們的區(qū)別如下所列:

(1)函數(shù)聲明必須包含名稱,而函數(shù)表達式可省略名稱。

(2)函數(shù)聲明有位置限制,不能出現(xiàn)在條件語句、循環(huán)語句或其他語句中,而函數(shù)表達式?jīng)]有位置限制,可以出現(xiàn)在語句中實現(xiàn)動態(tài)編程。

(3)函數(shù)聲明會先于函數(shù)表達式被提升至作用域的頂部,因此用函數(shù)聲明創(chuàng)建的函數(shù)可以在聲明之前被調(diào)用,而函數(shù)表達式必須在表達式之后才能被調(diào)用。[考點]函數(shù)

14.

用遞歸實現(xiàn)一個簡單的函數(shù),返回一個布爾值,檢測某個字符串是否是回文,例如“aabaa”返回true,而“aabcc”返回false。正確答案:當函數(shù)反復調(diào)用自身時,就執(zhí)行了遞歸(recursion)操作。如果把一個字符串反轉(zhuǎn),能和原字符串相等,那么這就是一個回文字符串。下面代碼就是實現(xiàn)回文驗證功能的函數(shù),它有兩個結(jié)束遞歸的出口,如果不滿足退出的條件,那么每次都會去除首尾字符再執(zhí)行遞歸。

functionpalindrome(str){

if(str.length<=1)

returntrue;

//首字符和末字符做匹配

if(str[0]!=str[str.length-1])

returnfalse;

//將去除首尾字符的字符串傳入函數(shù)自身中

returnpalindrome(str.substr(1,str.length-2));

}[考點]函數(shù)

15.

Function構(gòu)造器有哪些功能?正確答案:利用Function構(gòu)造器能創(chuàng)建函數(shù),這是第三種創(chuàng)建函數(shù)的方式。構(gòu)造器通過動態(tài)編譯字符串代碼來實現(xiàn)函數(shù)的創(chuàng)建,其實現(xiàn)方式和使用全局函數(shù)eval()類似。構(gòu)造函數(shù)Function()能接收任意多個實參(在調(diào)用函數(shù)時傳入的參數(shù)),最后一個參數(shù)是新函數(shù)的函數(shù)體,其他都是新函數(shù)的形參(在函數(shù)中定義的參數(shù)),下面代碼演示了它的用法。

varfunc=newFunction("a","b","returna+b;");

//相當于下面的函數(shù)表達式

varfunc=function(a,b){

returna+b;

};

用Function構(gòu)造器創(chuàng)建新函數(shù)不但寫法比較晦澀、性能比較低效,而且新函數(shù)使用的還是全局作用域,代碼如下所示。

varname="freedom";

//全局變量

functionfunc(){

varname="strick";

returnnewFunction("returnname;");

}

func()();//"freedom"[考點]函數(shù)

16.

執(zhí)行下面的代碼,為何輸出的都是3?

for(vari=0;i<3;1++){

setTimeout(function(){

console.log(i);

},0);

}正確答案:當把匿名函數(shù)作為值傳遞給定時器時,只要執(zhí)行異步回調(diào),就會創(chuàng)建一個閉包。在閉包中能夠引用循環(huán)中的i變量,幾個定時器都會在循環(huán)結(jié)束后再執(zhí)行,此時i變量中的值為3。[考點]函數(shù)

17.

請談談你對閉包的理解。正確答案:當一個函數(shù)能夠訪問和操作另一個函數(shù)作用域中的變量時,就構(gòu)成了一個閉包(closure)。閉包之所以有這個能力,是因為這些變量存在于該函數(shù)聲明時所處的作用域。在一個函數(shù)中嵌套另一個函數(shù),或者將一個匿名函數(shù)作為值傳入另一個函數(shù)中,是創(chuàng)建閉包的常見方式。閉包有個最大的特點,就是能記住聲明時所處的作用域,這樣就能讓函數(shù)在其他作用域中也能被成功調(diào)用,即使那個作用域消失了,它還是能訪問其中的變量,因為它保存了變量的引用。[考點]函數(shù)

18.

請封裝一個函數(shù),用于判斷某個數(shù)是否是質(zhì)數(shù)。正確答案:質(zhì)數(shù)又叫素數(shù),是指一個大于1的自然數(shù),除了1和它本身外,不能被其他自然數(shù)整除。利用記憶函數(shù),可在每次計算完成后,就將計算結(jié)果緩存到函數(shù)的自有屬性內(nèi),具體實現(xiàn)如下所示。

functionprime(number){

if(!prime.digits){

prime.digits={};

//緩存對象

}

if

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論