天天看點

程式員面試金典算法題空格替換基本字元串壓縮确定字元互異原串翻轉确定兩串亂序同構像素翻轉清除行列翻轉子串通路單個節點的删除連結清單分割鍊式A+B回文連結清單雙棧排序二叉樹平衡檢查輸出單層結點檢查是否為BST尋找下一個結點二進制插入二進制小數最接近的數整數轉化奇偶位交換找出缺失的整數像素設定第k個數碰撞的螞蟻上樓梯機器人走方格I機器人走方格II魔術索引I魔術索引II

題目描述

請編寫一個方法,将字元串中的空格全部替換為“%20”。假定該字元串有足夠的空間存放新增的字元,并且知道字元串的真實長度(小于等于1000),同時保證字元串由大小寫的英文字母組成。

給定一個string inistring 為原始的串,以及串的長度 int len, 傳回替換後的string。

測試樣例:

“mr john smith”,13

傳回:”mr%20john%20smith”

”hello world”,12

傳回:”hello%20%20world”

利用字元重複出現的次數,編寫一個方法,實作基本的字元串壓縮功能。比如,字元串“aabcccccaaa”經壓縮會變成“a2b1c5a3”。若壓縮後的字元串沒有變短,則傳回原先的字元串。

給定一個string inistring為待壓縮的串(長度小于等于3000),保證串内字元均由大小寫英文字母組成,傳回一個string,為所求的壓縮後或未變化的串。

測試樣例

“aabcccccaaa”

傳回:”a2b1c5a3”

“welcometonowcoderrrrr”

傳回:”welcometonowcoderrrrr”

請實作一個算法,确定一個字元串的所有字元是否全都不同。這裡我們要求不允許使用額外的存儲結構。

給定一個string inistring,請傳回一個bool值,true代表所有字元全都不同,false代表存在相同的字元。保證字元串中的字元為ascii字元。字元串的長度小于等于3000。

“aeiou”

傳回:true

“barackobama”

傳回:false

請實作一個算法,在不使用額外資料結構和儲存空間的情況下,翻轉一個給定的字元串(可以使用單個過程變量)。

給定一個string inistring,請傳回一個string,為翻轉後的字元串。保證字元串的長度小于等于5000。

“this is nowcoder”

傳回:”redocwon si siht”

給定兩個字元串,請編寫程式,确定其中一個字元串的字元重新排列後,能否變成另一個字元串。這裡規定大小寫為不同字元,且考慮字元串重點空格。

給定一個string stringa和一個string stringb,請傳回一個bool,代表兩串是否重新排列後可相同。保證兩串的長度都小于等于5000。

“this is nowcoder”,”is this nowcoder”

“here you are”,”are you here”

有一副由nxn矩陣表示的圖像,這裡每個像素用一個int表示,請編寫一個算法,在不占用額外記憶體空間的情況下(即不使用緩存矩陣),将圖像順時針旋轉90度。

給定一個nxn的矩陣,和矩陣的階數n,請傳回旋轉後的nxn矩陣,保證n小于等于500,圖像元素小于等于256。

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

傳回:[[7,4,1],[8,5,2],[9,6,3]]

解析:首先沿對角線折疊,然後交換列

請編寫一個算法,若mxn矩陣中某個元素為0,則将其所在的行與列清零。

給定一個mxn的int[][]矩陣(c++中為vector>)mat和矩陣的階數n,請傳回完成操作後的int[][]矩陣(c++中為vector>),保證n小于等于300,矩陣中的元素為int範圍内。

[[1,2,3],[0,1,2],[0,0,1]]

傳回:[[0,0,3],[0,0,0],[0,0,0]]

假定我們都知道非常高效的算法來檢查一個單詞是否為其他字元串的子串。請将這個算法編寫成一個函數,給定兩個字元串s1和s2,請編寫代碼檢查s2是否為s1旋轉而成,要求隻能調用一次檢查子串的函數。

給定兩個字元串s1,s2,請傳回bool值代表s2是否由s1旋轉而成。字元串中字元為英文字母和空格,區分大小寫,字元串長度小于等于1000。

“hello world”,”worldhello ”

“waterbottle”,”erbottlewat”

實作一個算法,删除單向連結清單中間的某個結點,假定你隻能通路該結點。

給定帶删除的節點,請執行删除操作,若該節點為尾節點,傳回false,否則傳回true

編寫代碼,以給定值x為基準将連結清單分割成兩部分,所有小于x的結點排在大于或等于x的結點之前

給定一個連結清單的頭指針 listnode* phead,請傳回重新排列後的連結清單的頭指針。

有兩個用連結清單表示的整數,每個結點包含一個數位。這些數位是反向存放的,也就是個位排在連結清單的首部。編寫函數對這兩個整數求和,并用連結清單形式傳回結果。

給定兩個連結清單listnode* a,listnode* b,請傳回a+b的結果(listnode*)。

{1,2,3},{3,2,1}

傳回:{4,4,4}

請編寫一個函數,檢查連結清單是否為回文。

給定一個連結清單listnode* phead,請傳回一個bool,代表連結清單是否為回文。

{1,2,3,2,1}

{1,2,3,2,3}

請編寫一個程式,按升序對棧進行排序(即最大元素位于棧頂),要求最多隻能使用一個額外的棧存放臨時資料,但不得将元素複制到别的資料結構中。

給定一個int[] numbers(c++中為vector),其中第一個元素為棧頂,請傳回排序後的棧。請注意這是一個棧,意味着排序過程中你隻能通路到第一個元素。

[1,2,3,4,5]

傳回:[5,4,3,2,1]

實作一個函數,檢查二叉樹是否平衡,平衡的定義如下,對于樹中的任意一個結點,其兩顆子樹的高度差不超過1。

給定指向樹根結點的指針treenode* root,請傳回一個bool,代表這棵樹是否平衡。

對于一棵二叉樹,請設計一個算法,建立含有某一深度上所有結點的連結清單。

給定二叉樹的根結點指針treenode* root,以及連結清單上結點的深度,請傳回一個連結清單listnode,代表該深度上所有結點的值,請按樹上從左往右的順序連結,保證深度不超過樹的高度,樹上結點的值為非負整數且不超過100000。

請實作一個函數,檢查一棵二叉樹是否為二叉查找樹。

給定樹的根結點指針treenode* root,請傳回一個bool,代表該樹是否為二叉查找樹。

請設計一個算法,尋找二叉查找樹中指定結點的下一個結點(即中序周遊的後繼)。

給定樹的根結點指針treenode* root和結點的值int p,請傳回值為p的結點的後繼結點的值。保證結點的值大于等于零小于等于100000且沒有重複值,若不存在後繼傳回-1。

有兩個32位整數n和m,請編寫算法将m的二進制數位插入到n的二進制的第j到第i位,其中二進制的位數從低位數到高位且以0開始。

給定兩個數int n和int m,同時給定int j和int i,意義如題所述,請傳回操作後的數,保證n的第j到第i位均為零,且m的二進制位數小于等于j-i+1。

1024,19,2,6

傳回:1100

有一個介于0和1之間的實數,類型為double,傳回它的二進制表示。如果該數字無法精确地用32位以内的二進制表示,傳回“error”。

給定一個double num,表示0到1的實數,請傳回一個string,代表該數的二進制表示或者“error”。

0.625

傳回:0.101

有一個正整數,請找出其二進制表示中1的個數相同、且大小最接近的那兩個數。(一個略大,一個略小)

給定正整數int x,請傳回一個vector,代表所求的兩個數(小的在前)。保證答案存在。

2

傳回:[1,4]

編寫一個函數,确定需要改變幾個位,才能将整數a轉變成整數b。

給定兩個整數int a,int b。請傳回需要改變的數位個數。

10,5

傳回:4

請編寫程式交換一個數的二進制的奇數位和偶數位。(使用越少的指令越好)

給定一個int x,請傳回交換後的數int。

10

傳回:5

數組a包含了0到n的所有整數,但其中缺失了一個。對于這個問題,我們設定限制,使得一次操作無法取得數組number裡某個整數的完整内容。唯一的可用操作是詢問數組中第i個元素的二進制的第j位(最低位為第0位),該操作的時間複雜度為常數,請設計算法,在o(n)的時間内找到這個數。

給定一個數組number,即所有剩下的數按從小到大排列的二進制各位的值,如a[0][1]表示剩下的第二個數二進制從低到高的第二位。同時給定一個int n,意義如題。請傳回缺失的數。

[[0],[0,1]]

傳回:1

有一個單色螢幕儲存在一維數組中,其中數組的每個元素代表連續的8位的像素的值,請實作一個函數,将第x到第y個像素塗上顔色(像素标号從零開始),并嘗試盡量使用最快的辦法。

給定表示螢幕的數組screen(數組中的每個元素代表連續的8個像素,且從左至右的像素分别對應元素的二進制的從低到高位),以及int x,int y,意義如題意所述,保證輸入資料合法。請傳回塗色後的新的螢幕數組。

[0,0,0,0,0,0],0,47

傳回:[255,255,255,255,255,255]

或者

有一些數的素因子隻有3、5、7,請設計一個算法,找出其中的第k個數。

給定一個數int k,請傳回第k個數。保證k小于等于100。

3

傳回:7

解析:

1. 初始化結果res=1和隊列q3,q5,q7

2. 分别往q3,q5,q7插入1*3,1*5,1*7

3. 求出三個隊列的隊頭元素中最小的那個x,更新結果res=x

4. 如果x在:

q3中,那麼從q3中移除x,并向q3,q5,q7插入3*x,5*x,7*x

q5中,那麼從q5中移除x,并向q5,q7插入5*x,7*x

q7中,那麼從q7中移除x,并向q7插入7*x

5. 重複步驟3-5,直到找到第k個滿足條件的數

在n個頂點的多邊形上有n隻螞蟻,這些螞蟻同時開始沿着多變形的邊爬行,請求出這些螞蟻相撞的機率。(這裡的相撞是指存在任意兩隻螞蟻會相撞)

給定一個int n(3<=n<=10000),代表n變形和n隻螞蟻,請傳回一個double,為相撞的機率。

傳回:0.75

有個小孩正在上樓梯,樓梯有n階台階,小孩一次可以上1階、2階、3階。請實作一個方法,計算小孩有多少種上樓的方式。為了防止溢出,請将結果mod 1000000007

給定一個正整數int n,請傳回一個數,代表上樓的方式數。保證n小于等于100000。

1

ac代碼:

有一個xxy的網格,一個機器人隻能走格點且隻能向右或向下走,要從左上角走到右下角。請設計一個算法,計算機器人有多少種走法。

給定兩個正整數int x,int y,請傳回機器人的走法數目。保證x+y小于等于12。

2,2

傳回:2

有一個xxy的網格,一個機器人隻能走格點且隻能向右或向下走,要從左上角走到右下角。請設計一個算法,計算機器人有多少種走法。注意這次的網格中有些障礙點是不能走的。

給定一個int[][] map(c++ 中為vector >),表示網格圖,若map[i][j]為1則說明該點不是障礙點,否則則為障礙。另外給定int x,int y,表示網格的大小。請傳回機器人從(0,0)走到(x - 1,y - 1)的走法數,為了防止溢出,請将結果mod 1000000007。保證x和y均小于等于50

在數組a[0..n-1]中,有所謂的魔術索引,滿足條件a[i]=i。給定一個升序數組,元素值各不相同,編寫一個方法,判斷在數組a中是否存在魔術索引。請思考一種複雜度優于o(n)的方法。

給定一個int數組a和int n代表數組大小,請傳回一個bool,代表是否存在魔術索引。

在數組a[0..n-1]中,有所謂的魔術索引,滿足條件a[i]=i。給定一個不下降序列,元素值可能相同,編寫一個方法,判斷在數組a中是否存在魔術索引。請思考一種複雜度優于o(n)的方法。

[1,1,3,4,5]

繼續閱讀