導航:首頁 > 源碼編譯 > 推薦演算法面試題

推薦演算法面試題

發布時間:2022-11-06 22:37:42

java演算法面試題:排序都有哪幾種方法

一、冒泡排序
[java] view plain
package sort.bubble;
import java.util.Random;
/**
* 依次比較相鄰的兩個數,將小數放在前面,大數放在後面
* 冒泡排序,具有穩定性
* 時間復雜度為O(n^2)
* 不及堆排序,快速排序O(nlogn,底數為2)
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for(int i = 0 ; i < 10 ; i++){
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for(int i : sort){
System.out.print(i+" ");
}
buddleSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for(int i : sort){
System.out.print(i+" ");
}
}
/**
* 冒泡排序
* @param sort
*/
private static void buddleSort(int[] sort){
for(int i=1;i<sort.length;i++){
for(int j=0;j<sort.length-i;j++){
if(sort[j]>sort[j+1]){
int temp = sort[j+1];
sort[j+1] = sort[j];
sort[j] = temp;
}
}
}
}
}
二、選擇排序
[java] view plain
package sort.select;
import java.util.Random;
/**
* 選擇排序
* 每一趟從待排序的數據元素中選出最小(或最大)的一個元素,
* 順序放在已排好序的數列的最後,直到全部待排序的數據元素排完。
* 選擇排序是不穩定的排序方法。
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for (int i = 0; i < 10; i++) {
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
selectSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
}
/**
* 選擇排序
* @param sort
*/
private static void selectSort(int[] sort){
for(int i =0;i<sort.length-1;i++){
for(int j = i+1;j<sort.length;j++){
if(sort[j]<sort[i]){
int temp = sort[j];
sort[j] = sort[i];
sort[i] = temp;
}
}
}
}
}
三、快速排序
[java] view plain
package sort.quick;
/**
* 快速排序 通過一趟排序將要排序的數據分割成獨立的兩部分, 其中一部分的所有數據都比另外一部分的所有數據都要小,
* 然後再按此方法對這兩部分數據分別進行快速排序, 整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
int[] sort = { 54, 31, 89, 33, 66, 12, 68, 20 };
System.out.print("排序前的數組為:");
for (int data : sort) {
System.out.print(data + " ");
}
System.out.println();
quickSort(sort, 0, sort.length - 1);
System.out.print("排序後的數組為:");
for (int data : sort) {
System.out.print(data + " ");
}
}
/**
* 快速排序
* @param sort 要排序的數組
* @param start 排序的開始座標
* @param end 排序的結束座標
*/
public static void quickSort(int[] sort, int start, int end) {
// 設置關鍵數據key為要排序數組的第一個元素,
// 即第一趟排序後,key右邊的數全部比key大,key左邊的數全部比key小
int key = sort[start];
// 設置數組左邊的索引,往右移動判斷比key大的數
int i = start;
// 設置數組右邊的索引,往左移動判斷比key小的數
int j = end;
// 如果左邊索引比右邊索引小,則還有數據沒有排序
while (i < j) {
while (sort[j] > key && j > start) {
j--;
}
while (sort[i] < key && i < end) {
i++;
}
if (i < j) {
int temp = sort[i];
sort[i] = sort[j];
sort[j] = temp;
}
}
// 如果左邊索引比右邊索引要大,說明第一次排序完成,將sort[j]與key對換,
// 即保持了key左邊的數比key小,key右邊的數比key大
if (i > j) {
int temp = sort[j];
sort[j] = sort[start];
sort[start] = temp;
}
//遞歸調用
if (j > start && j < end) {
quickSort(sort, start, j - 1);
quickSort(sort, j + 1, end);
}
}
}
[java] view plain
/**
* 快速排序
*
* @param a
* @param low
* @param high
* voidTest
*/
public static void kuaisuSort(int[] a, int low, int high)
{
if (low >= high)
{
return;
}
if ((high - low) == 1)
{
if (a[low] > a[high])
{
swap(a, low, high);
return;
}
}
int key = a[low];
int left = low + 1;
int right = high;
while (left < right)
{
while (left < right && left <= high)// 左邊向右
{
if (a[left] >= key)
{
break;
}
left++;
}
while (right >= left && right > low)
{
if (a[right] <= key)
{
break;
}
right--;
}
if (left < right)
{
swap(a, left, right);
}
}
swap(a, low, right);
kuaisuSort(a, low, right);
kuaisuSort(a, right + 1, high);
}
四、插入排序
[java] view plain
package sort.insert;
/**
* 直接插入排序
* 將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據
* 演算法適用於少量數據的排序,時間復雜度為O(n^2)。是穩定的排序方法。
*/
import java.util.Random;
public class DirectMain {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for (int i = 0; i < 10; i++) {
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
directInsertSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
}
/**
* 直接插入排序
*
* @param sort
*/
private static void directInsertSort(int[] sort) {
for (int i = 1; i < sort.length; i++) {
int index = i - 1;
int temp = sort[i];
while (index >= 0 && sort[index] > temp) {
sort[index + 1] = sort[index];
index--;
}
sort[index + 1] = temp;
}
}
}
順便添加一份,差不多的
[java] view plain
public static void charuSort(int[] a)
{
int len = a.length;
for (int i = 1; i < len; i++)
{
int j;
int temp = a[i];
for (j = i; j > 0; j--)//遍歷i之前的數字
{
//如果之前的數字大於後面的數字,則把大的值賦到後面
if (a[j - 1] > temp)
{
a[j] = a[j - 1];
} else
{
break;
}
}
a[j] = temp;
}
}
把上面整合起來的一份寫法:
[java] view plain
/**
* 插入排序:
*
*/
public class InsertSort {
public void sort(int[] data) {
for (int i = 1; i < data.length; i++) {
for (int j = i; (j > 0) && (data[j] < data[j - 1]); j--) {
swap(data, j, j - 1);
}
}
}
private void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
五、順便貼個二分搜索法
[java] view plain
package search.binary;
public class Main {
public static void main(String[] args) {
int[] sort = {1,2,3,4,5,6,7,8,9,10};
int mask = binarySearch(sort,6);
System.out.println(mask);
}
/**
* 二分搜索法,返回座標,不存在返回-1
* @param sort
* @return
*/
private static int binarySearch(int[] sort,int data){
if(data<sort[0] || data>sort[sort.length-1]){
return -1;
}
int begin = 0;
int end = sort.length;
int mid = (begin+end)/2;
while(begin <= end){
mid = (begin+end)/2;
if(data > sort[mid]){
begin = mid + 1;
}else if(data < sort[mid]){
end = mid - 1;
}else{
return mid;
}
}
return -1;
}
}

② Java面試演算法題求解

看了兩行看不下去了,吐槽一下。
現在某些小公司的面試官,面試題花式秀智商,一副全世界都求著他賜予工作的樣子。

③ 面試官常問十大經典演算法排序(用python實現)

演算法是一種與語言無關的東西,更確切地說就算解決問題的思路,就是一個通用的思想的問題。代碼本身不重要,演算法思想才是重中之重

我們在面試的時候總會被問到一下演算法,雖然演算法是一些基礎知識,但是難起來也會讓人非常頭疼。

排序演算法應該算是一些簡單且基礎的演算法,但是我們可以從簡單的演算法排序鍛煉我們的演算法思維。這里我就介紹經典十大演算法用python是怎麼實現的。

十大經典演算法可以分為兩大類:

比較排序: 通過對數組中的元素進行比較來實現排序。

非比較排序: 不通過比較來決定元素間的相對次序。


演算法復雜度

冒泡排序比較簡單,幾乎所有語言演算法都會涉及的冒泡演算法。

基本原理是兩兩比較待排序數據的大小 ,當兩個數據的次序不滿足順序條件時即進行交換,反之,則保持不變。

每次選擇一個最小(大)的,直到所有元素都被輸出。

將第一個元素逐個插入到前面的有序數中,直到插完所有元素為止。

從大范圍到小范圍進行比較-交換,是插入排序的一種,它是針對直接插入排序演算法的改進。先對數據進行預處理,使其基本有序,然後再用直接插入的排序演算法排序。

該演算法是採用 分治法 對集合進行排序。

把長度為n的輸入序列分成兩個長度為n/2的子序列,對這兩個子序列分別採用歸並排序,最終合並成序列。

選取一個基準值,小數在左大數在在右。

利用堆這種數據結構所設計的一種排序演算法。

堆是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。利用最大堆和最小堆的特性。

採用字典計數-還原的方法,找出待排序的數組中最大和最小的元素,統計數組中每個值為i的元素出現的次數,對所有的計數累加,將每個元素放在新數組依次排序。

設置一個定量的數組當作空桶;遍歷輸入數據,並且把數據一個一個放到對應的桶里去;對每個不是空的桶進行排序;從不是空的桶里把排好序的數據拼接起來。

元素分布在桶中:


然後,元素在每個桶中排序:

取得數組中的最大數,並取得位數;從最低位開始取每個位組成新的數組;然後進行計數排序。

上面就是我整理的十大排序演算法,希望能幫助大家在演算法方面知識的提升。看懂之後可以去試著自己到電腦上運行一遍。最後說一下每個排序是沒有調用數據的,大家記得實操的時候要調用。

參考地址:https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

④ 面試演算法題:你的任務就是計算出長度為n的字元串(只包含『A』、『B』和『C』),有多少個是暗黑字元串。

程序肯定不是判斷一個字元串是純潔的還是黑暗的。從現有的題目描述看,程序和題目沒有關系。

題目是否不全?

⑤ 面試演算法知識梳理(14) - 數字演算法

面試演算法知識梳理(1) - 排序演算法
面試演算法知識梳理(2) - 字元串演算法第一部分
面試演算法知識梳理(3) - 字元串演算法第二部分
面試演算法知識梳理(4) - 數組第一部分
面試演算法知識梳理(5) - 數組第二部分
面試演算法知識梳理(6) - 數組第三部分
面試演算法知識梳理(7) - 數組第四部分
面試演算法知識梳理(8) - 二分查找演算法及其變型
面試演算法知識梳理(9) - 鏈表演算法第一部分
面試演算法知識梳理(10) - 二叉查找樹
面試演算法知識梳理(11) - 二叉樹演算法第一部分
面試演算法知識梳理(12) - 二叉樹演算法第二部分
面試演算法知識梳理(13) - 二叉樹演算法第三部分

斐波那契數列 滿足下面的通項公式,要求給出 N ,輸出第 N 項的 F(N)

這里介紹兩種解決辦法, 循環演算法 矩陣演算法 。循環演算法比較容易理解,就是從 F(0) 開始,根據通項公式,得到下一個斐波那契數列中的數字即可。

對於上面的通項公式,可以用下面的矩陣乘法的形式來表示

一個台階總共有 n 級,如果一次可以跳 1 級,也可以跳 2 級,求總共有多少總跳法。

由於有兩種跳台階方式,因此跳 n 級台階可以轉換為下面兩個問題之和:

這就和之前的斐波那契數列的通項公式相同。

這個問題,需要先總結一下規律,我們根據數字 N 的 位數 來進行分析:

那麼 N>=1 時才會出現 1 ,並且出現 1 的次數為 1 次

在這種情況下,出現 1 的次數等於個位上出現 1 的次數加上十位上出現 1 的個數。

例如,如果要計算百位上 1 出現的次數,它要受到三方面的影響:百位上的數字,百位以下的數字,百位以上的數字。

對於一個二進制數,例如 1010 ,將其減 1 後得到的結果是 1001 ,也就是將最後一個 1 (倒數第二位)及其之後的 0 變成 1 , 1 變成 0 ,再將該結果與原二進制數相與,也就是 1010 & 1001 = 1000 ,那麼就可以去掉最後一個 1 。

因此,如果需要計算兩個數的二進製表示中有多少位是不同的,可以 先將這兩個數異或 ,那麼不相同的位數就會變成 1 ,之後利用上面的技巧,通過每次去掉最後一個 1 ,來 統計該結果中 1 的個數 ,就可以知道兩個數的二進製表示中有多少是不同的了。

N! 的含義為 1*2*3*...*(N-1)*N ,計算 N! 的十進製表示中,末尾有多少個 0 。

N! 中能產生末尾是 0 的質數組合是 2*5 ,所以 N! 末尾的 0 的個數取決了 2 的個數和 5 的個數的最小值,有因為被 2 整除的數出現的概率大於 5 ,因此 5 出現的次數就是 N! 末尾 0 的個數。因此,該問題就轉換成為計算從 1~N ,每個數可以貢獻 5 的個數,也就是每個數除以 5 的值。

上面的解法需要從 1 到 N 遍歷每一個數,當然還有更加簡便的方法。以 26! 為例,貢獻 5 的數有 5、10、15、20、25 ,一共貢獻了 6 個 5 ,可以理解為 5 的倍數 5、10、15、20、25 貢獻了一個 5 ,而 25 的倍數又貢獻了一個 5 ,得到下面的公式:

首先,讓我們換一個角度考慮,其實這個問題就是求解二進製表示中從最低位開始 0 的個數,因為二進制最低位為 0 代表的是偶數,能夠被 2 整除,所以質因數 2 的個數就是二進製表示中最低位 1 後面的 0 的個數。

因此,我們的實現這就和上面 2.7 中求解質因數 5 的個數是一樣的。

最大公約數 的定義為 兩個或多個整數的共有約數中最大的一個 。這里採用的是 更相止損法 ,其操作步驟為:

則第一步中約掉的若干個 2 與第二步中等數的乘積就是所求的最大公約數。

有限小數或者無限循環小數都可以轉化為分數,例如:

在 http://blog.csdn.net/flyfish1986/article/details/47783545 這邊文章中,詳細地描述了該題的解決思路,核心思想就是將原小數分為 有限部分 無限循環小數 部分,對於這兩部分別進行處理。

⑥ 大公司筆試面試有哪些經典演算法題目

大公司的筆試面試一般是針對你所面試的崗位進行一些專業知識的考核,不會出現想考公員裡面的行測似得,當然也有哪些逆向思維的計算題。

⑦ A/B Test基本原理

一、引入

ABTest,就是做一個測試,在產品設計場景中,為同一個產品目標制定兩個方案(比如兩個頁面一個用這個文案另一個用那個文案,一個用紅色的按鈕、另一個用藍色),讓一部分用戶使用A方案,另一部分用戶使用B方案,然後利用埋點可以對用戶點擊行為數據進行採集,並通過統計引擎分析結構化的日誌數據,計算相關指標,一般是點擊率、轉化率、CTR(點擊次數/展示量)等,進行假設檢驗,從而得出那個方案更好

ABtest原理很簡單。ABtest的難度主要在開發上:開發新版本、進行測試、測試數據回傳保存

二、AB Test步驟

ABtest本質上是一個兩總體假設檢驗問題,要檢驗A、B兩個版本是否有顯著區別。

兩總體假設檢驗步驟:

第一步:確定對象和指標。明確要檢驗的A、B兩個對象,版本。以及要檢驗的指標,是CTR,還是客單價,ARPU

第二步:給出原假設/備擇假設

第三步:選擇檢驗統計量,t 還是F?(t是總體方差未知或小樣本,用樣本方差代替總體方差。F是總體方差或大樣本)

第四步:埋點,獲取數據。計算統計量,明確A,B版本是否有顯著區別。p值小於顯著性水平0.05則推翻原假設

確定目標 --> 確定最小樣本量 --> 確認流量分割方案 --> 實驗上線 --> 規則校驗 --> 數據收集 --> 效果檢驗

三、AB Test例子

某電商平台,想提升用戶客單價,運營部門做了兩套A、B激勵方案,想將流量分成相同的兩批測試下效果。已選出兩組各12名用戶,測試用戶客單價如下

H0:方案A客單價均值=方案B客單價均值

H1:兩者不相等

解讀結論

既然方案A與方案B不同,A的均值又高於B,那麼就認為A更好

三、AB Test的局限性

AB Test要求數據充足、開發資源充足的時候,才能完美落地

且AB測試得到的結果是更優的方案,而不是最優,所以只能作為一種驗證性的工具和方法,要得到最優,不可能通過做很多次AB Test,這樣成本太大

A/B測試只有在 你要測的KPI指標 可以被電腦量化 時適用,對於聲譽,公關等不適用

四、面試題

Q1:什麼場景可以做AB測試?

產品迭代場景:界面優化、增加功能

策略優化場景:運營策略優化,演算法策略優化(推薦演算法)

檢驗場景:新功能推出,30天內的DAU增加了,那麼要通過假設檢驗來測試這個結果是否顯著

Q2:為什麼要進行ABtest

APP想要存活及增長,精細化運營就變成了必須。往往產品的認知並不是用戶的認知,所以我們需要去測試,去實驗。類似於醫學中的「雙盲實驗」

Q3:AB Test需要多大的樣本?AB Test需要做多久是如何確定的?如果計劃做20天,第10天時感覺結果顯著,能不能停止測試?

樣本量        計算公式: 

Q4:做AB實驗的時候,數據對比上漲25%,判定為效果顯著,但上線後效果不好,為什麼?

樣本量不足,結果是隨機波動導致

實驗時間太短,用戶由於新鮮感表現出不可持續的行為

實驗人群不等於上線人群

外部環境變化,比如打車場景下,下雨和下雪會導致訂單量激增

Q5:談談第一類錯誤,第二類錯誤

互聯網產品案例中,第一類錯誤(拒真錯誤):本來是一個好的產品,它本來可以給我們帶來收益,但是由於我們統計的誤差,導致我們誤認為它並不能給我們帶來收益。

第二類錯誤代表的是一個功能改動,本來不能給我們帶來任何收益,但是我們卻誤認為它能夠給我們帶來收益。

Q6:流量分割有哪兩種方式?

Q7:假設檢驗如何選取統計量?

Q7:ABTest有哪些注意事項?

一些效應

① 網路效應:

主要是因為對照組和實驗組在一個社交網路導致。如果微信改動了某一個功能,這個功能讓實驗組用戶更加活躍,發更多朋友圈。但是實驗組用戶的好友可能在對照組,實驗組發的多,對照組用戶可能就刷朋友圈刷的多,所以本質上對照組用戶也受到了新功能的影響,那麼ABTest就不再能很好的檢測出相應的效果

解決辦法:從地理上隔絕用戶

② 學習效應:

主要是用戶的好奇心理導致。比如產品將某個按鈕從暗色調成亮色。很多用戶剛剛看到,會有個新奇心裡,去點擊該按鈕,導致按鈕點擊率在一段時間內上漲,但是長時間來看,點擊率可能又會恢復到原有水平

解決方法:一是把時間拉長。二是只看新用戶的數據

Q7:如果樣本量不足該怎麼辦

只能通過拉長時間周期,通過累計樣本量來進行比較

Q8:是否需要上線第一天就開始看效果?

在做AB測試時,盡量設定一個測試生效期,這一般是用戶的一個活躍周期。如用戶活躍間隔是7天,那麼生效期為7天,如果是一個機酒app,用戶活躍間隔是30天,那生效期為30天

BOUNUS:

ABtest實驗可以分成兩種,客戶端client實驗和服務端server實驗

客戶端實驗一般來說只是UI上的實驗,純粹是展示端的策略;

而服務端的實驗是返回給client數據的內容做實驗,比如推薦的策略,演算法策略等

⑧ 經典C語言面試演算法題

經典C語言面試演算法題

1.寫一個函數,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字元串中找出連續最長的數字串,並把這個串的長度返回,並把這個最長數字串付給其中一個函數參數outputstr所指內存。例如:"abcd12345ed125ss123456789"的首地址傳給intputstr後,函數將返回

9,outputstr所指的值為123456789。

#include

#include

#include

int FindMax_NumStr(char *outputstr,char *inputstr)

{

char *in = inputstr,*out = outputstr,*temp;

char *final;

int count = 0;

int maxlen = 0;

int i;

while(*in!='')

{

if(*in > 47 && *in < 58)

{

for(temp = in;*in> 47 && *in <58;in++)

count++;

}

else

in++;

if(maxlen < count)

{

maxlen = count;

count = 0;

final = temp;

}

}

for(i =0;i

{

*out = *final;

out++;

final++;

}

*out = '';

return maxlen;

}

void main(void)

{

char input[]="abc123def123456eec123456789dd";

char output[50] = {0};

int maxlen;

maxlen = FindMax_NumStr(output,input);

printf("the str %s ",output);

printf("the maxlen is %d ",maxlen);

}

2.求1000!的未尾有幾個0;

求出1->1000里,能被5整除的數的個數n1,能被25整除的數的個數n2,能被125整除的'數的個數n3,能被625整除的數的個數n4.1000!末尾的零的個數=n1+n2+n3+n4;

只要是末尾是5的數它乘以一個偶數就會出現一個0,而末尾是0的數乘以任何數也都會出現0

而末尾是0的如果是一個0肯定能被5整除,兩個0肯定能被25整數,以此類推3個0就能被5的三次方整除,也就是125

1000!就是1-1000數的相乘,能被5整除的所有數分別乘以一個偶數就會出現這些個的0,而例如100,既能被5整除,也能被25整除,所以就是兩個0

1000,既能被5,25,也能被125整除,所以算三個0

例如是10!=1*2*3*4*5*6*7*8*9*10,裡面有兩個數能被5整除,就是10和5,而

5隨便乘以一個偶數就出現一個0,而10乘以其它數也會出現一個0,所以10!會有兩個0

#include

#define NUM 1000

int find5(int num)

{

int ret = 0;

while(num%5==0)

{

num/=5;

ret++;

}

return ret;

}

int main(void)

{

int result = 0;

int i;

for(i=5;i<=NUM;i+=5)

result +=find5(i);

printf("the total zero number is %d ",result);

return 0;

}

3。編寫一個 C 函數,該函數在一個字元串中找到可能的最長的子字元串,且該字元串是由同一字元組成的。

char * search(char *cpSource, char ch)

{

char *cpTemp=NULL, *cpDest=NULL;

int iTemp, iCount=0;

while(*cpSource)

{

if(*cpSource == ch)

{

iTemp = 0;

cpTemp = cpSource;

while(*cpSource == ch)

++iTemp, ++cpSource;

if(iTemp > iCount)

iCount = iTemp, cpDest = cpTemp;

if(!*cpSource)

break;

}

++cpSource;

}

return cpDest;

}

;

⑨ 如何准備演算法面試

主要介紹演算法面試的一些問題、以及如何准備演算法面試

!--more--

演算法面試不僅僅是正確的回答問題

對於面試中遇到的大多數問題,都能有一個合理的思考路徑

讓大家在面對面試中的演算法問題時,有一個合理的思考路徑:

不代表能夠「正確」回答每一個演算法問題,但是合理的思考方向其實更重要,也是正確完成演算法面試問題的前提

演算法面試優秀不意味著技術面試優秀

技術面試優秀不意味著能夠拿到Offer

演算法面試的目的不是給出一個「正確」答案,

而是展示給面試官你思考問題的方式。

演算法面試不是高考。

把這個過程看作是和面試官一起探討一個問題的解決方案。

對於問題的細節和應用環境,可以和面試官溝通。

這種溝通本身很重要,它暗示著你思考問題的方式。

我們需要對一組數據進行排序

設計排序介面,標准庫的設計,業務中排序演算法。

排序是基礎操作,很重要。

解決

快速排序演算法:O(nlogn)

忽略了演算法使用的基礎環境。要動態選擇。

(向面試官提問):這組數據有什麼樣的特徵?

有沒有可能包含有大量重復的元素?

如果有這種可能的話,三路快排是更好地選擇。

普通數據:普通快速排序就行了;java語言標准庫排序使用的三路快排。

是否大部分數據距離它正確的位置很近?是否近乎有序?

如果是這樣的話,插入排序是更好地選擇。

按照業務發生順序,先發生先完成,幾乎有序,插入排序是更好的選擇。

是否數據的取值范圍非常有限?比如對學生成績排序。

如果是這樣的話,計數排序是更好地選擇。高考成績取值范圍有限:計數排序更好。

(向面試官提問):對排序有什麼額外的要求?

是否需要穩定排序?

如果是的話,歸並排序是更好地選擇。

(向面試官提問):數據的存儲狀況是怎樣的?

是否是使用鏈表存儲的?

如果是的話,歸並排序是更好地選擇。

快排依賴於數組的隨機存取。

(向面試官提問):數據的存儲狀況是怎樣的?

數據的大小是否可以裝載在內存里?

數據量很大,或者內存很小,不足以裝載在內存里,需要使用外排序演算法。

有沒有可能包含有大量重復的元素?

是否大部分數據距離它正確的位置很近?是否近乎有序?

是否數據的取值范圍非常有限?比如對學生成績排序。

是否需要穩定排序?

是否是使用鏈表存儲的?

數據的大小是否可以裝載在內存里?

正確除了你能把代碼編出來運行出正確的結果。正確還包含對問題的獨到見解;優化;代碼規范;容錯性;

o 不僅僅是給出解決演算法問題的代碼,還要把上面因素包括。

o 如果是非常難的問題,對你的競爭對手來說,也是難的。

關鍵在於你所表達出的解決問題的思路。

甚至通過表達解題思路的方向,得出結論:這個問題的解決方案,應該在哪一個領域,我可以通過查閱或者進一步學習解決問題。

演算法面試只是面試的一部分

演算法面試只是技術面試的一部分。

根據你的簡歷和應聘職位的不同,勢必要考察其他技術方面。

項目經歷和項目中遇到的實際問題

o 解決能力,是否參與

o 深入思考

o 技術態度

面試前梳理自己簡歷上所寫到的項目:整理一下可能會問到的。

你遇到的印象最深的bug是什麼?

面向對象

設計模式

網路相關;安全相關;內存相關;並發相關;…

系統設計;scalability(大規模)

技術面試只是面試的一部分。面試不僅僅是考察你的技術水平,還是了解你的過去以及形成的思考行為方式。

關於過去:參與項目至關重要

工作人士

研究生

本科生

o 畢業設計

o 其他課程設計(大作業)

實習

創建自己的項目

o 自己做小應用:計劃表;備忘錄;播放器…

o 自己解決小問題:爬蟲;數據分析;詞頻統計...

o 「不是項目」的項目:一本優秀的技術書籍的代碼整理等…(github)

o 分享:自己的技術博客;github等等

通過過去了解你的思考行為方式:

遇到的最大的挑戰?

犯過的錯誤?

遭遇的失敗?

最享受的工作內容?

遇到沖突的處理方式?

做的最與眾不同的事兒?

具體闡述:我在某某項目中遇到一個怎樣的演算法問題:這個問題是怎樣的。它是我遇到的最大的挑戰,我是如何克服解決的。

整個小組的大概運行模式是怎樣的?

整個項目的後續規劃是如何的?

這個產品中的某個問題是如何解決的?

為什麼會選擇某些技術?標准?

我對某個技術很感興趣,在你的小組中我會有怎樣的機會深入這種技術?

演算法面試仍然是非常重要的一部分

如何准備演算法面試

准備面試和准備演算法面試是兩個概念

演算法面試,只是面試中的一個環節。

遠遠不需要啃完一本《演算法導論》

o 強調理論證明

o 第一遍讀不需要弄懂證明

o 前幾遍閱讀應該記住結論就行了,不需要弄懂證明。把更多的精力放在演算法思想上。

針對演算法面試,演算法導論裡面的理論推導和證明不是很重要的方面。

選擇合適的oj

leetcode

o Online Portal for IT Interview

o 真實的面試問題

o http://www.leetcode.com

HankeRank

o 特點是對於問題的分類很詳細。偏難,不過可以對某一類細分問題解決。

o http://www.hackerrank.com

在學習和實踐做題之間,要掌握平衡

基礎演算法實現與演算法思想

如何回答演算法面試問題

注意題目中的條件

o 給定一個有序數組...(二分法)

有一些題目中的條件本質是暗示

o 設計一個O(nlogn)的演算法(分治:在一顆搜索樹中完成任務,對於數據排序)

o 無需考慮額外的空間(用空間換時間上的優化)

o 數據規模大概是10000(O(n^2)就可以)

當沒有思路的時候

自己給自己幾個簡單的測試用例,試驗一下

不要忽視暴力解法。暴力解法通常是思考的起點。

例子

LeetCode 3 LongestSubstringWithout Repeating Characters

在一個字元串中尋找沒有重復字母的最長子串

如」abcabcbb」,則結果為」abc」

如」bbbbb」,則結果為」b」

對於字元串s的子串s[i...j]

使用O(n^2)的演算法遍歷i,j,可以得到所有的子串s[i...j]

使用O(length(s[i...j]))的演算法判斷s[i...j]中是否含有重復字母

三重循環:復雜度O(n^3),對於n=100的數據,可行

遍歷常見的演算法思路

遍歷常見的數據結構

空間和時間的交換(哈希表)

預處理信息(排序)

在瓶頸處尋找答案:O(nlogn)+ O(n^2); O(n^3)

o O(n^2)能否優化。

什麼樣的問題使用什麼樣的思路和數據結構。

極端條件的判斷

o 數組為空?

o 字元串為空?

o 數量為0?

o 指針為NULL?

代碼規范:

o 變數名

o 模塊化

o 復用性

⑩ 經典C語言面試演算法題

1.寫一個函數,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字元串中找出連續最長的數字串,並把這個串的長度返回,並把這個最長數字串付給其中一個函數參數outputstr所指內存。例如:"abcd12345ed125ss123456789"的首地址傳給intputstr後,函數將返回

9,outputstr所指的值為123456789。

#include

#include

#include

int FindMax_NumStr(char *outputstr,char *inputstr)

{

char *in = inputstr,*out = outputstr,*temp;

char *final;

int count = 0;

int maxlen = 0;

int i;

while(*in!='')

{

if(*in > 47 && *in < 58)

{

for(temp = in;*in> 47 && *in <58;in++)

count++;

}

else

in++;

if(maxlen < count)

{

maxlen = count;

count = 0;

final = temp;

}

}

for(i =0;i

{

*out = *final;

out++;

final++;

}

*out = '';

return maxlen;

}

void main(void)

{

char input[]="abc123def123456eec123456789dd";

char output[50] = {0};

int maxlen;

maxlen = FindMax_NumStr(output,input);

printf("the str %s ",output);

printf("the maxlen is %d ",maxlen);

}

2.求1000!的'未尾有幾個0;

求出1->1000里,能被5整除的數的個數n1,能被25整除的數的個數n2,能被125整除的數的個數n3,能被625整除的數的個數n4.1000!末尾的零的個數=n1+n2+n3+n4;

只要是末尾是5的數它乘以一個偶數就會出現一個0,而末尾是0的數乘以任何數也都會出現0

而末尾是0的如果是一個0肯定能被5整除,兩個0肯定能被25整數,以此類推3個0就能被5的三次方整除,也就是125

1000!就是1-1000數的相乘,能被5整除的所有數分別乘以一個偶數就會出現這些個的0,而例如100,既能被5整除,也能被25整除,所以就是兩個0

1000,既能被5,25,也能被125整除,所以算三個0

例如是10!=1*2*3*4*5*6*7*8*9*10,裡面有兩個數能被5整除,就是10和5,而

5隨便乘以一個偶數就出現一個0,而10乘以其它數也會出現一個0,所以10!會有兩個0

#include

#define NUM 1000

int find5(int num)

{

int ret = 0;

while(num%5==0)

{

num/=5;

ret++;

}

return ret;

}

int main(void)

{

int result = 0;

int i;

for(i=5;i<=NUM;i+=5)

result +=find5(i);

printf("the total zero number is %d ",result);

return 0;

}

3。編寫一個 C 函數,該函數在一個字元串中找到可能的最長的子字元串,且該字元串是由同一字元組成的。

char * search(char *cpSource, char ch)

{

char *cpTemp=NULL, *cpDest=NULL;

int iTemp, iCount=0;

while(*cpSource)

{

if(*cpSource == ch)

{

iTemp = 0;

cpTemp = cpSource;

while(*cpSource == ch)

++iTemp, ++cpSource;

if(iTemp > iCount)

iCount = iTemp, cpDest = cpTemp;

if(!*cpSource)

break;

}

++cpSource;

}

return cpDest;

}

閱讀全文

與推薦演算法面試題相關的資料

熱點內容
iis7gzip壓縮 瀏覽:39
有什麼安卓機打吃雞好 瀏覽:595
三星u盤加密狗 瀏覽:471
php函數的返回值嗎 瀏覽:584
國企穩定程序員 瀏覽:325
編程貓如何使用教程視頻 瀏覽:216
安卓遠端網頁如何打日誌 瀏覽:216
壓縮flash大小 瀏覽:991
解壓的玩具教程可愛版 瀏覽:366
哪個求職app比較靠譜 瀏覽:888
java的讀法 瀏覽:59
nod32區域網伺服器地址 瀏覽:1002
數碼科技解壓 瀏覽:235
新網的雲伺服器管理界面復雜嗎 瀏覽:367
無人聲解壓強迫症視頻 瀏覽:571
計算機編譯運行 瀏覽:639
單片機嵌套 瀏覽:988
python字元串中符號 瀏覽:787
python正則表達式貪婪模式 瀏覽:650
愛國精神指的是什麼app 瀏覽:408