版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
前端程序員面試分類模擬題4簡答題1.
五名海盜搶得了窖藏的100塊金子,打算瓜分這些戰(zhàn)利品。這是一些講民主的海盜(當然是他們自己特有的民主),他們的習慣是按下面的方式進行分配:最厲害的一名海盜提出分配方案(江南博哥),然后所有的海盜(包括提出方案者本人)就此方案進行表決。如果50%或更多的海盜贊同此方案,此方案就獲得通過并據(jù)此分配戰(zhàn)利品。否則提出方案的海盜將被扔到海里,然后下一名最厲害的海盜又重復上述過程。
所有的海盜都樂于看到他們的一位同伙被扔進海里,不過,如果讓他們選擇的話,他們還是寧可只得一筆現(xiàn)金,也不愿意自己被扔到海里。所有的海盜都是有理性的,而且知道其他的海盜也是有理性的。此外,沒有兩名海盜是同等厲害的——這些海盜按照完全由上到下的等級排好了座次,并且每個人都清楚自己和其他所有人的等級。這些金塊不能再分,也不允許幾名海盜共有金塊,因為任何海盜都不相信他的同伙會遵守關于共享金塊的安排。這是一伙每人都只為自己打算的海盜。
最兇的一名海盜應當提出什么樣的分配方案才能使他獲得最多的金子呢?正確答案:如果輪到第四個海盜分配:100,0。
輪到第三個:99,0,1。
輪到第二個:99,0,1,0。
輪到第一個:98,0,1,0,1,這就是第一個海盜的最佳方案。
可以從后往前推測每次最優(yōu)的方案,從而確定第一種方案就是最好的。
(1)當只剩兩個海盜分金時,因為只要有50%或以上的支持率則方案通過,所以第四個海盜和第五個海盜分金時,無論第五個海盜是否支持自己,第四個海盜都可以給自己分配100個金幣。
(2)當只剩三個海盜分金時,第三個海盜分金的方案,除了自己的支持外,還需要一個海盜的支持,否則方案不通過。所以,如果第三個海盜想要拿最多金幣,最好的方案就是讓第五個海盜得到金幣來支持他,因為第四個海盜可以通過否定第三個海盜的方案實現(xiàn)自己的利益最大化。所以,第三個海盜得99金幣,而第五個海盜得1個金幣的方案是最好的。
(3)當只剩下四個海盜分金時,第二個海盜的方案,只需要一個海盜支持他即可通過方案。由(2)的分析知道,要第四個海盜支持自己是最有利的,所以可以得到最好的方案是:第二個海盜99金幣,第四個海盜1個金幣的方案。
(4)最初的情況,五個海盜分金,第一個海盜必須要其余兩名海盜支持自己,它才有可能得到最多的金幣。通過(3)的分析知道,分配給第三個海盜和第五個海盜各1枚金幣從而讓他們支持自己是最優(yōu)的方案。[考點]邏輯題經典邏輯題
2.
什么是響應式設計?正確答案:響應式設計(ResponsiveWebDesign)可根據(jù)不同設備的可視區(qū)域改變網頁布局,展現(xiàn)不同設計風格,力求在當前設備中達到最完美的效果,減少用戶瀏覽網頁的額外操作(例如縮放、平移或滾動等)。舉個簡單的例子,同一張網頁,在打印的時候盡量用白底黑字、為鏈接增加下畫線、禁止背景圖像;在移動端移除不支持的CSS偽類(例如:hover、:focus等),少用耗性能的特效,考慮橫屏和豎屏之間的變化;在屏幕閱讀器中確保CSS插入的內容僅僅是裝飾,過渡、轉換和動畫也僅僅是裝飾,而不是關鍵功能。響應式設計是流式網格、自適應圖像和媒體查詢的結合體,具體如下所列。
(1)流式網格要求元素使用相對單位或百分比控制尺寸大小。
(2)自適應圖像是指不給圖像設置固定尺寸,根據(jù)流式網格進行縮放,最大到100%。
(3)創(chuàng)建不同的媒體查詢,根據(jù)設備的尺寸和特點,設置適合的樣式。下圖中展示的就是不同屏幕尺寸下的頁面布局。
響應式布局[考點]CSS3屬性媒體查詢
3.
HTML實體的應用場景有哪些?正確答案:如果要在HTML文檔中顯示特殊字符(例如“<”“>”等),那么就可以使用HTML實體。HTML實體還能預防XSS(跨站腳本攻擊)攻擊。XSS通常會將腳本代碼注入HTML文檔中,再解析執(zhí)行,但使用了HTML實體后,就可以讓相關代碼只打印,而不執(zhí)行。[考點]HTML與XHTML
4.
XSS是什么?對這種攻擊有哪些防范辦法?正確答案:XSS(CrossSiteScript)即跨站腳本攻擊,它將惡意腳本注入到目標網頁中,用戶在訪問該頁面時,有可能造成信息泄露、用戶行為被劫持、感染并傳播蠕蟲病毒等危害。防范辦法如下所列:
(1)為Cookie添加HttpOnly標記,使得客戶端不能通過JavaScript讀取Cookie信息。
(2)對提交到服務器中的信息做輸入檢查,例如白名單過濾、把字符編碼成HTML實體等。
(3)對輸出到頁面中的信息做輸出檢查,檢查方式和第二種類似。[考點]Web性能和安全
5.
10個房間里放著隨機數(shù)量的金幣,每個房間只能進入一次,并只能在一個房間中拿金幣。一個人采取如下策略:前4個房間只看不拿,隨后的房間只要看到比前4個房間都多的金幣數(shù)就拿,否則就拿最后一個房間的金幣。編程計算這種策略拿到最多金幣的概率。正確答案:這道題是求一個概率的問題。由于10個房間里放的金幣數(shù)量是隨機的,因此,在編程實現(xiàn)的時候首先需要生成10個隨機數(shù)來模擬10個房間里的金幣數(shù)量,然后再判斷通過這種策略是否能拿到最多的金幣。如果僅僅通過一次模擬來求拿到最多金幣的概率顯然是不準確的,那么就需要進行多次模擬,通過記錄模擬的次數(shù)m,以及拿到最多金幣的次數(shù)n,就可以計算出拿到最多金幣的概率n/m。顯然這個概率與金幣的數(shù)量以及模擬的次數(shù)有關系。模擬的次數(shù)越多越能接近真實值。下面以金幣數(shù)為1~10的隨機數(shù),模擬次數(shù)為1000次為例給出實現(xiàn)代碼。
/*
**函數(shù)功能:判斷用指定的策略是否能拿到最多金幣
**函數(shù)參數(shù):把數(shù)組a看成房間,總共n個房間
**返回值:如果能拿到最多金幣返回1,否則返回0
*/
functiongetMaxNum(a,n){
//隨機生成10個房間里的金幣個數(shù)
varrand;
for(vari=0;i<n;i++){
rand=Math.floor(Math.random()*10);
a[i]=rand%10+1;
//生成1~10的隨機數(shù)
}
//找出前4個房間中最多的金幣個數(shù)
varmax4=0;
for(i=0;i<4;i++){
if(a[i]>max4)
max4=a[i];
}
for(i=4;i<n-1;i++){
if(a[i]>max4)
return1;
//能拿到最多的金幣
}
return0;
//不能拿到最多的金幣
}
vara=[],
monitorCount=1000,
success=0;
for(vari=0;i<monitorCount;i+){
if(getMaxNum(a,10))
success++;
}
console.log(success/monitorCount);
//返回的是隨機數(shù),例如0.421[考點]排列組合與概率
6.
什么叫漸進增強?它和優(yōu)雅降級有哪些區(qū)別?正確答案:漸進增強(ProgressiveEnhancement)并不是一種技術,而是一種設計思想。各個瀏覽器的渲染能力各不相同,要做一個每個人看到的網頁、感受到的體驗都一致的網站是幾乎不可能的。但還是得確保網站的可訪問性,保證用戶在任何環(huán)境下,都能正常訪問核心內容或使用基本功能(避免頁面打不開、排版錯亂等),并為他們提供當前條件下最好的體驗,這是漸進增強的核心思想。
優(yōu)雅降級(GracefulDegradation)也是一種設計思想,保證在高版本瀏覽器中提供最好的體驗,遇到低版本瀏覽器再降級進行兼容處理,使其能正常瀏覽。兩種思想的區(qū)別如下所列。
(1)漸進增強是向上兼容,優(yōu)雅降級是向下兼容。
(2)漸進增強是從簡單到復雜,優(yōu)雅降級是從復雜到簡單。
(3)漸進增強關注的是內容,優(yōu)雅降級關注的是瀏覽體驗。[考點]CSS與CSS3
7.
請簡單描述一下canvas元素。正確答案:canvas是HTML5新增的元素,該元素能創(chuàng)建一個固定大小的畫布,在畫布中可以繪制或處理要展示的內容(例如圖像、文本等),以下是它的特征和功能。
(1)只能通過JavaScript腳本來繪制圖形,例如矩形、圓等。
(2)如果要為圖形設置CSS樣式、文本或動畫,那么也得通過JavaScript來實現(xiàn)。
(3)canvas元素有很強的圖像操作能力,不僅能實現(xiàn)圖像的合成與裁剪,還能修改圖像的像素數(shù)據(jù),實現(xiàn)濾鏡的一些效果(例如浮雕、模糊和黑白等)。
(4)如果在畫布中繪制一個按鈕,不能直接為這個按鈕添加DOM事件(例如點擊、聚焦等)。[考點]多媒體和繪圖
8.
在移動端,經常會做整屏的專題頁面。如何設置元素的高度,使得頁面的背景能鋪滿整個屏幕?正確答案:為了能讓背景鋪滿整個屏幕,可以把根元素(html)的高度設為100%(代碼如下所示),然后在該元素中設置背景。
html{
height:100%;
}
根元素的百分比高度之所以有效,是因為根元素的包含塊是由視口提供的初始包含塊(initialcontainingblock),初始包含塊的高度就是視口高度。[考點]值和單位
9.
現(xiàn)在有100個燈泡,每個燈泡都是關著的。第一次把所有的燈泡打開,第二次把偶數(shù)位的燈泡置反(也就是開了的關掉,關了的打開),第三次讓第3,6,9……的燈泡置反,以此類推,直到第100次讓第100個燈泡置反,那么經過一百次以后有多少燈泡亮著?正確答案:根據(jù)題目意思可以得出以下三個結論:
(1)對于每盞燈,當拉動的次數(shù)是奇數(shù)時,燈就是亮著的,當拉動的次數(shù)是偶數(shù)時,燈就是關著的。
(2)每盞燈拉動的次數(shù)與它的編號所含約數(shù)的個數(shù)有關,它的編號有幾個約數(shù),這盞燈就被拉動幾次。
(3)1~100這100個數(shù)中有幾個數(shù)的約數(shù)個數(shù)是奇數(shù)。
由于最開始燈是滅的,所以,只有經過奇數(shù)次改變開關狀態(tài)的燈是亮的,相對應的數(shù)學解釋就是燈的編號有奇數(shù)個不同的約數(shù)。一個數(shù)的約數(shù)都是成對出現(xiàn)的,只有完全平方數(shù),它的約數(shù)個數(shù)才是奇數(shù),例如:1的約數(shù)為1,4的約數(shù)為1、2、4,9的約數(shù)為1、3、9,以此類推,這100盞燈中有10盞燈是亮著的。它們的編號分別是:1、4、9、16、25、36、49、64、81、100。[考點]邏輯題數(shù)學計算
10.
像下面這樣判斷obj是不是一個對象有什么潛在問題?如何改進?
typeofobj==="object"正確答案:當用typeof運算符檢測數(shù)據(jù)類型時,如果操作數(shù)是null,那么返回的不是“null”,而是“object”。如果要區(qū)分null和對象,可以用基礎對象Object的原型方法toString()對null做進一步的檢測,如下所示。
vartoString=Ototype.toString;
toString.call(null);
//"[objectNull]"[考點]基本語法
11.
古典問題:若有一只兔子每個月生一只小兔子,小兔子一個月后也開始生產。起初只有一只兔子,一個月后就有兩只兔子,二個月后就有三只兔子,三個月后有五只兔子(小兔子投入生產),n個月后有多少只兔子?正確答案:兔子的出生規(guī)律數(shù)列為1,1,2,3,5,8,13,21,…實際上是求解斐波那契數(shù)列,公式為:S(n)=S(n-1)+S(n-2)。首先用k表示要求解多少個月,k1表示上個月的兔子數(shù)量,k2代表上上個月的兔子數(shù)量,sum為兔子的總數(shù)。然后從1月開始循環(huán),通過斐波那契數(shù)列公式得到sum=k1+k2,之后,把k1(上個月的兔子數(shù)量)賦值給k2(上上個月的兔子數(shù)量),再把sum(當月的兔子總數(shù))賦值給k1(上個月的兔子數(shù)量)。循環(huán)結束后輸出的sum就是兔子的總數(shù)了。JavaScript代碼實現(xiàn)為:
vark=12,
//一共12個月
k1=1,
//記錄上個月兔子數(shù)量
k2=0,
//記錄上個月兔子數(shù)量
sum=0;
//總和
for(vari=1;i<k;i++){
sum=k1+k2;
//當月的兔子和
k2=k1;
//上個月的兔子數(shù)量賦值給上上個月的記錄
k1=sum;
//當月的兔子數(shù)量賦值給上個月的記錄
}
console.log(sum);
//144[考點]經典算法題
12.
什么是MAC地址?正確答案:MAC地址,也稱為物理地址,用來定義網絡設備的位置,它總共有48位,以十六進制表示,由兩大塊組成:IEEE(電氣電子工程師學會)分配給廠商的識別碼和廠商內部定義的唯一識別碼,如下所示。
00-36-76-47-D6-7A[考點]網絡安全
13.
如何實現(xiàn)鏈表的逆序?正確答案:鏈表作為最基本的數(shù)據(jù)結構,它不僅在實際應用中有著非常重要的作用,而且也是程序員面試筆試中必考的內容。具體而言,它的存儲特點為:可以用任意一組存儲單元來存儲單鏈表中的數(shù)據(jù)元素(存儲單元可以是不連續(xù)的),而且,除了存儲每個數(shù)據(jù)元素ai外,還必須存儲指示其直接后繼元素的信息。這兩部分信息組成的數(shù)據(jù)元素ai的存儲映像稱為結點。N個結點連在一塊被稱為鏈表,結點只包含其后繼結點信息的鏈表就被稱為單鏈表,而鏈表的第一個結點通常被稱為頭結點。
對于單鏈表,又可以將其分為有頭結點的單鏈表和無頭結點的單鏈表,如下圖所示。
有頭結點和無頭結點
在單鏈表的開始結點之前附設一個類型相同的結點,稱之為頭結點,頭結點的數(shù)據(jù)域可以不存儲任何信息(也可以存放線性表的長度等附加信息),頭結點的指針域存儲指向開始結點的指針(即第一個元素結點的存儲位置)。
具體而言,頭結點的作用主要有以下兩點:
(1)對于帶頭結點的鏈表,當在鏈表的任何結點之前插入新結點或刪除鏈表中任何結點時,要做的都是修改前一個結點的指針域,因為任何結點都有前驅結點。若鏈表沒有頭結點,則首結點沒有前驅結點,在其前面插入結點或刪除該結點時操作會復雜些,需要特殊的處理。
(2)對于帶頭結點的鏈表,鏈表的頭指針是指向頭結點的非空指針,因此,對空鏈表與非空鏈表的處理是一樣的。
以下是一個單鏈表數(shù)據(jù)結構的定義示例。
//鏈表結點
functionnode(id,name){
this.id=id;
//結點id
=name;
//結點名稱
this.next=null;
//下一結點
}
//單鏈表
functionlinkList(id,name){
this.header=newnode(id,name);
//鏈表頭結點
}
linkLtotype={
addLink:function(node){
//添加結點數(shù)據(jù)
varcurrent=this.header;
while(current.next!=null){
if(current.next.id>node.id){
break;
}
current=current.next;
}
node.next=current.next;
current.next=node;
},
clear:function(){
//清空鏈表
this.header=null;
},
getLinkList:function(){
//獲取鏈表
varcurrent=this.header;
if(current.next==null){
console.log("鏈表為空");
return;
}
vartxt="";
while(current.next!=null){
txt+=+"";
if(current.next.next==null){
break;
}
current=current.next;
}
console.log(txt);
},
reverse:function(){
//對單鏈表進行逆序
varhead=this.header;
//判斷鏈表是否為空
if(head==null||head.next==null){
console.log("鏈表為空");
return;
}
varpre=null,
//前驅結點
cur=null,
//當前結點
next=null;
//后繼結點
//把鏈表首結點變?yōu)槲步Y點
cur=head.next;
next=cur.next;
cur.next=null;
pre=cur;
cur=next;
//使當前遍歷到的結點cur指向其前驅結點
while(cur.next!=null){
next=cur.next;
cur.next=pre;
pre=cur;
cur=cur.next;
cur=next;
}
//最后一個結點指向倒數(shù)第二個結點
cur.next=pre;
//鏈表的頭結點指向原來鏈表的尾結點
head.next=cur;
}
};
varlists=newlinkList();
for(vari=0;i<8;1++){
lists.addLink(newnode(i,i));
}
console.log("逆序前:");
lists.getLinkList();
//01234567
lists.reverse();
console.log("逆序后:");
lists.getLinkList();
//76543210
//釋放鏈表所占的空間
lists.clear();[考點]鏈表
14.
假設下面div元素中的a元素可動態(tài)添加,現(xiàn)在要求點擊任意的a元素,都能讓它的自定義屬性data-digit的值和內容進行拼接,再用alert()方法輸出拼接后的結果。
<divid="container">
<ahref="#"data-digit="1">按鈕</a>
</div>正確答案:可以采用事件委托的方式,一次性為所有的a元素綁定點擊事件,不用再為每個動態(tài)添加的a元素綁定點擊事件了。通過事件對象event的target屬性獲取當前的事件目標,然后讀取它的標簽名并判斷是否是a元素。如果是a元素,那么再讀取它的自定義屬性和內容執(zhí)行拼接操作,最后用alert()方法輸出,具體過程如下所示。
varcontainer=document.getElementById("container");
container.addEventListener("click",function(event){
varelement=event.target;
//當前事件目標
if(element.tagName.toLowerCase()!="a"){
return;
}
alert(element.dataset.digit+element.innerHTML);
},false);[考點]事件處理和Ajax
15.
請封裝一個函數(shù),用于判斷某個數(shù)是否是質數(shù)。正確答案:質數(shù)又叫素數(shù),是指一個大于1的自然數(shù),除了1和它本身外,不能被其他自然數(shù)整除。利用記憶函數(shù),可在每次計算完成后,就將計算結果緩存到函數(shù)的自有屬性內,具體實現(xiàn)如下所示。
functionprime(number){
if(!prime.digits){
prime.digits={};
//緩存對象
}
if(prime.digits[number]!==undefined){
returnprime.digits[number];
}
varisPrime=false;
for(vari=2;i<number;i++){
if(number%i==0)
{
isPrime=false;
break;
}
}
if(i=number){
isPrime=true;
}
return(prime.digits[number]=isPrime);
}[考點]函數(shù)
16.
翻轉(也叫顛倒)棧的所有元素,例如輸入棧{1,2,3,4,5},其中,1在棧頂,翻轉之后的棧為{5,4,3,2,1},其中,5在棧項。正確答案:最容易想到的辦法是申請一個額外的隊列,先把棧中的元素依次出棧放到隊列里,然后把隊列里的元素按照出隊列的順序入棧,這樣就可以實現(xiàn)棧的翻轉,這種方法的缺點是需要申請額外的空間存儲隊列,因此,空間復雜度較高。下面介紹一種空間復雜度較低的遞歸方法。
遞歸程序有兩個關鍵因素需要注意:遞歸定義和遞歸終止條件。經過分析后,很容易得到該問題的遞歸定義和遞歸終止條件。遞歸定義:將當前棧的最底元素移到棧頂,其他元素順次下移一位,然后對不包含棧頂元素的子棧進行同樣的操作。終止條件:遞歸下去,直到棧為空。遞歸的調用過程如圖1所示。
圖1翻轉棧的遞歸過程
在圖1中,對棧{1,2,3,4,5}進行翻轉的操作為:首先把棧底元素移動到棧頂?shù)玫綏5,1,2,3,4},然后對不包含棧頂元素的子棧進行遞歸調用(對子棧元素進行翻轉),子棧{1,2,3,4}翻轉的結果為{4,3,2,1},因此,最終得到翻轉后的棧為{5,4,3,2,1}。
此外,由于棧的后進先出的特點,使得只能取棧頂?shù)脑?。因此,要把棧底的元素移動到棧頂也需要遞歸調用才能完成,主要思路為:把不包含該棧頂元素的子棧棧底元素移動到子棧的棧頂,然后把棧頂?shù)脑嘏c子棧棧頂?shù)脑?其實就是與棧頂相鄰的元素)進行交換。
圖2子棧的遞歸過程
為了容易理解遞歸調用,可以認為在進行遞歸調用的時候,子棧已經實現(xiàn)把棧底元素移動到棧頂。在圖2中為了把棧{1,2,3,4,5}的棧底元素5移動到棧頂,首先對子棧{2,3,4,5}進行遞歸調用,調用的結果為{5,2,3,4},然后將子棧棧頂元素5與棧頂元素1進行交換得到棧{5,1,2,3,4},從而把棧底元素移動到了棧頂。示例代碼如下。
functionLNode(){
this.mElem=null;
this.mNext=null;
}
functionStackLinked(){
this.mNext=null;
//頭"指針",指向棧頂元素
this.mLength=0;
//棧內元素個數(shù)
}
StackLtotype={
/**
*判斷棧是否為空棧
*@returnboolean如果為空棧返回true,否則返回false
*/
getlsEmpty:function(){
returnthis.mNext==null;
},
/**
*將所有元素出棧
*@returnarray返回所有棧內元素
*/
getAllPopStack:function(){
vare=[];
if(!this.getIsEmpty()){
while(this.mNext!=null){
e.push(this.mNext.mElem);
this.mNext=this.mNext.mNext;
}
}
this.mLength=0;
returne;
},
/**
*返回棧內元素個數(shù)
*@returnint
*/
getLength:function(){
returnthis.mLength;
},
/**
*元素入棧
*@parammixede入棧元素值
*@returnvoid
*/
push:function(e){
varnewLn=newLNode();
newLn.mElem=e;
newLn.mNext=this.mNext;
this.mNext=newLn;
this,mLength++;
},
/**
*元素出棧
*@returnboolean出棧成功返回true,否則返回false
*/
pop:function(){
if(this.getIsEmpty()){
returnfalse;
}
varp=this.mNext,
e=p,mElem;
this.mNext=p.mNext;
this.mLength--;
returntrue;
},
/**
*僅返回棧內所有元素
*@returnarray棧內所有元素組成的一個數(shù)組
*/
getAllElem:function(){
varsldata=[],
p;
if(!this.getlsEmpty()){
p=this,mNext;
while(p!=null){
sldata.push(p.mElem);
p=p.mNext;
}
}
returnsldata;
},
/**
*返回棧頂元素
*@returnelement返回棧頂元素
*/
top:function(){
if(this.getIsEmpty()){
returnfalse;
}
varlist=this.getAllElem();
returnlist[0];
},
/**
*把棧底元素移動到棧頂
*/
move_bottom_to_top:function(){
if(this,getIsEmpty())
return;
vartop1=this.top(),
top2;
this.pop();
//彈出棧頂元素
if(!this.getIsEmpty()){
//遞歸處理不包含棧頂元素的子棧
this.move_bottom_to_top();
top2=this.top();
this.pop();
//交換棧項元素與子棧棧頂元素
this.push(top1);
this.push(top2);
}else{
this.push(top1);
}
},
/**
*翻轉棧
*/
reverse_stack:function(){
if(this.getIsEmpty())
return;
//把棧底元素移動到棧頂
this.move_bottom_to_top();
vartop=this.top();
this.pop();
//遞歸處理子棧
this.reverse_stack();
this.push(top);
}
};
varstack=newStackLinked();
stack.push('5');
stack.push('4');
stack.push('3');
stack.push('2');
stack.push('1');
stack.reverse_stack();
console.log("翻轉后的出棧順序為:");
vartxt="";
while(!stack.getIsEmpty()){
txt+=stack.top()+"";
stack.pop();
}
console.log(txt);
//54321[考點]棧和隊列
17.
把一個有序數(shù)組最開始的若干個元素搬到數(shù)組的末尾,稱之為數(shù)組的旋轉。輸入一個排好序的數(shù)組的一個旋轉,輸出旋轉數(shù)組的最小元素。例如數(shù)組[3,4,5,1,2]為數(shù)組[1,2,3,4,5]的一個旋轉,該數(shù)組的最小值為1。正確答案:通過數(shù)組的特性可以發(fā)現(xiàn),數(shù)組元素首先是遞增的,然后突然下降到最小值,再遞增。雖然如此,但是還有下面三種特殊情況需要注意:
(1)數(shù)組本身是沒有發(fā)生過旋轉的,還是一個有序的數(shù)組,例如序列[1,2,3,4,5,6]。
(2)數(shù)組中元素值全部相等,例如序列[1,1,1,1,1,1]。
(3)數(shù)組中元素值大部分都相等,例如序列[1,0,1,1,1,1]。
通過旋轉數(shù)組的定義可知,經過旋轉之后的數(shù)組實際上可以劃分為兩個有序的子數(shù)組,前面子數(shù)組的元素值都大于或者等于后面子數(shù)組的元素值。可以根據(jù)數(shù)組元素的這個特點,采用二分查找的思想不斷縮小查找范圍,最終找出問題的解決方案,具體實現(xiàn)思路如下。
按照二分查找的思想,給定數(shù)組arr,首先定義兩個變量low和high,分別表示數(shù)組的第一個元素和最后一個元素的下標。按照題目中對旋轉規(guī)則的定義,第一個元素應該是大于或者等于最后一個元素的(當旋轉個數(shù)為0,即沒有旋轉的時候,要單獨處理,直接返回數(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){
//如果旋轉個數(shù)為0(即沒有旋轉),則單獨處理,直接返回數(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ù)組
18.
什么是嚴格模式?嚴格模式有哪些限制?正確答案:ECMAScript5引入了嚴格模式(strictmode)的概念。嚴格模式對JavaScript的語法和行為都做了一些更改,消除了語言中一些不合理、不確定、不安全之處;提
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度攝影師與攝影棚運營方居間合同2篇
- 二零二五版社區(qū)配送訂餐服務合同范本與社區(qū)管理協(xié)議3篇
- 二零二五年度酒店地毯綠色生產與環(huán)保認證合同3篇
- 二零二五年新能源充電樁建設運營合同樣本3篇
- 二零二五版高端住宅項目全程代理銷售合同3篇
- 二零二五版基因合成與生物技術知識產權轉讓合同3篇
- 二零二五版10月大型設備運輸委托合同2篇
- 二零二五版廣西事業(yè)單位聘用示范性合同模板12篇
- 2025年度出口貨物環(huán)保認證服務合同3篇
- 二零二五年度膩子材料國際貿易代理合同2篇
- 金蝶云星辰初級考試題庫
- 常見老年慢性病防治與護理課件整理
- 履約情況證明(共6篇)
- 云南省迪慶藏族自治州各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會明細
- 設備機房出入登記表
- 六年級語文-文言文閱讀訓練題50篇-含答案
- 醫(yī)用冰箱溫度登記表
- 零售學(第二版)第01章零售導論
- 口袋妖怪白金光圖文攻略2周目
- 光伏發(fā)電站集中監(jiān)控系統(tǒng)通信及數(shù)據(jù)標準
- 三年級下冊生字組詞(帶拼音)
評論
0/150
提交評論